本章继续介绍一些细节上的优化。
及时删除无用的模块,不要引入无用的文件,使用 treeshaking 尽量减少包体。也可以利用 splitchunks 将包文件切割,有效率利用缓存。
webpack 本身是单线程打包,将其扩展为多进程模式,可以分利用多核的优势。关于中丝路,目前有以下三种解决方案:
把这个 loader 放置在其他 loader 之前, 放置在这个 loader 之后的 loader 就会在一个单独的 worker 池(worker pool)中运行。
在 worker 池(worker pool)中运行的 loader 是受到限制的。例如:
应该仅在耗时的 loader 上使用。
npm install --save-dev thread-loader
module.exports = {
module: {
rules: [
{
test: /\.js$/,
include: path.resolve("src"),
use: [
"thread-loader",
"expensive-loader"
]
}
]
}
}
happypack 的处理思路是将原有的 webpack 对 loader 的执行过程从单一进程的形式扩展多进程模式,原本的流程保持不变。其详细原理可以参考 happypack 原理解析
npm install --save-dev happypack
// @file: webpack.config.js
const HappyPack = require('happypack');
exports.module = {
rules: [
{
test: /.js$/,
// 1) replace your original list of loaders with "happypack/loader":
// loaders: [ 'babel-loader?presets[]=es2015' ],
use: 'happypack/loader',
include: [ /* ... */ ],
exclude: [ /* ... */ ]
}
]
};
exports.plugins = [
// 2) create the plugin:
new HappyPack({
// 3) re-add the loaders you replaced above in #1:
loaders: [ 'babel-loader?presets[]=es2015' ]
})
];
这个是专门针对压缩阶段的并行处理,因为打包过程中压缩基本上是最耗时的阶段了。
如果使用 webpack4,就不用关注这个了。
import ParallelUglifyPlugin from 'webpack-parallel-uglify-plugin';
module.exports = {
plugins: [
new ParallelUglifyPlugin({
// Optional regex, or array of regex to match file against. Only matching files get minified.
// Defaults to /.js$/, any file ending in .js.
test,
include, // Optional regex, or array of regex to include in minification. Only matching files get minified.
exclude, // Optional regex, or array of regex to exclude from minification. Matching files are not minified.
cacheDir, // Optional absolute path to use as a cache. If not provided, caching will not be used.
workerCount, // Optional int. Number of workers to run uglify. Defaults to num of cpus - 1 or asset count (whichever is smaller)
sourceMap, // Optional Boolean. This slows down the compilation. Defaults to false.
uglifyJS: {
// These pass straight through to uglify-js@3.
// Cannot be used with uglifyES.
// Defaults to {} if not neither uglifyJS or uglifyES are provided.
// You should use this option if you need to ensure es5 support. uglify-js will produce an error message
// if it comes across any es6 code that it can't parse.
},
uglifyES: {
// These pass straight through to uglify-es.
// Cannot be used with uglifyJS.
// uglify-es is a version of uglify that understands newer es6 syntax. You should use this option if the
// files that you're minifying do not need to run in older browsers/versions of node.
}
}),
],
};
webpack4 默认启用,一般无需关心。
[
new UglifyJsPlugin({
uglifyOptions: {
ie8: false,
ecma: 8,
parse: {...options},
mangle: {
...options,
properties: {
// mangle property options
}
},
output: {
comments: false,
beautify: false,
...options
},
compress: {...options},
warnings: false
}
})
]
terser 较 uglifyjs 压缩性能更好,推荐使用。而且用法很简单,webpack4 支持在 optimization 配置中指定压缩插件。
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
optimization: {
minimize: true,
minimizer: [new TerserPlugin()],
},
};
这个可以参考前面讲解 sourceMap的配置 的章节。
这个可以参考前面讲解 打包分析的章节,由其关注以下两个工具。
使用 dev-server
其实就是设置成 development,然后尽量少引入一些不必要的产检,比如开发环境完全没必要压缩。
happypack 原理解析