这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战
首先说明优化目的:
1、加速打包时间
2、减少打包后的体积
一、加速打包时间
要加速打包时间,就需要先缩⼩⽂件搜索范围,一般影响整体打包的时间主要是loader和plugin两个的编译构建的过程。需要先压缩,再优化,可以减少很多打包时间。所以我们要先减少搜索文件的过程,提前编译和缓存等几个方法实现
1、优化loader查找文件范围
可以使用test、include、exclude三个配置项来缩⼩loader的处理范围,推荐include
//string
include: path.resolve(__dirname, "./src"),
//array
include: [
path.resolve(__dirname, 'app/styles'),
path.resolve(__dirname, 'vendor/styles')
]
注:exclude 优先级要优于 include 和 test ,所以三个都配置时, exclude 会优先于其他两 个配置
2、优化resolve.modules配置
reslove.modules用于配置webpack打包后在哪个目录下查找模块,默认是node_modules,可以配置:
module.exports={
resolve:{
modules: [path.resolve(__dirname, "./node_modules")]
}
}
3、优化resolve.alias配置
resolve.alias主要是配置别名,把原路径映射为一个新配置的路径,我们可以直接指定文件路径,避免查找的耗时
alias: {
"@": path.join(__dirname, "./pages"),
react: path.resolve(
__dirname,
"./node_modules/react/umd/react.production.min.js"
),
"react-dom": path.resolve(
__dirname,
"./node_modules/react-dom/umd/react-dom.production.min.js"
)
},
resolve: {
alias: {
"@assets": path.resolve(__dirname, "../src/images/"),
},
}
//html-css中使⽤
.sprite3 {
background: url("~@assets/s3.png");
}
4、优化resolve.extensions配置
resolve.extensions在导入语句没写入文件后缀时,webpack会自动带入后缀,并尝试查找文件是否存在
默认配置:extensions:['.js','.json','.jsx','.ts']
所以我们在开发过程中,尽量带入后缀,减少查找文件的时间
5、使用cache缓存
webpack打包的核心是js文件的打包,js使用babel-loader。所以打包时间长主要是babel-loader执行太慢导致的,这时需要使用exclude和include来准确的确定转换内容的范围,并减少重复文件的转换,造成打包后文件体积过大,也会增大编译速度。
使用cacheDirectory配置给babel编译时指定的目录,并且用于缓存加载的结果,但是默认是false,需要手动设置为true,默认的缓存目录是node_modules/.cache/babel-loader ,但是如果在任何根⽬录下都没有找到 node_modules ⽬录,就会降级回退到操作系统默认的临时⽂件⽬录。
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
options: {
cacheDirectory: true
},
}
];
二、减少打包后的体积
除了构建之外,压缩打包后的体积也比较重要,除了上面提到的cache还可以使用terser-webpack-plugin的时候配置使用多线程和缓存实现。
题外话:在2017年的时候,刚会vue一年,因为项目中必须使用jq,打包后体积太大,成为当时一大难题,弄了一两天才解决,真的是各个方面都要考虑到,解决办法下面会提到
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
optimization: {
minimizer: [
new TerserPlugin({
cache: true, // 开启缓存
parallel: true // 多线程
})
]
}
};
还可以使用cdn地址或者自己服务器的地址存放一些静态资源文件,这样在打包的时候就不需要打包一大堆东西了,可以很大程度的减少打包后的体积,比如:超大的背景图片,jq地址使用cdn,echarts图表类的等,
如果需要在使用的时候可以通过import的方法引入jq(import $ from 'jquery')或echarts并且不会对其打包,可以尝试配置externals
//webpack.config.js
module.exports = {
externals: {
//jquery通过script引⼊之后,全局中即有了 jQuery 变量
'jquery': 'jQuery'
}
}
CSS的压缩
使用optimize-css-assets-webpack-plugin,是一个压缩css的插件,默认引擎是cssnano,css-loader已经集成了cssnano,可以使用optimize-css-assets-webpack-plugin来自定义规则
//安装命令
npm install cssnano -D
npm i optimize-css-assets-webpack-plugin -D
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
new OptimizeCSSAssetsPlugin({
cssProcessor: require("cssnano"), // 可以指定引擎,默认是 cssnano
cssProcessorOptions: {
discardComments: { removeAll: true }
}
})
HTML的压缩
//使用html-webpack-plugin
new htmlWebpackPlugin({
title: "京东商城",
template: "./index.html",
filename: "index.html",
minify: {
// 压缩HTML⽂件
removeComments: true, //删掉HTML里的注释
collapseWhitespace: true, // 删除空⽩符和换⾏符
minifyCSS: true // 压缩内联css
}
})
JS的压缩
虽然webpack会自动压缩js,但是还是推荐使用terser-webpack-plugin,也是webpack官方维护的插件。
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
optimization: {
minimizer: [new TerserPlugin(
parallel: true //使用并开启多线程减少压缩的耗时
)]
}
};