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...