nuxtにtypescriptを入れたnuxtプロジェクトにて、古くなったパッケージの更新を行った後に遭遇したメモリエラーの記録です。実際は、node_modulesをbackアップしてnode_modules_bak
のようなディレクトリを作成していたというチョンボなのですが、そのとき@nuxt/typescript-build
について調べたので、そのときの内容を共有しようと思います。
目次
環境について
バージョンアップ後の主要モジュールのバージョンは以下の通りです。
- nuxt@2.12.2
- typescript@3.8.3
- @nuxt/typescript-build@1.0.2
発生していた現象
yarn build
を行うと90%前後まで進んでしばらくすると、下記のようなエラーログが出力されます。
<--- Last few GCs --->
[89792:0x108008000] 54574 ms: Scavenge 2044.1 (2051.1) -> 2042.7 (2051.3) MB, 2.2 / 0.0 ms (average mu = 0.219, current mu = 0.104) allocation failure
[89792:0x108008000] 54580 ms: Scavenge 2044.4 (2051.3) -> 2043.0 (2051.6) MB, 2.3 / 0.0 ms (average mu = 0.219, current mu = 0.104) allocation failure
[89792:0x108008000] 54588 ms: Scavenge 2044.6 (2051.6) -> 2043.2 (2056.3) MB, 2.7 / 0.0 ms (average mu = 0.219, current mu = 0.104) allocation failure
<--- JS stacktrace --->
==== JS stack trace =========================================
0: ExitFrame [pc: 0x100950919]
1: StubFrame [pc: 0x1008fc271]
Security context: 0x1269d26c08d1 <JSObject>
2: slice [0x1269d26ceba9](this=0x1269a3522fe9 <JSArray[14]>,1)
3: parseNodeModuleFromPath(aka parseNodeModuleFromPath) [0x1269d9d1a9e9] [/Users/kawashima/work/app-swing-by/closb/web-ui/cloud-gen-wui/node_modules/typescript/lib/typescript.js:~30223] [pc=0xe0405f03469](this=0x126998e804b1 <undefined>,0x1269a3522d49 <Obje...
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
Writing Node.js report to file: report.20200813.101626.89792.0.001.json
Node.js report completed
1: 0x100080c68 node::Abort() [/Users/kawashima/.nodebrew/node/v12.16.1/bin/node]
2: 0x100080dec node::errors::TryCatchScope::~TryCatchScope() [/Users/kawashima/.nodebrew/node/v12.16.1/bin/node]
3: 0x100185167 v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [/Users/kawashima/.nodebrew/node/v12.16.1/bin/node]
4: 0x100185103 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [/Users/kawashima/.nodebrew/node/v12.16.1/bin/node]
5: 0x10030b2f5 v8::internal::Heap::FatalProcessOutOfMemory(char const*) [/Users/kawashima/.nodebrew/node/v12.16.1/bin/node]
6: 0x10030c9c4 v8::internal::Heap::RecomputeLimits(v8::internal::GarbageCollector) [/Users/kawashima/.nodebrew/node/v12.16.1/bin/node]
7: 0x100309837 v8::internal::Heap::PerformGarbageCollection(v8::internal::GarbageCollector, v8::GCCallbackFlags) [/Users/kawashima/.nodebrew/node/v12.16.1/bin/node]
8: 0x1003077fd v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [/Users/kawashima/.nodebrew/node/v12.16.1/bin/node]
9: 0x100312fba v8::internal::Heap::AllocateRawWithLightRetry(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [/Users/kawashima/.nodebrew/node/v12.16.1/bin/node]
✔ Client
Compiled successfully in 56.76s
✔ Server
Compiled successfully in 20.71s
調査してみると、ビルドの中でtypescriptの型チェックが実行されていることがわかりました。nuxt.config.js
は、下記のような設定になっています。
/*
** Nuxt.js dev-modules
*/
buildModules: [
'@nuxtjs/vuetify',
'@nuxt/typescript-build',
'nuxt-typed-vuex'
],
ビルドには、@nuxt/typescript-build
を利用しています。nuxt typescriptにModule optionsが記載されていますが、ビルド時の型チェックを無効にする方法は、typeCheck
にfalse
を設定してます。typecCheck
は、オブジェクトか真偽値(object | boolean
)で定義されています。object
については、fork-ts-checker-webpack-plugin
に定義されているのでそちらを参照してください。
buildModules: [
'@nuxtjs/vuetify',
['@nuxt/typescript-build', {
typeCheck: false
}],
'nuxt-typed-vuex'
],
エラーログにある「ERROR Issues checking service aborted - probably out of memory. Check the memoryLimit option in the ForkTsCheckerWebpackPlugin configuration.
」の部分に注目し、メモリ上限についても確認してみます。
メモリ上限について
メモリ上限の割当には、nodeのオプションを利用する方法とfork-ts-checker-webpack-pluginのオプションを利用する方法があります。
nuxt.config.js
にfork-ts-checker-webpack-pluginのオプションを渡すには、下記に記載します。memoryLimit
は、MBで指定します。
〜省略〜
['@nuxt/typescript-build', {
typeCheck: {
async: true,
typescript: {
enable: true,
memoryLimit: 16384,
},
〜省略〜
memoryLimitのデフォルト値は、2048MBです。fork-ts-checker-webpack-plugin/src/typescript-reporter/TypeScriptReporter
で定義されています。
node -v8オプション
--max_old_space_size
オプションで指定できます。v8オプションは他にも便利なもの例えば、--gc_interval
などもあるので調べてみると面白いと思います。
おわりに
今回は、チョンボから色々ビルド処理の流れなどを追ってメモリ上限などについても調べました。今後、プロジェクトが肥大化するとビルドプロセスを見直した高速化なども取り組んだ内容なども共有していこうと思ってますので、楽しみにしていて下さい。