Fetch API を軸とした変更
新バージョンのリリースに併せて、ライブラリ製作者である @kettanaito さんがブログでその背景を語っています。大変な苦労が垣間見えますが、Fetch API を軸とした API の再設計が目玉の様です。
(req, res, ctx) => res(...)
で馴染みの response resolver は利用者にインターフェースの教育が必要だった。- Node.js 18 が FetchAPI をサポートしたことで、Node.js 環境においてもポリフィルに依存する必要がなくなった。
- 満を持して Fetch API に寄り添ったインターフェースに作り替え、MSW 2.0 としてリリースした。
その結果、response resolver のインターフェースが大きく変更されています。
Response resolver call signature is no longer (req, res, ctx) => res() but instead ({ request }) => new Response().
この変更は個人的にかなり嬉しかったです。かくいう私も response resolver をおまじないのように使っていた 1 人であり、Next.js の作り出す流れ (Fetch API の拡張) も相まって、インターフェースが 1 つの方向にまとまってくれるのは助かります。今後、MSW 独自のシグネチャは http.get('/movie', async () => {})
だけになるというのですから驚きですね 😮
新旧のコードを比較してみましょう。
// import { reset } from 'msw';
import { http } from 'msw';
// const handlers = [
// rest.get('/api/movie', (_req, res, ctx) => {
// res(ctx({ name: 'some movie' }));
// });
// ];
const handlers = [
http.get('/api/movie', () => {
return new Response({ name: 'some movie' });
})
];
移行中に生じた問題
すぐに陳腐化すると思いますが、移行ガイド でハマった点を記載します。
環境
$ node --version
v18.15.0
$ npx next --version
Next.js v13.2.4
$ npx jest --version
29.5.0
旧公式ドキュメントが見つからない
v1 系のドキュメントを見つけられなくて結構焦りました (急いで触りだしたのも 90% くらいこれが要因です)。記事を書いている途中で対応されたので、現在は Introduction ページの上部にバーナーが追加されています。
add 1.x docs banner by kettanaito · Pull Request #264 · mswjs/mswjs.iogithub.com
TextEncoder is not defined
適当なテストを実行してみたところ、Reference エラーが発生しました。
どうやら Jest (jsdom) 環境下では、いくつかのポリフィルが必要になるようです。
Why am I getting "TextEncoder is not defined" in Jest?When testing a function that uses either the TextEncoder or the TextDecoder I get:
ReferenceError: TextEncoder is not defined
ReferenceError: TextDecoder is not defined
I am using jsdom, so why is...stackoverflow.com
1.x → 2.xMigration guidelines for version 2.0.mswjs.io
移行ガイドに従って jest.config.js
の設定を変更しました。
@@ -1,3 +1,4 @@
+const { TextDecoder, TextEncoder } = require('node:util');
const nextJest = require('next/jest');
const createJestConfig = nextJest({
@@ -13,6 +14,16 @@ const customJestConfig = {
},
testEnvironment: 'jest-environment-jsdom',
roots: ['<rootDir>/src'],
+ globals: {
+ fetch,
+ Request,
+ Response,
+ Headers,
+ FormData,
+ ReadableStream,
+ TextEncoder,
+ TextDecoder,
+ },
};
module.exports = createJestConfig(customJestConfig);
Cannot find module 'msw/node'
上記のポリフィルを追加したところ、msw/node
を参照できなくなりました。
こちらは GitHub に issue が立っていますが、2023/10/25 時点で解決策を検討中のようです。
おわりに
MSW 2.0 ではインターフェースが大きく変わるため、積極的に使うことで早く手に馴染ませていきたいです!