Table of Contents
问题描述
在打包大的项目时,打包过程中会报错失败。报错信息为 FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory in XXX。
首先一定要排除代码中是否有会导致内存泄露的可能,如果没有内存泄露,项目又比较大,打包过程确实消耗较大的内存,那么请继续阅读。
查阅资料后发现,当电脑内存为 8G 时,安装 node,默认分配给堆的内存大小就是 2G,一旦项目运行时超过这个限制就会报错。可以使用如下命令来查看自己的堆大小限制:
node -e 'console.log(v8.getHeapStatistics().heap_size_limit/(1024*1024))'解决方案
既然是分配给堆的内存大小不够造成的问题,那么在打包时将堆的内存大小设置大一些即可。
windows 环境下使用 set 关键字设置
set NODE_OPTIONS=--max-old-space-size=4096 && npm run buildlinux 或 macOS 环境下使用 export 关键字设置
export NODE_OPTIONS=--max-old-space-size=4096 && npm run build永久设置
上述对内存大小的设置,都仅在当前执行环境生效,下次还需要重新设置。如何实现永久化设置?
windows 环境
需要通过 我的电脑 - 属性 - 高级系统设置 - 环境变量 来配置。
linux 或 macOS 环境
- 需要修改系统文件,修改所有用户或当前用户皆可。
# 所有用户/etc/profile# 当前用户~/.bash_profile- 打开文件,并在文件末尾添加对环境变量的修改
export NODE_OPTIONS=--max-old-space-size=4096- 修改完成后,重新加载系统文件
# 所有用户source /etc/profile# 当前用户source ~/.bash_profile跨端设置
修改环境变量,基本上解决了个人的问题,但基于 DEVOPS 的构建环境,打包动作并不是只在本机运行,那么就会遇到新的问题:CI/CD 服务器也可能出现内存资源不足的情况,需要在服务器环境自动构建时,也设置环境变量。
解决方案:把设置环境变量的操作写入 package.json 的 scripts 中。
// 修改前{ ... "scripts": { "build": "craco build" }}// 修改后{ ... "scripts": { "build": "set NODE_OPTIONS=--max-old-space-size=4096 && craco build" }}如果本机环境为 windows,CI/CD 服务器的环境为 linux,这时你会发现自动构建还是会报错,因为 linux 系统并不支持 set 关键字,而需要使用 export 关键字。如何解决这个跨系统的问题呢?
网上大量的文章推荐了 cross-env 这个库,当通过 npm 安装这个库后,并修改命令:
npm i -D cross-env{ ... "scripts": "cross-env NODE_OPTIONS=--max-old-space-size=4096 && craco build"}你会发现并没有效果。因为 cross-env 并不支持串行命令,环境变量只影响到了 && 前的执行环境,&& 后的 craco build 并没有修改到环境变量。
我最终选择了 cross-os 这个库,在不同的环境下,执行不同的命令。
# 安装npm i -D cross-os// 配置{ ... "scripts": { "build": "cross-os memory-build", }, "cross-os": { "memory-build": { "win32": "set NODE_OPTIONS=--max_old_space_size=4096 && craco build", // windows 环境 "darwin": "export NODE_OPTIONS=--max_old_space_size=4096 && craco build", // macOS 环境 "linux": "export NODE_OPTIONS=--max_old_space_size=4096 && craco build" // linux 环境 } }}参考资料