Node.js v12にアップデートするとgulp v4でもfs.jsで「ReferenceError: primordials is not defined」エラーが発生

Chocolateyのnodejs-ltsでNode.jsを更新したところ、v10.16.3からv12.13.0になった。

その状態でgulp v3.9.2のタスクを実行してみると、fs.jsで ReferenceError: primordials is not defined というエラーが発生。

ちょっと調べると、Node.js v12とgulp v3の組み合わせは動かないので、Node.jsのバージョンを下げるかgulpをv4に上げろとのこと。

今更感が強いが、いい機会だと思い、Node.jsをv10.16.3に戻した状態でgulpをv4.0.2にバージョンアップ。

Node.jsをv12.13.0に更新し、タスクを実行すると...同じエラーが発生。

もろもろ調べて何とか解決したのでメモ。

環境

Node.js v12.13.0、gulp v4.0.2で確認。

パッケージ管理にはYarn v1.19.1を使用。

状況

Node.js v12.13.0とgulp v3.9.2の組み合わせてタスク実行すると、以下のエラーが発生。

fs.js:27
const { Math, Object } = primordials;
                         ^

ReferenceError: primordials is not defined
    at fs.js:27:26
    at req_ (${project_directory}\node_modules\natives\index.js:143:24)
    at Object.req [as require] (${project_directory}\node_modules\natives\index.js:55:10)
    at Object.<anonymous> (${project_directory}\node_modules\scp2\node_modules\graceful-fs\fs.js:1:37)
    at Module._compile (internal/modules/cjs/loader.js:956:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:973:10)
    at Module.load (internal/modules/cjs/loader.js:812:32)
    at Function.Module._load (internal/modules/cjs/loader.js:724:14)
    at Module.require (internal/modules/cjs/loader.js:849:19)
    at require (internal/modules/cjs/helpers.js:74:18)

Node.js v12.13.0に対応すべく、gulpをv4に、その他のnpmパッケージも更新。

gulpfile.jsもgulp v4向けに修正した上でタスク実行したが、エラーが解消しない。

調査と対応

gulpのissueを見ていたら、ちょっと気になるコメントがあった。

github.com

And to clarify even further, the natives module would only come from a VERY outdated version of graceful-fs that is not included in gulp 4 so it's going to be a different issue within your project (like an incorrect lockfile).

古いgraceful-fsが使われているnpmパッケージがあるのかと思い、 yarn list | grep graceful-fs してみると、graceful-fs@4... の中に1つだけ graceful-fs@3.0.11 があった。

依存関係をたどっていくと、gulp-scp2@0.2.0から推移していた。gulp-scp2は2015年のv0.2.0から更新されておらず、タスクも不要だったため、gulpfile.jsから削除し、yarn remove gulp-scp2 でパッケージも削除。

再度タスクを実行すると、エラーが消え、無事タスクが実行できた。

振り返り

エラーメッセージで検索していたら、Stack Overflowに、以下のQAがあった。

stackoverflow.com

Node.js v12とgulp v3では動かないので、Node.jsのバージョンを下げるかgulpをv4に上げるか、がベストアンサーになっているが、そこにこんなコメントがついていた。

I'm using node v12.1.0 and gulp gulp@4.0.2 but it doesn't work – Most Wanted May 7 at 12:50

エラーが const { Math, Object, Reflect } = primordials; になっていたりと、graceful-fsのバージョンによって微妙に異なるようだが、コメントした人も、古いnpmパッケージを知らず知らずのうちに使っていたのかもしれない。

どこかで、Node.js v12では内部APIの変更により、graceful-fsはv4でないと動かない、みたいな記述を見た気がしたが、気のせいだったかな...

あと、これを書いていて、エラーメッセージに思いっきりscp2って出ていたことに気づいた。

at Object.<anonymous> (${project_directory}\node_modules\scp2\node_modules\graceful-fs\fs.js:1:37)

やっぱりエラーメッセージはちゃんと読まないとダメだな...