背景
前几天早晨上班的时候, 路过隔壁项目组, 听他们在聊我的项目构建的事:
当初线上打包工夫太长了, 修个 bug 1 分钟, 公布一下半小时, 贼好受。
他们我的项目比拟宏大, 线上构建工夫特地长, 根本都在15分钟以上
。
和他们简略聊了会, 回去瞅了一下本人我的项目的构建工夫:
其实也挺长的, 于是抽空优化了一下, 成果还是比拟显著的:
在注释局部,我将分享的内容次要是:
一些晋升 webpack 打包性能的配置
优化大型项目构建工夫的一些思考
心愿对大家有所启发。
注释
咱们我的项目不是很大, 是一个中型的国际化我的项目, 一百来个页面。
之前本地构建工夫挺长的,首次启动要三次分钟, 前面我配置了 Vite
, 本地启动工夫升高到了 20s
左右,感兴趣的能够移步我这篇文章:
Webpack to Vite, 为开发提速!
看了一下,线上构建工夫五六分钟,不痛不痒,然而应该也有优化空间,于是筹备优化一下。
1. 发现问题
既然要优化构建工夫, 第一步当然是先发现问题
, 找出比拟耗时
的阶段,再加以优化。
这里我用到了SMP
插件。
SMP
插件用法非常简单, 这里也简略提一下:
// webpack.config.js
const SpeedMeasurePlugin = require('speed-measure-webpack-plugin');
const smp = new SpeedMeasurePlugin();
module.exports = smp.wrap({
// ...
});
利用 SMP
插件得出各个阶段的打包耗时:
发现两个比拟显著的问题:
IgnorePlugin
耗时靠近 20 秒。less-loader
局部执行了2次,节约了一分多钟。ts-loader
耗时一分半, 也挺长的。
2. 解决问题
1. IgnorePlugin
查看了一下配置, 发现配置里的 IgnorePlugin
并没有达到预期的成果, 删掉。
2. less-loader
查看配置后发现, 在解决less
的局部,的确多解决了一遍。
less 文件的解决,能够间接看官网文档,文档地址:
https://webpack.docschina.org…
我的配置:
{
test: /\.less$/,
use: [
'style-loader',
'css-loader',
{
loader: 'less-loader',
options: {
javascriptEnabled: true,
sourceMap: true,
modifyVars: {
// inject our own global vars
// https://github.com/ant-design/ant-design/issues/16464#issuecomment-491656849
hack: `true;@import '${require.resolve('./src/vars.less')}';`,
...themeVariables,
},
limit: 10000,
name: '[name].[hash:7].[ext]',
outputPath: 'styles/',
},
},
],
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
3. ts-loader
对于ts-loader
局部的优化, 能够参考:
https://webpack.js.org/guides…
文档上也有比拟清晰的形容:
文档倡议, 咱们开启transpileOnly
选项,敞开类型查看。
如果要类型查看, 能够应用 ForkTsCheckerWebpackPlugin
,这个插件会在另外一个过程中做相干的查看。
这个插件,咱们在优化构建时内存溢出的问题上, 也做了摸索, 感兴趣的能够移步我这篇文章:
我的项目构建内存溢出了?看看 Node 内存限度
当初咱们也开启这个选项。
开启之后, 本地构建的时候, 本地报了个正告:
这个谬误, 非常的眼生, 是之前咱们讲过的 import type
的问题,
你不晓得的 「 import type 」
修复一下:
问题解决。
从新构建, 失去如下后果:
优化之后之后, 咱们发现:
IgnorePlugin、HtmlWebpackPlugin
工夫大幅缩短。less-loader
等复原了失常,只执行了一次。ts-loader
工夫大幅缩短,由1分30秒缩短为40秒。
本地成果显著,须要去线上构建验证。
3. 确认无效
在线上执行之后, 失去如下后果:
而后去查看了一下页面,也都是失常的。
完满!
回头看,不难发现,其实也没改多少货色, 就播种了不错的成果。
针对中小型我的项目来说, 改改配置往往就能达到咱们的要求, 然而如果是面对大型项目
呢?
比方那种数十个模块, 几百个页面的我的项目。
回到结尾那个问题: 修个 bug 1 分钟, 公布一下半小时
。
简略的批改配置, 都无奈把工夫降下来, 这时候该怎么办呢?
优化大型项目构建工夫的一些思考
拆分子利用
假如咱们有一个我的项目,大模块就有将近30个:
每个大模块外面又有几十个页面,这种零碎构建工夫会比拟久, 须要做优化。
而且到了我的项目前期,问题会越来越显著, 比方:
- 代码越来越臃肿
- 业务模块自身无关联
- 构建速度越来越慢
- 无奈独立部署
面对这种状况,一种可行的做法是:拆分子利用
。
拆分之后的架构:
每个子项目都有独自的入口, 是能够独立部署的我的项目。
子项目打成独自umd
包:
在主我的项目启动的时候, 再去加载这些子项目:
加载实现之后, 须要解决路由
以及store
, 示例代码:
// base
export const bootstrap = () => {
// ...
ReactDOM.render((
<Provider store={store}>
<Router history={history}>
<App defaultInitialData={_initialData} />
</Router>
</Provider>
), document.getElementById('root'));
return Promise.resolve();
};
// main
const loadSubApp = (htmlEntry: string) => {
return importHTML(`${htmlEntry}?${Date.now()}`)
.then((res: any) => res.execScripts())
.then((exportedValues: any) => {
console.log(`importHTML: ${htmlEntry} loaded, exports:`, exportedValues);
const { store, router } = exportedValues || {} as any;
router && addCustomRouter(router);
store && addCustomStore(store);
})
.catch(e => {
console.error('importHTML: ${htmlEntry} load error:', e);
});
};
const load = () => {
if (__ENV__ !== 'dev') {
const paths: string[] = [];
subAppConfig.subApps.forEach(item => {
if (item.project === localStorage.getItem('ops_project')) {
paths.push(...item.paths);
}
});
Promise.all(paths.map(path => loadSubApp(path)))
.catch(e => console.log(e))
.finally(setAllLoaded);
} else {
setAllLoaded();
}
};
const init = () => {
console.log('init: Start to bootstrap the main APP');
addCustomStore(rootStore);
bootstrap().then(() => {
load();
});
};
init();
代码共享
common
包-
- component
-
- utils
-
- typings
-
- ..
externals
-
- react全家桶
-
- moment
-
- antd
-
- ..
款式隔离
给款式增加以子项目为名的 namespace
:
开发调试
以 ops 我的项目为例。
让开发调试 ops-common 包像本地文件一样不便:
- 让我的项目来编译 common 包
- wepback alias
- TS alias
独立部署
在同一个project上为每个子项目申请独立module
拆分子利用的优缺点
长处:
- 每个子利用都能够
独立公布
, 子模块和主模块解偶
。 - 子项目是能够
独自编译
的,主我的项目只须要做引入即可, 以此缩小主模块的构建工夫
。
毛病:
- 额定的复杂性和保护老本
论断
一般来说,对于中小型我的项目,做好打包配置的优化, 可能解决一部分问题。
大型项目的构建工夫优化, 能够思考拆分子利用的模式。
只不过这种模式须要思考一些保护
的问题,比方如何保护版本 tag、如何疾速回滚等。
这些须要联合你们我的项目的理论状况
再做决定。
明天的内容就这么多,心愿对大家有所启发。
最初
祝大家五一高兴~~
如果感觉文章内容有帮忙, 能够关注下我哦, 把握最新动静。
也能够加我微信 「 scaukk 」, 一起探讨。
发表回复