🙄

Node.jsをv12からv16へアップデートした話

2022/02/09に公開

はじめに

メディアエンジン株式会社の田中です!

最近、フロントエンド開発で利用しているNode.jsをv12からv16へアップデートしたため、それについてお話しさせていただきます。

実施したこと

まず、CircleCIで使用するDockerイメージのNode.jsバージョンをv16へ更新しました。

  default:
    working_directory: ~/<project-name>
    docker:
-       image: circleci/node:12.22.0-stretch
+       image: circleci/node:16.13.1-buster

次に、ローカル開発用のDockerイメージもNode.js v16へ更新しました。

- FROM node:12-buster
+ FROM node:16.13.1-buster

最後に、いくつかの依存ライブラリのアップデートなども実施しました。

作業時間としては全部で1.5日くらいかかりました。

ハマった問題について

node-fibersパッケージが動作しない

Node.jsのアップデート後、nuxt buildを実行したところ下記のようなエラーが発生するようになりました。

node: ../src/coroutine.cc:134: void* find_thread_id_key(void*): Assertion `thread_id_key != 0x7777' failed.
Aborted (core dumped)

調べてみたところ、node-fibersパッケージがNode.js v16と互換性がないことが原因のようでした。

https://github.com/laverdet/node-fibers/commit/8f2809869cc92c28c92880c4a38317ae3dbe654d

しかし、プロジェクトの直接の依存関係としてnode-fibersは追加していません。

いずれかのパッケージから間接的にインストールされているはずと思い、yarn whyを使って調べてみることにしました。

https://classic.yarnpkg.com/en/docs/cli/why

$ yarn why fibers

  ...省略...

=> Found "fibers@4.0.3"
info Reasons this module exists
   - "@nuxtjs#vuetify" depends on it
   - Hoisted from "@nuxtjs#vuetify#fibers"
info Disk size without dependencies: "4.54MB"
info Disk size with unique dependencies: "4.58MB"
info Disk size with transitive dependencies: "4.58MB"
info Number of shared dependencies: 1
✨  Done in 0.68s.

どうやら@nuxtjs/vuetifynode-fibersに依存しているようでした。

調べてみたところ、@nuxtjs/vuetifyはv1.11.3でnode-fibersへの依存を削除しているようです。

https://github.com/nuxt-community/vuetify-module/releases/tag/v1.11.3

そのため、@nuxtjs/vuetifyをv1.11.3以降にアップデートしたところ、この問題は無事に解消しました。

@nuxtjs/vuetifyアップデートしたら大量に警告が出る

先ほど、@nuxtjs/vuetifyをアップデートしたと書きました。

このアップデート後、nuxt buildの実行時に次のような警告が大量に出力されるようになりました。

Deprecation Warning: Using / for division outside of calc() is deprecated and will be removed in Dart Sass 2.0.0.

Recommendation: math.div($grid-gutter, 3) or calc($grid-gutter / 3)

More info and automated migrator: https://sass-lang.com/d/slash-div64 │     'md': $grid-gutter / 3,
   │           ^^^^^^^^^^^^^^^^
   ╵
    node_modules/vuetify/src/styles/settings/_variables.scss 64:11                @import
    node_modules/vuetify/src/styles/settings/_index.sass 1:9                      @import
    node_modules/vuetify/src/styles/styles.sass 2:9                               @import
    node_modules/vuetify/src/components/VProgressLinear/_variables.scss 1:9       @import
    node_modules/vuetify/src/components/VProgressLinear/VProgressLinear.sass 3:9  root stylesheet

調べてみたところ、sassパッケージが原因のようです。

この問題についてはvuetifyの公式リポジトリでissueが立っています。

https://github.com/vuetifyjs/vuetify/issues/13694

この問題はVuetify 3では解決されているものの、Vuetify 2ではsassパッケージのバージョンを~1.32にする必要があるようです。

ひとまず、一時しのぎとしてpackage.jsonresolutionsフィールドを使って解決することにしました。

  "resolutions": {
    "sass": "~1.32"
  },

https://classic.yarnpkg.com/lang/en/docs/selective-version-resolutions/

gypが動かない問題

他にも、ローカル環境ではnuxt buildでビルドが通るが、CircleCI上だとgypでエラーが発生するという問題にも遭遇しました。

元々、CircleCIでは下記イメージを利用していました。

circleci/node:12.22.0-stretch

最初は、これを下記のバージョンにアップデートしようとしました。

circleci/node:16.13.1-stretch

これでビルドしてみたところ、gypでエラーが発生するようになりました。

調べてみると、node:*-stretchイメージで使用されているPythonのバージョンがgypと互換性がないことが原因のようでした。

https://github.com/nodejs/docker-node/issues/1528

以下のように、node:*-busterイメージを使用するように変更したところ、ちゃんとgypが動くようになりました。

circleci/node:16.13.1-buster

学んだこと

依存パッケージの管理について

今回、Node.jsのアップデートそのものでは特に大きな問題は発生せず、問題の大半は依存ライブラリ周りのものでした。

そのため、Dependabotなどを導入して、日頃からライブラリをアップデートしやすい仕組みを整えておくと、Node.jsアップデート時の影響も減らせてよさそうに感じました。

テストをちゃんと書いておくと安心

今回、思い切ってNode.jsをv12からv16へアップデートしてみましたが、あらかじめe2eテストなどを用意しておいたおかげで、事前にいくつかの影響に気づくことができました。

フロントエンド開発であっても、可能であればe2eテストや統合テストなどのテストコードをしっかり用意しておくと、こういったアップデートなどを実施するときに安全性が上がってよさそうです。

おわりに

今回、色々と問題には遭遇したもののなんとか無事にNode.jsのアップデートできてよかったです。

もしNode.jsのアップデートなどを検討されている場合は、少しでも参考になりましたら幸いです。

最後に、弊社ではエンジニアやデザイナーなどの職種で積極的に採用中です!

弊社チームの紹介ページがあるのでぜひ、見に来てください!

https://mediaengine.notion.site/ba128c5708fc480198f5d8c9440a7062

Discussion