swc/jestでESM, CJS混在のコードをJestを使ってテストする有力な方法は今のところ多分ない
更新日:
投稿日:
投稿日:
ESM化が叫ばれて久しいですが、未だにJestはESMとCJSが混在したコードを処理してくれません。
Getting StartedにもSWCに対する言及がないので、きっともう忘れられているのでしょう。swc-project/jestの方も特にやる気はなさそうだし、やりたければ自分でPR書きましょうって感じだと思います。きっと。
確認環境
node_modules配下にESMで作られたモジュールが存在し、コードはTypeScript、トランスパイルにはSWCを利用する。
| Env | Ver |
|---|---|
| @swc/cli | 0.1.62 |
| @swc/core | 1.3.92 |
| @swc/jest | 0.2.29 |
| @swc/register | 0.1.10 |
| jest | 29.7.0 |
| typescript | 5.2.2 |
やったけど意味がなかったこと
package.jsonのtypeをmoduleにするjest.config.jsのtransformIgnorePatternsにESMモジュールのパスだけ除外する設定を書く- 上記に加えて
transform.jsc.pathにpkg-name: ['node_modules/pkg-name']を追記する node --experimental-vm-modules node_modules/jest/bin/jest.jsで実行する- 多少マシになったがコケるものはコケる
- ESMで書かれたモジュールを丸ごとモックする
- 一切効果なし
所感
多分Webpackでバンドルしてnode_modulesの中身も外も関係ない状態にするのが一番無難なのではないかと思いました。
Node.jsの組み込みテストランナーにすれば解決するかな?と思ったものの、こちらは現状SWCでは使えそうにないので諦めました。
参考までに以下のコマンドで走らさせられます。
node --require @swc/register --test ./src/**/*.spec.ts
取り敢えずESMに引っかったモジュールはCJS時のバージョンを維持しておくことにしましたが、このままだとSWC使えないし、なんとかなって欲しいですね。Webpack使えば解決できるのはわかるんですが、このために使いたくないので、テストを重視する場合、Vitestを持つViteが有力候補になって来そうです。
2024-02-17追記
esbuild + Node.js built-in test runnerの組み合わせであればテストはできるが肝心の実行ができず無意味だった