以前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 表示縮進是兩個空格不然會報錯, 其餘用法可參考官網。