Mig*_*g82 15 javascript heap-memory eslint
我正在尝试在一个非常大的 javascript 文件上运行EsLint,但该进程内存不足。为了让您了解文件有多大,我在其上运行了Cloc,这是输出:
$ cloc app.js
1 text file.
1 unique file.
0 files ignored.
github.com/AlDanial/cloc v 1.80 T=12.81 s (0.1 files/s, 42499.8 lines/s)
-------------------------------------------------------------------------------
Language files blank comment code
-------------------------------------------------------------------------------
JavaScript 1 4255 23744 516524
-------------------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)
该文件重 23MB。
$ ls -lAh app.js
-rw-r--r-- 1 miguelangel staff 23M Jan 28 11:58 app.js
Run Code Online (Sandbox Code Playgroud)
这就是说这很可能不是EsLint 中的内存泄漏。我在 Github.com 上看到 EsLint 存在内存泄漏的一些问题。我不认为这是这里的情况。
文件这么大是因为它是连接许多其他 Javascript 模块的结果。我的目标是尝试找到任何未使用的代码。这个项目的代码库显然在不受控制的情况下增长,我正试图摆脱沉重的负担。所以我试图在整个代码库的串联上运行EsLint 的no-unused-vars
规则。这是我的 EsLint 配置文件:
.eslintrc.js
module.exports = {
"env": {
"browser": true,
"commonjs": false,
"es6": true
},
"parserOptions": {
"ecmaVersion": 2015
},
"rules": {
"no-unused-vars": [
"warn"
]
}
};
Run Code Online (Sandbox Code Playgroud)
这个项目既不是 Node 也不是 AMD 项目,所以我想我必须将整个代码库放在一个文件中以避免误报。
问题是尝试在此文件上运行 EsLint 会导致JavaScript heap out of memory
错误。
$ eslint app.js
<--- Last few GCs --->
[60451:0x104002200] 43814 ms: Mark-sweep 1395.7 (1424.1) -> 1395.2 (1423.6) MB, 5719.6 / 0.0 ms (+ 0.1 ms in 28 steps since start of marking, biggest step 0.0 ms, walltime since start of marking 5755 ms) (average mu = 0.148, current mu = 0.037) alloca[60451:0x104002200] 49447 ms: Mark-sweep 1397.4 (1424.1) -> 1396.9 (1425.6) MB, 5569.8 / 0.0 ms (+ 0.1 ms in 11 steps since start of marking, biggest step 0.0 ms, walltime since start of marking 5598 ms) (average mu = 0.081, current mu = 0.011) alloca
<--- JS stacktrace --->
==== JS stack trace =========================================
0: ExitFrame [pc: 0x3275f3d4fb7d]
Security context: 0x14c691f9d969 <JSObject>
1: /* anonymous */ [0x14c6f1b7b981] [/usr/local/lib/node_modules/eslint/node_modules/acorn/dist/acorn.js:~2868] [pc=0x3275f40f5843](this=0x14c6b794c669 <Parser map = 0x14c603088f11>)
2: /* anonymous */ [0x14c6f1b7b111] [/usr/local/lib/node_modules/eslint/node_modules/acorn/dist/acorn.js:2190] [bytecode=0x14c691fecb01 offset=968](this=0x14c6b794c669 <...
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
1: 0x10003ace0 node::Abort() [/usr/local/bin/node]
2: 0x10003aeb1 node::OnFatalError(char const*, char const*) [/usr/local/bin/node]
3: 0x10018c8cf v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [/usr/local/bin/node]
4: 0x10018c870 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [/usr/local/bin/node]
5: 0x10047b188 v8::internal::Heap::UpdateSurvivalStatistics(int) [/usr/local/bin/node]
6: 0x10047cc01 v8::internal::Heap::CheckIneffectiveMarkCompact(unsigned long, double) [/usr/local/bin/node]
7: 0x10047a4c4 v8::internal::Heap::PerformGarbageCollection(v8::internal::GarbageCollector, v8::GCCallbackFlags) [/usr/local/bin/node]
8: 0x100479236 v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [/usr/local/bin/node]
9: 0x100481826 v8::internal::Heap::AllocateRawWithLightRetry(int, v8::internal::AllocationSpace, v8::internal::AllocationAlignment) [/usr/local/bin/node]
10: 0x100481b5c v8::internal::Heap::AllocateRawWithRetryOrFail(int, v8::internal::AllocationSpace, v8::internal::AllocationAlignment) [/usr/local/bin/node]
11: 0x100461562 v8::internal::Factory::NewFillerObject(int, bool, v8::internal::AllocationSpace) [/usr/local/bin/node]
12: 0x100653464 v8::internal::Runtime_AllocateInNewSpace(int, v8::internal::Object**, v8::internal::Isolate*) [/usr/local/bin/node]
13: 0x3275f3d4fb7d
Abort trap: 6
Run Code Online (Sandbox Code Playgroud)
如何增加 EsLint 对内存的访问?
Mig*_*g82 21
我浏览了 EsLint 文档,希望找到一个选项来配置它以使用更多内存运行。可悲的是,我找不到任何类似的东西。
然而,受到@vsemozhetbyt 的回答的启发——因此投票——我开始研究 Node 的配置选项,我找到了一种使用Node 的NODE_OPTIONS
环境变量来解决这个问题的方法。
以空格分隔的命令行选项列表。选项...被解释为好像它们已在实际命令行之前在命令行上指定
所以这就是我所做的:
$ export NODE_OPTIONS="--max-old-space-size=4096"
$ echo $NODE_OPTIONS
--max-old-space-size=4096
$ eslint app.js
Run Code Online (Sandbox Code Playgroud)
这样,运行 EsLint 的 Node 进程只需选择它,而无需我--max-old-space-size
每次调用 EsLint 时输入标志或 Node 二进制文件的路径。
默认情况下,Node.js 将内存限制设置为接近 1.5 GB。您可以--max_old_space_size
按键增加它(例如,--max_old_space_size=4096
使用 4 GB)。
要使用密钥,您需要知道 ESLint 主文件的路径并通过以下方式将其作为脚本调用:
node --max_old_space_size=4096 ./node_modules/eslint/bin/eslint.js app.js
Run Code Online (Sandbox Code Playgroud)
我在 Laravel/Vue 应用程序中遇到了这个问题。这些细节并不重要,但 Laravel 有一些文件夹(例如vendor
包含所有composer
包)的事实意味着 ES Lint 正在遍历大量文件,足以炸毁堆。
解决办法是先.eslintignore
在项目根目录下添加一个文件,如:
/app
/bootstrap
/config
/database
/node_modules
/public
/routes
/storage
/tests
/vendor
Run Code Online (Sandbox Code Playgroud)
接下来,从 CLI(和 GitLab-CI)执行 ES Lint:
node_modules/eslint/bin/eslint.js --config ./.eslintrc.json .
Run Code Online (Sandbox Code Playgroud)
确保 ES Lint 使用正确的配置文件来检查预期的规则集也很重要。
您可以通过添加--debug
到您的 CLI 命令中来直观地测试其中的一些,如果发生这种情况,您将看到它遍历非法文件夹和文件。我认为这是一个不错的调试步骤——在详细模式下测试它。您可能会看到 ES Lint 遍历不必要的文件夹或针对不正确的规则进行测试。
在我看来,这个问题很容易源于 ES Lint 在工作时试图将大量错误加载到内存中。您可以拨入 ES Lint 正在检查的内容,而不是增加堆。
小智 5
将.env
文件放入您的文件夹中,内容为:
NODE_OPTIONS=--max_old_space_size=4096
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
12005 次 |
最近记录: |