webpack構(gòu)建自定義vue應(yīng)用



在上一篇中我們利用webpack從0到1搭建了一篇最基本的react應(yīng)用,而vue在團(tuán)隊(duì)項(xiàng)目里也是用得非常之多,我們?nèi)绾尾灰蕾噕ue-cli腳手架搭建一個(gè)自己的vue工程化項(xiàng)目呢?

相比較react,vue所需要的插件要少得多,我們知道在vue中,大多數(shù)是以.vue的模版組件,因此關(guān)鍵是我們可以用webpack的相關(guān)loader能夠解析.vue文件即可,在vue項(xiàng)目中解析單文件組件,熱加載,css作用域等全部依賴于這個(gè)插件vue-loader[1],因此vue-loader算是vue工程化中必不可少的一個(gè)插件。

正文開始...

初始化項(xiàng)目
新建一個(gè)webpack-03-vue目錄,執(zhí)行npm init -y

安裝相關(guān)基礎(chǔ)配置插件

npm i webpack webpack-cli fs-loader css-loader style-loader html-webpack-plugin mini-css-extract-plugin -D
安裝vue最新版本,執(zhí)行以下命令

npm i vue -s
安裝解析.vue文件的loader

npm i vue-loader -D
配置loader
// webpack.config.js
module.exports = {
  ...
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      },
      {
        test: /\.vue$/,
        loader: 'vue-loader' // 與 use: ['vue-loader']等價(jià)
      }
    ]
  },
}
除了設(shè)置loader,我們還需要引入另外一個(gè)插件VueLoaderPlugin,不然運(yùn)行項(xiàng)目加載template時(shí)就會(huì)報(bào)錯(cuò)。

// webpack.config.js
const HtmlWebpackPlguins = require('html-webpack-plugin');
const miniCssExtractPlugin = require('mini-css-extract-plugin');
// 引入VueLoaderPlugin 必不可少
const { VueLoaderPlugin } = require('vue-loader');
module.exports = {
  ...
  plugins: [
    new HtmlWebpackPlguins({
      template: './public/index.html'
    }),
    new miniCssExtractPlugin({
      filename: 'css/[name].css'
    }),
    new VueLoaderPlugin(),
  ]
}
如果我們需要提取css,我們需要把style-loader換成miniCssExtractPlugin.loader即可

// webpack.config.js
const miniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [miniCssExtractPlugin.loader, 'css-loader']
      },
      ...
    ]
}
所有配置完成后,看下最終的webpack.config.js完整配置

const path = require('path');
const HtmlWebpackPlguins = require('html-webpack-plugin');
const miniCssExtractPlugin = require('mini-css-extract-plugin');
const { VueLoaderPlugin } = require('vue-loader');

module.exports = {
  entry: {
    app: './src/index.js'
  },
  output: {
    filename: '[name][hash].js',
    path: path.resolve(__dirname, 'dist')
  },
  mode: 'development',
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [miniCssExtractPlugin.loader, 'css-loader']
      },
      {
        test: /\.vue$/,
        loader: 'vue-loader'
      },
      {
        test: /\.less$/,
        use: [
          miniCssExtractPlugin.loader,
          'css-loader',
          {
            loader: 'less-loader'
          },
          {
            loader: 'postcss-loader'
            // options: {
            //   postcssOptions: {
            //     plugins: [['postcss-preset-env']]
            //   }
            // }
          }
        ]
      },
      {
        test: /\.(js|jsx)$/,
        loader: 'babel-loader'
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlguins({
      template: './public/index.html'
    }),
    new miniCssExtractPlugin({
      filename: 'css/[name].css'
    }),
    new VueLoaderPlugin()
  ]
};
我們?cè)趕rc目錄下新建一個(gè)index.js與App.vue文件

<!--App.vue-->
<template>
  <div class="app">
       <h1>{{name}}</h1>
       <h2>{{age}}</h2>
       <h3>{{publicText}}</h3>
    </div>
</template>
<script>
import {reactive, toRefs } from 'vue';
export default {
  name: 'App',
  setup() {
    const info = reactive({
          name: 'Maic',
          age: 18,
          publicText: 'web技術(shù)學(xué)苑'
    })
    return {
        ...toRefs(info)
    }
  },
}
</script>
<style scoped>
.app h1{
  color: red;
}
</style>

我們?cè)趇ndex.js中引入App.vue文件

import { createApp } from 'vue';
import App from './App.vue';
createApp(App).mount('#app');
運(yùn)行npm run server,打開地址localhost:8080訪問








在vue中會(huì)用less,因此我們看下less在vue中的運(yùn)用

配置less
在項(xiàng)目中,我們會(huì)用less,scss或者stylus這樣的第三方css編譯語言,在vue項(xiàng)目中需要有對(duì)應(yīng)的loader加載才行

安裝npm i less less-loader -d,并設(shè)置loader[2]

// webpack.config.js
module.exports = {
  module: {
    rules: [
       ...
       {
        test: /\.less$/,
        use: [miniCssExtractPlugin.loader,  'css-loader', 'less-loader']
      },
    ]
  }
}
在App.vue中設(shè)置less

<style lang="less" scoped>
.app{
  h1 {
      color: red;
      & {
        font-size:30px;
      }
  }
  h2 {
    display: flex;
  }

}
</style>
ok頁面已經(jīng)支持less了,我們知道css有很多特性需要些支持多個(gè)瀏覽器的兼容性,因此會(huì)有很多的前綴,譬如--webkeit--,--ms--等等,那么這些前綴,我能否利用插件來支持呢,因此我們需要了解一個(gè)插件postcss

配置postcss
postcss有很多可配置的參數(shù),更多參考可以查看官網(wǎng)webpack-postcss[3],也可以查看更詳細(xì)api文檔github-postcss[4]實(shí)現(xiàn)更多的功能

npm install --save-dev postcss-loader postcss postcss-preset-env
我們?cè)趌oader上加上postcss-loader

module.exports = {
  module: {
    rules: [
      ...
       {
        test: /\.less$/,
        use: [
          miniCssExtractPlugin.loader,
          'css-loader',
          {
            loader: 'less-loader'
          },
          {
            loader: 'postcss-loader',
            options: {
              postcssOptions: {
                plugins: [['postcss-preset-env']]
              }
            }
          }
        ]
      },
    ]
  }
}
我們注意到官方提供了一個(gè)autoprefixer,但是我們這里使用的是postcss-preset-env,實(shí)際上這個(gè)插件已經(jīng)有了autoprefixer的功能。

從官網(wǎng)了解到,你可以在webpack.config.js的loader中設(shè)置postcss-preset-env,你也可以在根目錄新建一個(gè)文件postcss.config.js以此來代替loader的設(shè)置

// postcss.config.js
module.exports = {
  plugins: [['postcss-preset-env']]
};
因此你就會(huì)看到樣式user-select加了前綴



但是你會(huì)發(fā)現(xiàn),為啥display:flex沒有前綴,因此有一個(gè)對(duì)瀏覽器兼容性設(shè)置的配置,實(shí)際上安裝webpack時(shí)就已經(jīng)給我們自動(dòng)安裝了,主要依靠.browserslist來設(shè)置支持瀏覽器的前綴css

browserslist
這個(gè)插件主要是可以讓你的樣式兼容多個(gè)不同版本的瀏覽器,如果指定的版本瀏覽器比較高,那么一些支持的特性就會(huì)自動(dòng)支持,所以就不會(huì)設(shè)置前綴,具體可以參考browserslist[5]

你可以在package.json中設(shè)置,比如像下面這樣

{
  ...
  "dependencies": {
    "vue": "^3.2.36"
  },
  "browserslist": [
    "> 1%",
    "last 2 versions"
  ]
}
當(dāng)你設(shè)置完后,你會(huì)發(fā)現(xiàn),重新執(zhí)行npm run server,對(duì)應(yīng)的display:flex就已經(jīng)加了前綴了。



或者你可以在根目錄新建一個(gè).browserslistrc文件,與package.json設(shè)置的等價(jià)

> 1%
last 2 versions

終于關(guān)于用webpack搭建vue的min工程版已經(jīng)可以了,項(xiàng)目還有一些圖片加載,字體圖標(biāo)啊這些都是file-loader插件的事情,后續(xù)有用上的時(shí)候就安裝支持配置一下,具體也可參考這一篇文章webpack從0到1構(gòu)建也有相關(guān)file-loader的設(shè)置

看完是不是覺得webpack配置vue沒那么難了

總結(jié)
安裝webpack,webpack-cli等基礎(chǔ)插件,支持vue核心插件vue-loader

.vue文件需要vue-loader編譯,需要配置對(duì)應(yīng)loader,在webpack.config.js中需要加入VueLoaderPlugin插件,一定要引入,不然會(huì)直接報(bào)錯(cuò)。

less與postcss的安裝,主要依賴less,less-loader, postcss,posscss-loader,postcss-preset-env這些插件支持,既可以在loader中支持配置postcss-preset-env,可以用postcss.config.js來代替設(shè)置

browserslist配置設(shè)置,內(nèi)部主要是依賴 caniuse-lite 與Can I Use 來做瀏覽器兼容性查詢的

本文code-example[6]

參考資料
[1]
vue-loader: https://vue-loader.vuejs.org/zh/

[2]
loader: https://webpack.docschina.org/loaders/less-loader/

[3]
webpack-postcss: https://webpack.docschina.org/loaders/postcss-loader/

[4]
github-postcss: https://github.com/webpack-contrib/postcss-loader

[5]
browserslist: https://www.npmjs.com/package/browserslist

[6]
code-example: https://github.com/maicFir/lessonNote/tree/master/webpack/webpack-03-vue







作者:Maic

歡迎關(guān)注微信公眾號(hào) :web技術(shù)學(xué)苑