はじめに
はじめまして、ラクスル事業部 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のgithub上のCHANGELOG.mdから[BREAKING]タグが付いているものを洗い出す
- Jestのアップグレードガイドから「breaking」の文字を探す
- Jestの公式ブログからbreaking changeを洗い出す
調査してわかったこと
調査してざっくり下記のことがわかりました。
jest-environment-jsdom
パッケージを個別にインストールする必要があるts-jest
のversionもv28
に上げる必要があるbabel-jest
でのversionもv28
に上げる必要があるTypeScript
のバージョンを4.3
以上にする必要がある
実際に手を動かしてみた
調査する限り大規模な変更はなさそうということで、実際にバージョンアップ作業を行いました。
対応したことを順番に記述していきます。
- Jestの
v28.1.3
をインストール
npm install --save-dev jest@28.1.3
jest-environment-jsdom
パッケージを個別にインストール
アップグレードガイドより、v28
にバージョンアップする際はjest-environment-jsdom
を個別にインストールする必要があるようです
npm install --save-dev jest-environment-jsdom
- Jestの設定ファイルに
testEnvironment
を追記
"testEnvironment": "jsdom”
- テストを実行すると
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
- テストを実行すると
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
- テストを実行すると下記エラーが発生。
Cannot read property 'createNodeArray' of undefined
こちらのissueによるとTypescript
を上げる必要があるとのことでした。
Typescript
を3.8.3
から4.3.4
へバージョンアップ
npm install typescript@4.3.4
4.3.4
のバージョンアップに伴い以下の修正を行いました。
- importしているファイルの拡張子
.d.ts
を削除 Typescript
のバージョンアップの影響で下記エラーが発生していたので、こちらのissueを参考にtypescript-eslint
を5.40.0
へバージョンアップしてエラーを解消error Parsing error: Cannot read property 'map' of undefined
typescript-eslint
の他にEslint
、ts-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
- eslint:
テストを実行するとエラーは解消されましたが、下記のように警告が出ていました。
Option "testURL" was replaced by passing the URL via "testEnvironmentOptions.url".
警告の文言通りにJestの設定ファイル内にあるtestURL
をtestEnvironmentOptions
に変更
"testURL": "http://localhost/"
↓
"testEnvironmentOptions": { "url": "http://localhost/" }
- ローカルのエラーと警告は解消されましたが、次はCircleCIのテストでタイムアウトしてしまいました。
Too long with no output (exceeded 10m0s): context deadline exceeded
CircleCiの公式ドキュメントを見てみると下記の記述がありました。
Jest テストの実行時には、
--runInBand
フラグを使用してください。 このフラグがない場合、Jest はジョブを実行している仮想マシン全体に CPU リソースを割り当てようとします。--runInBand
を使用すると、Jest は仮想マシン内の仮想化されたビルド環境のみを使用するようになります。
runInBand
のオプションを追加して無事CircleCiのタイムアウトエラーも解消されました
"test:ci": "jest --runInBand"
感想
npmパッケージのバージョンアップってついつい後回しにしてしまいがちですよね。
ラクスルに参画するまでは受託開発の現場が多く、腰を据えてバージョンアップ作業に取り組むのはほとんど初めての経験でした。
バージョンアップ作業はトライ&エラーの繰り返しという地道な作業ではありますが、個人的にはパズルを解いているようで苦労しながらも楽しんで作業ができたように感じます。新しい自分こんにちは。
また、npm audit
してみると脆弱性のあるパッケージがちらほらあったのでそれも気持ちが熱いうちに対応していきたいと思います。
最後に
自分が楽しみつつ作業ができたのは、ひとえに記事を上げてくださった先人たちの苦労があってこそであります。
この記事もどこかでバージョンアップに苦戦しているエンジニアの一助になれば幸いです。
ラクスルではエンジニアを募集しています!どしどしご応募お待ちしております。