從0開始搭建vue+webpack腳手架(四)

以前1-3部分是webpack最基本的配置, 接下來會把項目結構和配置文件從新設計,能夠擴充更多的功能模塊。css

1、重構webpack的配置項html

1. 新建目錄build,存放webpack不一樣的配置文件vue

  (1) webpack.config.base.js  【保留公共的配置項,將生產環境和開發環境使用的配置項分離出去】node

 1 const path = require('path')
 2 const webpack = require('webpack')
 3 const VueLoaderPlugin = require('vue-loader/lib/plugin')
 4 const HtmlWebpackPlugin = require('html-webpack-plugin')
 5 const CleanWebpackPlugin = require('clean-webpack-plugin')
 6 
 7 const isDev = process.env.NODE_ENV === 'development'
 8 
 9 const config = {
   mode: process.env.NODE_ENV || 'production'
10 target: 'web', 11 performance: { 12 hints: false, 13 maxAssetSize: 500000 14 }, 15 entry: path.join(__dirname, '../src/index.js'), 16 output: { 17 path: path.join(__dirname, '../dist'), 18 filename: 'scripts/bundle.[hash:8].js' 19 }, 20 module: { 21 rules: [ 22 { 23 test: /\.vue$/, 24 use: [ 25 { 26 loader: "vue-loader" 27 } 28 ] 29 }, 30 { 31 test: /\.jsx$/, 32 loader: "babel-loader" 33 }, 34 { 35 test: /\.js$/, 36 loader: "babel-loader", 37 exclude: /node_modules/ 38 }, 39 { 40 test: /\.(jpg|jpeg|gif|png|svg)$/, 41 use: [ 42 { 43 loader: "url-loader", 44 options: { 45 limit: 1024, 46 name: 'images/[name]-[hash:8].[ext]' 47 } 48 } 49 ] 50 } 51 ] 52 }, 53 plugins: [ 54 new VueLoaderPlugin() 55 ] 56 } 57 58 module.exports = config

注意: 入口文件和輸出路徑webpack

注意: VueLoaderPlugin是使用vue-loader必須的,兩種環境都須要加載。jsx和js的規則分開配置,由於js編譯時須要除去node_modules目錄下的文件。es6

 

  (2) webpack.config.client.js 【配置開發和生產環境環境須要的選項】web

    安裝 webpack-merge工具, 提供配置文件擴展方法。npm

1 $ npm i -D webpack-merge

    (3)  在webpack.config.client.js中使用merge對基礎的配置baseConfig進行擴展。json

  1 const path = require('path')
  2 const webpack = require('webpack')
  3 const merge = require('webpack-merge')
  4 const VueLoaderPlugin = require('vue-loader/lib/plugin')
  5 const HtmlWebpackPlugin = require('html-webpack-plugin')
  6 const CleanWebpackPlugin = require('clean-webpack-plugin')
  7 const ExtractTextPlugin = require('extract-text-webpack-plugin')
  8 const baseConfig = require('./webpack.config.base')
  9 
 10 const isDev = process.env.NODE_ENV === 'development'
 11 const basePlugin = [
 12   new VueLoaderPlugin(),
 13   new CleanWebpackPlugin(['../dist']),
 14   // 根據不一樣環境區分打包
 15   new webpack.DefinePlugin({
 16     'process.env': {
 17       NODE_ENV: isDev ? '"development"' : '"production"',
 18     }
 19   }),
 20   new HtmlWebpackPlugin({
 21     template: path.join(__dirname, '../index.html')
 22   })
 23 ]
 24 const devServer = {
 25   port: 9000,
 26   host: '0.0.0.0',
 27   overlay: {
 28     errors: true
 29   },
 30   historyApiFallback: true,
 31   hot: true,
 32 }
 33 
 34 let config
 35 
 36 if (isDev) {
 37   config = merge(baseConfig, {
 38     // mode: 'development',
 39     // devtool: '#cheap-module-eval-source-map',
 40     module: {
 41       rules: [
 42         {
 43           test: /\.css$/,
 44           use: ['style-loader', 'css-loader']
 45         },
 46         {
 47           test: /\.styl(us)?$/,
 48           use: [
 49             'style-loader',
 50             'css-loader',
 51             {
 52               loader: "postcss-loader",
 53               options: {
 54                 sourceMap: true
 55               }
 56             },
 57             'stylus-loader',
 58           ]
 59         },
 60       ]
 61     },
 62     devServer,
 63     plugins: basePlugin.concat([
 64       new webpack.HotModuleReplacementPlugin(),
 65       new webpack.SourceMapDevToolPlugin() // devtool
 66     ])
 67   })
 68 } else {
 69   config = merge(baseConfig, {
 70     // mode: 'production',
 71     entry: {
 72       app: path.join(__dirname, '../src/index.js'),
 73       vendor: ['vue']
 74     },
 75     output: {
 76       filename: 'scripts/[name].[chunkhash:8].js'
 77     },
 78     module: {
 79       rules: [
 80         {
 81           test: /\.css$/,
 82           use: ExtractTextPlugin.extract({
 83             fallback: 'style-loader',
 84             use: ['css-loader']
 85           })
 86         },
 87         {
 88           test: /\.styl(us)?$/,
 89           use: ExtractTextPlugin.extract({
 90             fallback: 'style-loader',
 91             use: [
 92               'css-loader',
 93               {
 94                 loader: "postcss-loader",
 95                 options: {
 96                   sourceMap: true
 97                 }
 98               },
 99               'stylus-loader',
100             ]
101           })
102         },
103       ]
104     },
105     plugins: basePlugin.concat([
106       new ExtractTextPlugin('style.[hash:8].css'),
107     ]),
108     optimization: {
109       splitChunks: {
110         chunks: 'all'  // name: 'vendor'
111       },
112  runtimeChunk: true 115     }
116   })
117 }
118 
119 module.exports = config

注意紅色部分的修改:promise

  1 .引入merge工具 和 webpack.config.base.js

  2 .將公共plugin提取保存在變量 basePlugin, 不在base.js中使用的緣由是後續的服務端渲染時無需使用, 故只在生產環境和開發環境引用。

  3. 將devServer提取保存在變量中。

  4. 聲明變量config, 保存經過merge以baseConfig爲基礎擴展的配置項

  5. basePlugin.concat()將公共的plugin添加到不一樣環境

 

修改package.json的運行腳本

1 "scripts": {
2     "test": "echo \"Error: no test specified\" && exit 1",
3     "build": "cross-env NODE_ENV=production webpack --config build/webpack.config.client.js --colors --progress",
4     "dev": "cross-env NODE_ENV=development webpack-dev-server --config build/webpack.config.client.js --colors --progress",
5     "start": "npm run dev"
6 },

注意, 指向指定路勁時必須使用 --config不然報錯沒法編譯。以前不用--config是由於默認指向了根目錄的webpack.config.js

至此: 運行 $ npm run build $ npm run dev正常。

 

另注: 若是後續須要編寫服務端的代碼,能夠將項目分爲client/ 和 server/ 兩個目錄,分別存放服務端和客戶端的業務代碼, 以下

將原來的src/改爲client/ 注意別忘了修改 webpack.config.base.js和 webpack.config.client.js內的相關路徑。目錄修改根據本身的習慣和環境而定。

 

2、使用rimraf工具 ,在打包前刪除舊包

  1. 以前使用的是clean-webpack-plugin,rimraf也有一樣的功能,但rimraf能夠直接寫在scripts腳本內

  2. 安裝 $ npm i -D rimraf

  3 . 添加到 scripts中

1 "scripts": {
2     "test": "echo \"Error: no test specified\" && exit 1",
3     "build": "npm run clean && cross-env NODE_ENV=production webpack --config build/webpack.config.client.js --colors --progress",
4     "dev": "npm run clean && cross-env NODE_ENV=development webpack-dev-server --config build/webpack.config.client.js --colors --progress",
5     "start": "npm run clean && npm run dev",
6     "clean": "rimraf dist"
7 },

 

 

3、添加eslint代碼校驗

  (1)安裝eslint及其依賴

npm i -D eslint 
npm i -D eslint-config-standard eslint-plugin-standard 
npm i -D eslint-plugin-promise eslint-plugin-import eslint-plugin-node
npm i -D eslint-plugin-html

  特別要說明的是,在vue項目中,eslint默認是沒法解析.vue的文件, 因此須要使用 eslint-plugin-html插件來解析 , 其餘都是輔助eslint的插件和工具 

(2)建立 .eslinrc配置文件

{
  "extends": "standard",
  "plugins": [
    "html"
  ]
}

 (3)package.json中添加命令

1 "scripts": {
2     "test": "echo \"Error: no test specified\" && exit 1",
3     "build": "npm run clean && cross-env NODE_ENV=production webpack --config build/webpack.config.client.js --colors --progress",
4     "dev": "npm run clean && cross-env NODE_ENV=development webpack-dev-server --config build/webpack.config.client.js --colors --progress",
5     "lint": "eslint --ext .js --ext .jsx --ext .vue client/",
6     "fix": "eslint --fix --ext .js --ext .jsx --ext .vue client/",
7     "start": "npm run clean && npm run dev",
8     "clean": "rimraf dist"
9 },

配置完成後運行腳本 : $ npm run lint會提示出一系列的警告。這是由於以前編寫的代碼中有些不符合eslint的默認規範。 可使用 $ npm run  fix命令批量修復。

  (4)錯誤

  在新版本的eslint中,若是設置extends爲 'standard'則會報錯:(再也不支持"standard"的方式, 具體緣由暫時未知),將eslinrc修改以下

 1 module.exports = {
 2   "env": {
 3     "browser": true,
 4     "commonjs": true,
 5     "es6": true
 6   },
 7   "extends": ["eslint:recommended"],
 8   "plugins": [
 9     "html"
10   ]
11 }

運行 $ npm run lint 但又出現錯誤:都不能使用export和 import, 繼續添加配置

1 "parserOptions": {
2     "ecmaFeatures": {
3       "jsx": true
4     },
5     "ecmaVersion": 2015,
6     "sourceType": "module"
7 },

此時運行 $ npm run lint再也不報錯。

以上是使用 eslint-plugin-html 解析vue文件 , 也可使用插件 eslint-plugin-vue來解析vue 文件,安裝插件後修改eslintrc

1 "extends": ["eslint:recommended", "plugin:vue/essential"],
2   "plugins": [
3     "vue"
4  ],

運行 $ npm run lint檢查錯誤, 運行 $ npm run fix修正錯誤。

 

  (5)在webpack項目中使用eslint-loader

   安裝 

1 $ npm i -D eslint-loader
2 $ npm i -D babel-eslint

    eslintrc的 parserOptions 中添加 babel-eslint

1 "parserOptions": {
2     "parser": "babel-eslint",   // 解析檢測babel的代碼
3     "ecmaFeatures": {    
4       "jsx": true          // 檢測jsx語法
5     },  
6     "ecmaVersion": 2015,
7     "sourceType": "module" 
8  },

    在 webpack.config.base.js中 rules 添加 eslint 規則

1 {
2    test: /\.(vue|js|jsx)$/,
3    exclude: /node_modules/,
4    loader: "eslint-loader",
5    enforce: "pre"   // 預處理,在匹配的文件編譯前先檢測語法
6 },

至此, 運行項目, 並在業務文件內改爲有錯誤的格式, eslint將會自動檢測到後提示錯誤, 只要再修改回來便可正常。

接下來在 eslintrc文件中配置 rules,設置指定的語法格式。這裏只配置了一小部分,根據項目需求可自定義。

"rules": {
    "no-new": "off",
    "no-alert": "off",
    "no-console": [
      "off"
    ],
    "eol-last": 0,
    "space-before-function-paren": 0,
    "indent": 0
  }

 0 或者 off通常表示關閉不作解析。如以上代碼中"indent" :0表示不作縮進的檢測, "indent": 2 表示縮進是兩個空格不然會報錯, 其餘用法可參考官網。

相關文章
相關標籤/搜索