1.问题
最近 WMS V2 项目 在 Jenkins 上部署前端代码时 build 不成功,如 图1.1 所示:
图1.1 Jenkins 部署过程
查看 部署日志 的时候我们可以看到这个错误,如 图1.2 所示:
图1.2 Jenkins 部署 Log
由此我们可以知道部署失败的主要原因是项目的代码过大,导致内存不够。
2.思考
现在我们知道部署失败是由于 WMS V2 项目代码过大,要从根本上解决这个问题,就是要优化我们的项目代码,减少代码的重复率,提高业务组件和函数的使用率。但是因为这个问题,test 环境的一直不能 build 最新的代码,而优化项目代码并不是一朝一夕的事情,当前的紧急任务是让 test 环境 build 到最新的代码,而且不能对原有代码有非常大的改动,因为有大的改动的话,不能确保是否代码的修改是否会对其它业务造成影响。
那最解决构建内存不够这个问题的最直接的方法就是增大内存。
首先我们会想到也许是因为 Node.js 内存不够,在 Node.js 里面,V8 自动帮助我们进行垃圾回收。但我们会思考,Node 进程的 Memory Limit 会是多少呢?在网上我们可以查阅到:
Currently, by default V8 has a memory limit of 512mb on 32-bit systems, and 1gb on 64-bit systems. The limit can be raised by setting —max-old-space-size to a maximum of ~1gb (32-bit) and ~1.7gb (64-bit), but it is recommended that you split your single process into several workers if you are hitting memory limits.
那我们先来看看 Node Process 的 Memory Limit 究竟是多少。最直接的方法就是写一段代码来把内存弄爆,这就知道内存限制是多少了。
代码地址: 代码在这里
我们可以直接用 Node 去运行这段代码,可以在 terminal 看到如图 2.1 所示的结果:
图2.1 Terminal 运行结果
我的电脑是 Macbook Pro masOS Catalina 16GB,Node 版本是 v12.16.1,这段代码大概在 1.6 GB 左右内存时候抛出异常。那我们现在知道 Node Process 确实是有一个内存限制的。那我们就来增大它的内存限制呗。
我们可以用 node —max-old-space-size=6000 来运行这段代码,我们来看看在 terminal 的结果如 图2.2 所示:
图2.2 Terminal 运行结果
一方面我们可以尝试在 build 的时候增大内存老生代区域的大小,我们修改 deploy 文件夹下的部署文件 build 时候的 commands,如图 2.3 所示:
图2.3 部署文件
另一方面因为我们的项目是用 Vue 的脚手架搭建起来的,webpack 的实现都是封装好的了。这时我们可以从另一个方向入手 - webpack plugin,或许可以通过 plugin 来修改 build 的时候的内存大小。
在 vue.config.js 里面我们引入 fork-ts-checker-webpack-plugin,通过它修改内存限制的大小,代码如图2.4所示:
configureWebpack: config => { // get a reference to the existing ForkTsCheckerWebpackPlugin const existingForkTsChecker = config.plugins.filter( p => p instanceof ForkTsCheckerWebpackPlugin, )[0]; // remove the existing ForkTsCheckerWebpackPlugin // so that we can replace it with our modified version config.plugins = config.plugins.filter( p => !(p instanceof ForkTsCheckerWebpackPlugin), ); // copy the options from the original ForkTsCheckerWebpackPlugin // instance and add the memoryLimit property const forkTsCheckerOptions = existingForkTsChecker.options; forkTsCheckerOptions.memoryLimit = 4096; config.plugins.push(new ForkTsCheckerWebpackPlugin(forkTsCheckerOptions)); }, |
---|
图2.4 vue.config.js 文件
这时候在 Jenkins 上 build 项目的时候就成功了。
在 vue.config.js 里面我们引入 fork-ts-checker-webpack-plugin 后我们就可以成功构建我们。是因为 fork-ts-checker-webpack-plugin 会在单独的进程里做 Typescript 类型检测和 ESLint 检查(by moving each to a separate process),不仅减少了在一个进程里的内存开销,而且加快了项目的构建速度,而 Typescript 类型检测是非常耗费内存的。
3.总结
现在 WMS V2 项目 在 Jenkins 上部署前端代码时 build 不成功,部署失败是由于 WMS V2 项目代码过大。为了可以让项目构建成功,而且不对代码进行大的改动。临时的一种方式是增大项目的构建内存。而项目构建时 Typescript 类型检测是非常耗费内存的。在 vue.config.js 里面我们引入 fork-ts-checker-webpack-plugin,fork-ts-checker-webpack-plugin 会在单独的进程里做 Typescript 类型检测和 ESLint 检查(by moving each to a separate process),不仅减少了在一个进程里的内存开销,而且加快了项目的构建速度。
当然项目构建失败的根本原因是项目代码过大,要从根本上解决这个问题,就是要优化我们的项目代码,减少代码的重复率,提高业务组件和工具函数的使用率。这也是我们日后优化的重心。
4.分享
在这个查阅过程中,看到一些有意思的文章,有兴趣的同事可以去看看: