vue-cli
優化的webpack
配置大概分爲如下幾點javascript
externals
配置來提取經常使用庫,引用外鏈CommonsChunkPlugin
提取公用代碼 (vue-cli
已作)alias
(vue-cli
配置了一部分)DllPlugin
和DllReferencePlugin
預編譯庫文件happypack
開啓多核構建項目webpack-parallel-uglify-plugin
來替換webpack
自己的UglifyJS
來進行代碼壓縮混淆webpack
至3.x版本開啓Scope Hoisting
文檔地址 https://doc.webpack-china.org...css
防止將某些 import 的包(package)打包到 bundle 中,而是在運行時(runtime)再去從外部獲取這些擴展依賴(external dependencies)。html
文檔地址 https://doc.webpack-china.org...vue
CommonsChunkPlugin 插件,是一個可選的用於創建一個獨立文件(又稱做 chunk)的功能,這個文件包括多個入口 chunk 的公共模塊。經過將公共模塊拆出來,最終合成的文件可以在最開始的時候加載一次,便存起來到緩存中供後續使用。這個帶來速度上的提高,由於瀏覽器會迅速將公共的代碼從緩存中取出來,而不是每次訪問一個新頁面時,再去加載一個更大的文件。java
文檔地址 https://doc.webpack-china.org...node
建立 import 或 require 的別名,來確保模塊引入變得更簡單。例如,一些位於 src/ 文件夾下的經常使用模塊:webpack
文檔地址 https://doc.webpack-china.org...git
Dll打包之後是獨立存在的,只要其包含的庫沒有增減、升級,hash也不會變化,所以線上的dll代碼不須要隨着版本發佈頻繁更新。使用Dll打包的基本上都是獨立庫文件,這類文件有一個特性就是變化不大。,只要包含的庫沒有升級, 增減,就不須要從新打包。這樣也提升了構建速度。es6
通常是用於打包階段github
build
文件夾下新建webpack.dll.conf.js
文件var path = require('path'); var webpack = require('webpack'); var AssetsPlugin = require('assets-webpack-plugin'); var CleanWebpackPlugin = require('clean-webpack-plugin'); var config = require('../config'); var env = config.build.env; module.exports = { entry: { libs: [ 'babel-polyfill', 'vue/dist/vue.esm.js', 'vue-router', 'vuex', 'element-ui', 'echarts', 'mockjs', ], }, output: { path: path.resolve(__dirname, '../libs'), filename: '[name].[chunkhash:7].js', library: '[name]_library', }, plugins: [ new webpack.DefinePlugin({ 'process.env': env, }), new webpack.DllPlugin({ path: path.resolve(__dirname, '../libs/[name]-mainfest.json'), name: '[name]_library', context: __dirname, // 執行的上下文環境,對以後DllReferencePlugin有用 }), new ExtractTextPlugin('[name].[contenthash:7].css'), new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false, }, }), new AssetsPlugin({ filename: 'bundle-config.json', path: './libs', }), new CleanWebpackPlugin(['libs'], { root: path.join(__dirname, '../'), // 絕對路徑 verbose: true, dry: false, }), ], module: { rules: [ { test: /\.js$/, loader: 'babel-loader', }, ], }, };
build
文件夾下新建build-dll.js
文件var path = require("path"); var webpack = require("webpack"); var dllConfig = require("./webpack.dll.conf"); var chalk = require("chalk"); var rm = require("rimraf"); var ora = require("ora"); var spinner = ora({ color: "green", text: "building for Dll..." }); spinner.start(); rm(path.resolve(__dirname, "../libs"), err => { if (err) throw err; webpack(dllConfig, function(err, stats) { spinner.stop(); if (err) throw err; process.stdout.write( stats.toString({ colors: true, modules: false, children: false, chunks: false, chunkModules: false }) + "\n\n" ); console.log(chalk.cyan(" build dll succeed !.\n")); }); });
webpack.prod.conf.js
文件var bundleConfig = require("../libs/bundle-config.json"); ... ... plugins: [ // 增長DllReferencePlugin配置 new webpack.DllReferencePlugin({ context: __dirname, manifest: require("../libs/libs-mainfest.json") // 指向生成的manifest.json }), ... ... new HtmlWebpackPlugin({ ... // 增長兩個變量 libJsName: bundleConfig.libs.js, libCssName: bundleConfig.libs.css, }), ... ... // 增長一個靜態文件目錄 new CopyWebpackPlugin([ ... ... { from: path.resolve(__dirname, "../libs"), to: config.build.assetsSubDirectory, ignore: ["*.json"] } ]) ]
index.html
<body> <div id="app"></div> <!-- built files will be auto injected --> <% if (htmlWebpackPlugin.options.libCssName){ %> <link rel="stylesheet" href="./static/<%= htmlWebpackPlugin.options.libCssName %>"> <% } %> <% if (htmlWebpackPlugin.options.libJsName){ %> <script src="./static/<%= htmlWebpackPlugin.options.libJsName %>"></script> <% } %> </body>
package.json
,增長scripts
"scripts": { // 增長 "dll": "node build/build-dll.js" },
npm run dll
先執行預編譯,而後在打包項目文件,若是引入的類庫文件沒有變動就再也不須要再次執行預編譯文檔地址 https://github.com/amireh/hap...
通常node.js是單線程執行編譯,而happypack則是啓動node的多線程進行構建,大大提升了構建速度。
在插件中new一個新的happypack進程出來,而後再使用使用loader的地方替換成對應的id
webpack.base.conf.js
文件var HappyPack = require('happypack'); var os = require('os'); var happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length }); ... ... // 增長plugins plugins: [ new HappyPack({ id: 'happy-babel-js', loaders: ['babel-loader?cacheDirectory=true'], threadPool: happyThreadPool, }) ] ... ... // 修改對應loader { test: /\.js$/, loader: 'happypack/loader?id=happy-babel-js', include: [resolve('src'), resolve('test')], }
文檔地址 https://github.com/gdborton/w...
webpack
提供的UglifyJS
插件因爲採用單線程壓縮,速度很慢 ,webpack-parallel-uglify-plugin
插件能夠並行運行UglifyJS
插件,這能夠有效減小構建時間。
webpack.prod.conf.js
文件var ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin'); ... ... // 刪掉webpack提供的UglifyJS插件 // new webpack.optimize.UglifyJsPlugin({ // compress: { // warnings: false, // drop_console: true // }, // sourceMap: true // }), // 增長 webpack-parallel-uglify-plugin來替換 new ParallelUglifyPlugin({ cacheDir: '.cache/', uglifyJS:{ output: { comments: false }, compress: { warnings: false } } }),
webpack3新特性一覽 https://juejin.im/entry/59714...
webpack 3.x 提供了一個新的功能:Scope Hoisting,又譯做「做用域提高」。只需在配置文件中添加一個新的插件,就可讓 Webpack 打包出來的代碼文件更小、運行的更快。
webpack.prod.conf.js
... ... plugins: [ // 往plugins添加一個配置 // ps 只針對es6的模塊化有效 new webpack.optimize.ModuleConcatenationPlugin(), ]
ps:配置文件詳情請點擊 https://github.com/liaoyinglo...