SWC, swc-nodeとは
SWCはRustで実装された高速なTypeScript/JavaScriptのトランスパイラで、BabelのようにTypeScript/JavaScriptのファイルを入力して、そこから様々な環境で動くJavaScriptファイルを生成することができます。
設定を行うことで、以下のようにtsconfig.jsonのpaths
の設定を利用したインポートを、相対パスでのimport
/require
に書き換えてくれる機能が標準で備わっている点を特に個人的に便利だと感じています。1
import { hogera } from "@/moge/hogera";
↓ トランスパイルされたJSファイル
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
const _hogera = require("../../moge/hogera");
swc-nodeは、SWCをベースにしたts-nodeの代替で、ts-node同様以下のようにTypeScriptファイルを直接実行できるようにするものです。2
node -r @swc-node/register script.ts
ts-nodeには、TypeScript 5.0から追加されたtsconfig.jsonでの配列型のextends
を使用するとエラーが出る点や、paths
を利用したインポートを認識させるためにtsconfig-paths/register
を別途要する点など、不便に感じる点がいくつかありました。
自分はビルドにSWCを使っているので、統一できる嬉しさなどから、最近は個人のプロジェクトではswc-nodeを使うようにしています。
また、swc-nodeのREADMEにはベンチマークとともに“Fastest TypeScript
transformer.”と書いてあるように、トランスパイルが高速(≒ 実行までが早い)なこともswc-nodeの利点といえるでしょう。
AVAでswc-nodeを使う
さて、この記事では詳しい説明はしないことにしますが、AVAはTypeScript/JavaScriptのためのテスティングフレームワークのひとつです。
AVAを使用する際に、JavaScriptではなくTypeScriptでテストを書くようにする方法はいくつかありますが、swc-nodeを使う方法もあるのでそれをここで紹介します。
AVAにはpackage.jsonから設定を読み込む機能があるので、package.jsonに以下を追加することで、設定が完了します。
{
"ava": {
"files": ["tests/**/*.ts"],
"extensions": ["ts"],
"nodeArguments": ["-r", "@swc-node/register"],
"environmentVariables": {
"SWCRC": "true"
}
}
}
それでは上記の設定の内容を順に説明します。
まず、files
とextensions
でテストファイルの場所と拡張子を指定して、AVAがTypeScriptのテストを見つけられるようにしています。files
の値は、各々のディレクトリ構成のテストファイルの配置に合わせて変更してください。3
"files": ["tests/**/*.ts"],
"extensions": ["ts"],
nodeArguments
には、AVAがテストファイルを実行するためにnode
コマンドを呼び出す際に渡すオプションを指定できます。-r @swc-node/register
が渡されるようにすることで、node
がTypeScriptを実行できるようにしています。
"nodeArguments": ["-r", "@swc-node/register"],
environmentVariables
に環境変数の名前と値(文字列)を設定すると、AVAを実行した際にその環境変数が自動で設定されます。swc-nodeはデフォルトでは、SWCの設定ファイル.swcrcを読み込まないようになっていて、SWCRC=true
を設定することで.swcrcを読み込むようになります。この設定がなくてもテストを実行することはできますが、設定ファイルを読み込ませてビルド時とSWCの設定を統一した方がよさそうなので、このようにしています。
"environmentVariables": {
"SWCRC": "true"
}
これでTypeScriptで書かれたテストが実行できるようになりました。
package.jsonで以下のようなスクリプトを定義して、npm test
などのコマンドを実行すれば各テストケースが実行されます。
{
"scripts": {
"test": "ava",
}
}
参考
-
paths
を利用したインポートはJavaScriptを実行するツールや環境によって認識されたりされなかったりするのでありがたいです。 ↩ -
同じようなts-nodeの代替に、tsxというツールもあります。swc-nodeは内部でSWCをトランスパイルに使っていて、tsxは内部でesbuildをトランスパイルに使っています。(参考: まだts-node使ってるの?tsxの紹介 - Qiita) ↩
-
この例では、プロジェクトのルートの
tests/
ディレクトリの下に配置したファイルがテストファイルとして認識されます。 ↩