RAKSUL TechBlog

ラクスルグループのエンジニアが技術トピックを発信するブログです

Jestをv28にバージョンアップした話

はじめに

はじめまして、ラクスル事業部 PBU(Printing Business Unit)開発チームでフロントエンドエンジニアをしている沖です。

ラクスルに参画して半年たちましたが、まだまだフレッシュな気持ちでいます。

さてRAKSUL Advent Calendar 2022の12月5日の記事では、

今年の8月に対応した「Jestをv28にバージョンアップした作業」について話していきたいと思います。

経緯

PBUで扱っているrepositoryではフロントエンドの単体テストとしてJestを使用しておりますが、開発環境のメンテナンスの一環として24.8.0から28へバージョンアップ対応を行いました。

アップデートする前の開発環境

  • Node.js: v14.19.2
  • Jest: 24.8.0
  • Typescript: 3.8.3

どのように対応したか

まずJestのv25からv28までにある破壊的変更について調査することからはじめました。

調査方法

調査してわかったこと

調査してざっくり下記のことがわかりました。

  • jest-environment-jsdomパッケージを個別にインストールする必要がある
  • ts-jestのversionもv28に上げる必要がある
  • babel-jestでのversionもv28に上げる必要がある
  • TypeScriptのバージョンを4.3以上にする必要がある

実際に手を動かしてみた

調査する限り大規模な変更はなさそうということで、実際にバージョンアップ作業を行いました。

対応したことを順番に記述していきます。

  1. Jestのv28.1.3をインストール
npm install --save-dev jest@28.1.3
  1. jest-environment-jsdomパッケージを個別にインストール

アップグレードガイドより、v28にバージョンアップする際はjest-environment-jsdomを個別にインストールする必要があるようです

npm install --save-dev jest-environment-jsdom
  1. Jestの設定ファイルにtestEnvironmentを追記
"testEnvironment": "jsdom
  1. テストを実行するとts-jestのエラーが発生したので、Jestのバージョンにあわせてts-jestをアップデート
Error: ● Invalid transformer module:
  "~/node_modules/ts-jest/dist/index.js" specified in the "transform" object of Jest configuration
  must export a `process` or `processAsync` or `createTransformer` function.
  Code Transformation Documentation:
  https://jestjs.io/docs/code-transformation
npm install --save-dev ts-jest@28.0.2
  1. テストを実行するとbabel-jestのエラーが発生したので、Jestのバージョンにあわせてbabel-Jestをアップデート
TypeError: Cannot destructure property 'config' of 'undefined' as it is undefined.

      at Object.getCacheKey (node_modules/babel-jest/build/index.js:151:8)
npm install --save-dev babel-jest@28.1.3
  1. テストを実行すると下記エラーが発生。
Cannot read property 'createNodeArray' of undefined

こちらのissueによるとTypescriptを上げる必要があるとのことでした。

  1. Typescript3.8.3から4.3.4へバージョンアップ
npm install typescript@4.3.4

4.3.4のバージョンアップに伴い以下の修正を行いました。

  • importしているファイルの拡張子.d.tsを削除
  • Typescriptのバージョンアップの影響で下記エラーが発生していたので、こちらのissueを参考にtypescript-eslint5.40.0へバージョンアップしてエラーを解消

      error Parsing error: Cannot read property 'map' of undefined
    
  • typescript-eslintの他にEslintts-loaderなど関連するパッケージをバージョンアップ

  • Eslint系パッケージのバージョンアップの影響によりeslint-loaderで下記エラーが発生していたので、子コンポーネントでprops のプロパティを直接を書き換えていた箇所を親コンポーネントで書き換えるように修正

      error  Unexpected mutation of "hoge" prop
    

    ※補足) Eslint系のパッケージは下記のバージョンにアップデートしました

    • eslint: 7.22.0
    • eslint-loader: 4.0.2
    • eslint-plugin-prettier: 3.3.1
    • eslint-plugin-vue: 7.7.0
  • テストを実行するとエラーは解消されましたが、下記のように警告が出ていました。

Option "testURL" was replaced by passing the URL via "testEnvironmentOptions.url".

警告の文言通りにJestの設定ファイル内にあるtestURLtestEnvironmentOptionsに変更

"testURL": "http://localhost/"

"testEnvironmentOptions": {
    "url": "http://localhost/"
}
  1. ローカルのエラーと警告は解消されましたが、次はCircleCIのテストでタイムアウトしてしまいました。
Too long with no output (exceeded 10m0s): context deadline exceeded

CircleCiの公式ドキュメントを見てみると下記の記述がありました。

Jest テストの実行時には、--runInBand  フラグを使用してください。 このフラグがない場合、Jest はジョブを実行している仮想マシン全体に CPU リソースを割り当てようとします。 --runInBand  を使用すると、Jest は仮想マシン内の仮想化されたビルド環境のみを使用するようになります。

  1. runInBandのオプションを追加して無事CircleCiのタイムアウトエラーも解消されました
"test:ci": "jest --runInBand"

感想

npmパッケージのバージョンアップってついつい後回しにしてしまいがちですよね。

ラクスルに参画するまでは受託開発の現場が多く、腰を据えてバージョンアップ作業に取り組むのはほとんど初めての経験でした。

バージョンアップ作業はトライ&エラーの繰り返しという地道な作業ではありますが、個人的にはパズルを解いているようで苦労しながらも楽しんで作業ができたように感じます。新しい自分こんにちは。

また、npm auditしてみると脆弱性のあるパッケージがちらほらあったのでそれも気持ちが熱いうちに対応していきたいと思います。

最後に

自分が楽しみつつ作業ができたのは、ひとえに記事を上げてくださった先人たちの苦労があってこそであります。

この記事もどこかでバージョンアップに苦戦しているエンジニアの一助になれば幸いです。

ラクスルではエンジニアを募集しています!どしどしご応募お待ちしております。