Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8883

node.jsを10->12に更新したときに起きたエラーと対処内容

$
0
0

表題通りの記事です。
これからnode.jsを10->12に更新する方の助けになれば幸いです。

確認環境

  • Ubuntu: 18.04.3 LTS
  • node.js: 10.16.0、12.14.1
  • ビルドツール: gulp (後述しますが4系へのアップデートが必須でした)

やったこと(全体像)

  • nをつかってローカル環境のnode.jsを10->12に更新 (参考: nodeとnpmのバージョン更新方法)
  • npm ciして、出てきたエラーを潰す
    • firebaseの更新
    • node-sassの更新
  • npm run buildして、出てきたエラーを潰す
    • gulpを3系->4系へ移行

エラー1 (firebaseの更新により解消)

最初はイージーケースから。

事象

npm ciしたところ、大量(体感3分)のログが出力され、最後に以下のエラーが吐かれました。

# これ以前にも大量のエラーログが出る
cc1plus: error: unrecognized command line option ‘-Wno-cast-function-type’ [-Werror]
cc1plus: all warnings being treated as errors
grpc_node.target.mk:188: recipe for target 'Release/obj.target/grpc_node/ext/channel.o' failed
make: *** [Release/obj.target/grpc_node/ext/channel.o] Error 1

# 最後の方に出るmakeのログを見ることで、どのパッケージのビルドに失敗したかが分かる
# (repository-nameでgrepすると早く見つかる)
make: ディレクトリ '/home/user1/repository-name/node_modules/grpc/build' から出ます

gyp ERR! build error 
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit (/usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:194:23)
gyp ERR! stack     at ChildProcess.emit (events.js:223:5)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:272:12)
gyp ERR! System Linux 4.15.0-74-generic
gyp ERR! command "/usr/local/bin/node" "/usr/local/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "build" "--fallback-to-build" "--library=static_library" "--module=/home/user1/repository-name/node_modules/grpc/src/node/extension_binary/node-v72-linux-x64-glibc/grpc_node.node" "--module_name=grpc_node" "--module_path=/home/user1/repository-name/node_modules/grpc/src/node/extension_binary/node-v72-linux-x64-glibc" "--napi_version=5" "--node_abi_napi=napi" "--napi_build_version=0" "--node_napi_label=node-v72"
gyp ERR! cwd /home/user1/repository-name/node_modules/grpc
gyp ERR! node -v v12.14.1
gyp ERR! node-gyp -v v5.0.5
gyp ERR! not ok 
node-pre-gyp ERR! build error 
node-pre-gyp ERR! stack Error: Failed to execute '/usr/local/bin/node /usr/local/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js build --fallback-to-build --library=static_library --module=/home/user1/repository-name/node_modules/grpc/src/node/extension_binary/node-v72-linux-x64-glibc/grpc_node.node --module_name=grpc_node --module_path=/home/user1/repository-name/node_modules/grpc/src/node/extension_binary/node-v72-linux-x64-glibc --napi_version=5 --node_abi_napi=napi --napi_build_version=0 --node_napi_label=node-v72' (1)
node-pre-gyp ERR! stack     at ChildProcess.<anonymous> (/home/user1/repository-name/node_modules/grpc/node_modules/node-pre-gyp/lib/util/compile.js:83:29)
node-pre-gyp ERR! stack     at ChildProcess.emit (events.js:223:5)
node-pre-gyp ERR! stack     at maybeClose (internal/child_process.js:1021:16)
node-pre-gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:283:5)
node-pre-gyp ERR! System Linux 4.15.0-74-generic
node-pre-gyp ERR! command "/usr/local/bin/node" "/home/user1/repository-name/node_modules/grpc/node_modules/.bin/node-pre-gyp" "install" "--fallback-to-build" "--library=static_library"
node-pre-gyp ERR! cwd /home/user1/repository-name/node_modules/grpc
node-pre-gyp ERR! node -v v12.14.1
node-pre-gyp ERR! node-pre-gyp -v v0.12.0
node-pre-gyp ERR! not ok 

調べたこと

ログにあるとおり、grpcのビルドに失敗しています。
(最初は大量のログにとまどいました。どのパッケージがインストールできていないか調べるのが第一歩です)

更新対象リポジトリのpackage.jsonにはgrpcの記述がなく、
npm lsで依存パッケージを調べたところ、firebaseがgrpcに依存していました。

$ npm ls
# 結果を抜粋
├─┬ firebase@5.5.7
│ ├─┬ @firebase/firestore@0.8.6
│ │ ├─┬ grpc@1.13.1 <- ここでエラー

解決策

執筆時点でfirebaseは7系が最新。単純に古いので、アップデートしたところ解決。
(メジャーバージョン更新による影響も今のところなし)

$ npm install -D firebase




エラー2 (node-sassの更新により解消)

エラー1をちょっとひねったパターン。

事象

npm ciしたところ、大量(体感3分)のログが出力され、最後に以下のエラーが吐かれました。

# これ以前にも大量のエラーログが出る
/home/user1/.node-gyp/12.14.1/include/node/v8.h:3039:5: note:   candidate expects 2 arguments, 1 provided
binding.target.mk:129: recipe for target 'Release/obj.target/binding/src/create_string.o' failed
make: *** [Release/obj.target/binding/src/create_string.o] Error 1

# 最後の方に出るmakeのログを見ることで、どのパッケージのビルドに失敗したかが分かる
make: ディレクトリ '/home/user1/repository-name/node_modules/node-sass/build' から出ます

gyp ERR! build error 
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit (/home/user1/repository-name/node_modules/node-gyp/lib/build.js:262:23)
gyp ERR! stack     at ChildProcess.emit (events.js:223:5)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:272:12)
gyp ERR! System Linux 4.15.0-74-generic
gyp ERR! command "/usr/local/bin/node" "/home/user1/repository-name/node_modules/node-gyp/bin/node-gyp.js" "rebuild" "--verbose" "--libsass_ext=" "--libsass_cflags=" "--libsass_ldflags=" "--libsass_library="
gyp ERR! cwd /home/user1/repository-name/node_modules/node-sass
gyp ERR! node -v v12.14.1
gyp ERR! node-gyp -v v3.8.0
gyp ERR! not ok 
Build failed with error code: 1

調べたこと

ログにあるとおり、node-sassのビルドに失敗しています。
とりあえずググったところ、node-sassは4.12.0でnode.jsに12対応したそうです。

更新対象リポジトリのpackage.jsonにはnode-sassの記述がなく、
npm lsで依存パッケージを調べたところ、gulp-sassがnode-sassの4.11に依存していました。

$ npm ls
# 結果を抜粋
├─┬ gulp-sass@4.0.2
│ ├─┬ node-sass@4.11.0  ←ここでエラー(4.12以降にする必要がある)

私は最初、この段階で「詰んだ」と勘違いしました。
gulp-sassの依存パッケージを変えるには、gulp-sass公式にissueなりPRなりを投げてpackage.jsonを書き換えなければならないと思ったからです。

解決策

明示的にnode-sassをインストールしたところ、nodeがよしなにやってくれました。

$ npm install -D node-sass@4.13.0  # 実行時点での最新バージョン
$ npm ls
# 結果を抜粋
├─┬ gulp-sass@4.0.2
│ ├── node-sass@4.13.0 deduped     <- 明示的に4.13を入れたところ、nodeが重複パッケージをまとめてくれた 

上記にdeduped(=重複排除)と表示されていますが、
これはnodeが「バージョン違いの同一パッケージを1つに統合した」ことを表しています。
(今回で言うとnode-sassの4.11, 4.13のうち、より新しい4.13に統合された)

この仕様は、今回のようなケースのほかに、
セキュリティ上の脆弱性を持つ孫パッケージ(こういう呼び方があるかは不明)のバージョンを更新したいときにも役立ちます。
(参考: https://cloudpack.media/41572)

$ npm ls
├─┬ lib-nobody-update@1.1.0 # 更新が止まっているライブラリ
│ ├── lib-something@2.2.0   # 2.3.0で脆弱性が修正されたライブラリ

$ npm install -D lib-something@2.3.0
$ npm ls
├─┬ lib-nobody-update@1.1.0
│ ├── lib-something@2.3.0 deduped
Llib-something@2.3.0

今回初めて知りましたが、なかなかに素敵。




エラー3 (gulpを3系->4系へ移行することで解消)

最後はgulpの話です。

事象

npm ci実行後、npm run buildしたところ以下のエラーが発生。

[18:21:08] Requiring external module @babel/register
fs.js:27
const { Math, Object } = primordials;
                         ^

ReferenceError: primordials is not defined
    at fs.js:27:26
    at req_ (/home/user1/repository-name/node_modules/natives/index.js:143:24)
    at Object.req [as require] (/home/user1/repository-name/node_modules/natives/index.js:55:10)
    at Object.<anonymous> (/home/user1/repository-name/node_modules/vinyl-fs/node_modules/graceful-fs/fs.js:1:37)
    at Module._compile (internal/modules/cjs/loader.js:955:30)
    at Module._compile (/home/user1/repository-name/node_modules/pirates/lib/index.js:99:24)
    at Module._extensions..js (internal/modules/cjs/loader.js:991:10)
    at Object.newLoader [as .js] (/home/user1/repository-name/node_modules/pirates/lib/index.js:104:7)
    at Module.load (internal/modules/cjs/loader.js:811:32)
    at Function.Module._load (internal/modules/cjs/loader.js:723:14)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! my-package-name@0.0.0 build-gulp: `gulp build`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the my-package-name@0.0.0 build-gulp script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/user1/.npm/_logs/2020-01-15T09_21_13_322Z-debug.log
ERROR: "build-gulp" exited with 1.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! my-package-name@0.0.0 build: `run-p build-gulp build-client-ts`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the my-package-name@0.0.0 build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/user1/.npm/_logs/2020-01-15T09_21_13_421Z-debug.log

調べたこと

一見して何のエラーか分かりませんでしたが、とりあえずエラーメッセージでググったところ
gulp3系がnode12に未対応なのが原因だと判明。gulp4系は対応済み。

いっそビルド関連をwebpackに置き換えることも考えましたが、
今回は対応速度を重視してgulpを更新する方針にしました。

解決策

以下を参考にgulpを更新しました。
(破壊的変更が多く、そこそこ面倒でした)


要点をかいつまむと、以下のようになります。

  • gulp.task()は非推奨になった(この点に触れない記事が多い)
    • 後方互換性のため、一応まだ使える
    • 代わりに関数をexportするスタイルになった
  • タスクの直列実行、並列実行は新関数gulp.series(), gulp.parallel()で制御
// 3系: gulp.task(”タスク名”, タスク用の関数)gulp.task("buildFrontend",()=>{/* フロントエンドのビルド処理 */});gulp.task("buildBackend",()=>{/* バックエンドのビルド処理 */});gulp.task("build",["buildFrontend","buildBackend"]);// []は並列実行// 4系: export const タスク名 = タスク用の関数;exportconstbuildFrontend=()=>{/* フロントエンドのビルド処理 */};exportconstbuildBackend=()=>{/* バックエンドのビルド処理 */};exportconstbuild=gulp.parallel(buildFrontend,buildBackend);

3系に比べて可読性があがりましたね。
なお、exportの順番が大切で、自行より下で定義された関数を参照するとエラーになります。(これは微妙)

// ダメな例
export const build2 = gulp.parallel(buildFrontend2, buildBackend2);
export const buildFrontend2 = () => { /* フロントエンドのビルド処理 */ };
export const buildBackend2 = () => { /* バックエンドのビルド処理 */ }; 


// 実行すると以下のエラーが出る
$ npx gulp build
> my-package-name@0.0.0 build /home/duser1/repository-name
> gulp build

/home/duser1/repository-name/gulpfile.js:10
const build = gulp.parallel(buildFrontend2, buildBackend2);
                            ^
ReferenceError: Cannot access 'buildFrontend2' before initialization
    at Object.<anonymous> (/home/duser1/repository-name/gulpfile.js:10:29)
    at Module._compile (internal/modules/cjs/loader.js:955:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:991:10)
    at Module.load (internal/modules/cjs/loader.js:811:32)
    at Function.Module._load (internal/modules/cjs/loader.js:723:14)
    at Module.require (internal/modules/cjs/loader.js:848:19)
    at require (internal/modules/cjs/helpers.js:74:18)
    at execute (/home/duser1/repository-name/node_modules/gulp/node_modules/gulp-cli/lib/versioned/^4.0.0/index.js:36:18)
    at Liftoff.handleArguments (/home/duser1/repository-name/node_modules/gulp/node_modules/gulp-cli/index.js:201:24)
    at Liftoff.execute (/home/duser1/repository-name/node_modules/liftoff/index.js:201:12)
    at module.exports (/home/duser1/repository-name/node_modules/flagged-respawn/index.js:51:3)
    at Liftoff.<anonymous> (/home/duser1/repository-name/node_modules/liftoff/index.js:191:5)
    at /home/duser1/repository-name/node_modules/liftoff/index.js:149:9
    at /home/duser1/repository-name/node_modules/v8flags/index.js:138:14
    at /home/duser1/repository-name/node_modules/v8flags/index.js:41:14
    at /home/duser1/repository-name/node_modules/v8flags/index.js:53:7
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! my-package-name@0.0.0 build: `gulp build`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the my-package-name@0.0.0 build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/duser1/.npm/_logs/2020-01-15T10_04_26_061Z-debug.log




まとめ

  • バージョン更新は思った以上に大変
  • こまめな更新が、バージョン更新のコストを下げる
  • npm lsでパッケージの依存関係をチェックできる
  • nodeにはdedupeという素敵機能がある
  • node12でgulp3系は使えない。4系に移行するか、webpackなど他ツールへ移行する


webpackちゃんと使えるようになりたいです。


Viewing all articles
Browse latest Browse all 8883

Trending Articles