在项目开发迭代的过程中,项目变得越来越庞大以后打包的时间会变长,体积会变大。这不仅会影响我们项目加载的体验,也会降低我们开发调试的效率。本文对打包时间和打包体积两个方面的优化进行了总结。
一、优化打包速度
配置方法如下:
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
const smp = new SpeedMeasurePlugin();
const webpackConfig = smp.wrap({
plugins: [
new MyPlugin(),
new MyOtherPlugin()
]
});分析结果:
因为webpack也是单线程模式,打包时只能一个文件一个文件的进行编译,当需要打包的文件过时,打包会变的非常慢。
const HappyPack = require('happypack');
const os = require('os');
const happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length });
module.exports = {
module: {
rules: [{
test: /\.js$/,/把对.js 的文件处理交给id为happyBabel 的HappyPack 的实例执行
use: [{
loader: 'happypack/loader',
options: { id: 'happyBabel' }
}],
//排除node_modules 目录下的文件
exclude: /node_modules/
}]
},
plugins: [
new HappyPack({
id: 'happyBabel',
use: [{
loader: 'babel-loader',
options: {
presets: ['react', 'stage-0', 'env' ],
plugins: ['transform-runtime', 'transform-class-properties']
}
}],
//共享进程池
threadPool: happyThreadPool,
//允许 HappyPack 输出日志
verbose: true,
})
]
}2、不经常变化的依赖包不参与打包进程:
2.1 : cdn 引入资源,设置不打包这些文件
webpack.config.jsmodule.exports = {
//...
externals: { jquery: 'jQuery' }
};2.2:没有模块依赖关系的,如果一些第三方模块没有AMD/CommonJS规范版本,可以使用 noParse来标识这个模块,这样webpack会引入这些模块,但是不进行转化和解析,从而提升webpack的构建性能,例如:jquery、lodash。注意被忽略掉的文件里不应该包含import、require、define等模块化语句,不然会导致构建出的代码中包含无法在浏览器环境下执行的模块化语句。noParse属性的值是一个正则表达式或者是function。
webpack.config.jsmodule.exports = {
//...
module: {
noParse: /jquery|lodash/
}
}3、优化loader的搜索范围
loader对文件的转换工作比较耗时,需要让尽可能少的文件被Loader处理。通过include去命中只有哪些件需要被处理。
4、babel编译过的文件可以缓存起来
cacheDirectory=true,loader 将使用默认的缓存目录 node_modules/.cache/babel-loader,如果在任何根目录下都没有找到node_modules目录,将会降级回退到操作系统默认的临时文件目录。
二:减小打包大小
通过配置webpack-bundle-analyzer插件可以分析打包体积。umi内置了此插件,只需在umi的config文件中加入analyzer配置,并在package.json添加analyzer命令即可:
// package.json
"scripts":{
"analyze": "set ANALYZE=1 && umi build"
}
// umi
config{
...,
plugins: [
// ref: https://umijs.org/plugin/umi-plugin-react.html
[
'umi-plugin-react',
{
...,
analyze: {
analyzerMode: 'server',
analyzerPort: 8888,
openAnalyzer: true,
// generate stats file while ANALYZE_DUMP exist
generateStatsFile: false,
statsFilename: 'stats.json',
logLevel: 'info',
defaultSizes: 'parsed',
// stat
// gzip
},
}
]
]
}new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /zh-cn/)npm install babel-plugin-import --save-dev
.babelrc 文件
{
"plugins": [
["import", { "libraryName": "antd", "libraryDirectory": "lib"}, "ant"],
["import", { "libraryName": "antd-mobile", "libraryDirectory": "lib"}, "antd-mobile"]
]
}
2、tree shaking :
webpack4 在在项目package.json文件中,添加一个"sideEffects" 属性后,在打包时会标记未引用代码为~unused harmony export square,在代码压缩的时候这些代码会被移除。umi中只需配置treeShaking: true,开启后效果还是很明显的:
在很多模块里,有相同的依赖,把这些依赖抽离为一个公共的文件,则可以有效地减少资源的体积,并可以充分利用浏览器缓存。不需要按照任何依赖,只需要在webpack config中加入optimization
splitChunksPlugin ,默认配置如下:
optimization:{
splitChunks: {
chunks: "async",// 选择分割哪些代码块,'all'(所有代码块),'async'(按需加载的代码块),'initial'(初始化代码块)。
minSize: 30000, // 模块的最小体积
minChunks: 1, // 模块的最小被引用次数
maxAsyncRequests: 5, // 按需加载的最大并行请求数
maxInitialRequests: 3, // 一个入口最大并行请求数
automaticNameDelimiter: '~', // 文件名的连接符
name: true,
cacheGroups: {
// 缓存组
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true
}
}
}
}
作者:汽车之家-前端体验部-王莹