如何让webpack打包的速度提升50%?
随着前端应用包含的模块数量日益增长,代码打包的耗时也越来越长。公司很多项目打包耗时超过了10秒,对于一般人来说超过10秒的等待是比较难受的,虽然后续增量编辑的速度很快。于是我想结合实际开发环境提升一下首次打包的速度。
1. 实际开发环境
我碰到大多数处于维护状态的网站都有一下几个特性:
- 模块数量庞大
- 模块中主要分为js模块和css模块,并且less模块最后使用
extract-text-webpack-plugin
打包出单独的css文件 - webpack入口文件包含了js和less,所以每次打包都需要处理js和less模块
- 许多需求只涉及到js模块的修改,并不涉及样式修改。反之亦然。
2. 优化思路
既然许多情况下编译less模块不是必须的,那在这些情况下单独编译js模块就能大幅提升webpack的性能。毕竟less的编译、以及css的抽出都非常消耗时间。
3. 优化步骤
优化包含以下两步:
- 区分编译目标,单独编译js? 还是单独编辑css? 还是js+css?
- 入口文件分离js和css
3.1 区分编译目标
这一步比较简单,我们需要使用cross-env
这个插件,例如下面两条编译命令区分了编译js和编译js+css。
{
"scripts": {
"build:js": "cross-env ctarget=all webpack",
"biuld:js+css": "cross-env ctarget=js webpack"
}
}
这样我们就可以在webpack配置文件中通过process.env.ctarget
区分当前编译目标了。
3.2 分离js和css
这一步需要通过webpack的loader来实现,可以使用现有的轮子string-replace-loader
。
这个loader可以在编译阶段修改代码,并且可以使用正则表达式进行替换。可以使用它来加载js文件,然后删除部分代码。下面的例子的作用是删除js文件中所有的less代码导入。
{
module: {
rules: [
{
test: /.js$/,
use: (function(){
var list = ['这里可以加上其他需要的loader'];
// 更具编译目标删除less的导入
if (process.env.ctarget === 'js') {
list.push({
loader: 'string-replace-loader',
options: {
search: '^.+?require\\(.+(\\.less).+$',
replace: '',
flags: 'm'
}
})
}
return list;
})()
}
]
}
}
这里在使用string-replace-loader
一定要加上flags: 'm'
,否则无法进行多行匹配。
如果要单独打包css我们可以写一个和
string-replace-loader
作用相反的loader,只保留样式部分而删除其他js代码。
4. 效果
经过实际测试,这个优化可以节省50%的时间。当然具体到每一个项目还要看js和css模块数量的比例。
转载自:https://juejin.cn/post/6844903604126482440