😣

SWCの--out-dir(-d)オプションがうまく動作しない件

2022/10/14に公開

Webpackでの開発がしんどくなってきた事もあり、SWCに移行しようと試行錯誤していた、その時。
表題通りの問題にぶつかりました。

問題点の詳細

npx swc ./src/ts/*.ts -d ./dist/assets/js -s --config-file .swcrc

上記のコマンドを実行すると、src/ts/の.tsファイルがコンパイルされて、dist/assets/js/に出力されるものと考えていました。
しかしながら、実際にコマンドを実行してみると dist/assets/js/ではなく、dist/assets/js/ts/ にjsファイルが出力されました。
-dオプションで出力先を指定しているにも関わらず、意図しないディレクトリにjsファイルが格納されてしまう…という問題です。

どうも私の他にも発生しているようで、SWC-Projectのissueにも登録されています。
> Pathing under --out-dir has extra segments | swc-project

問題が発生したプロジェクトのリポジトリ(※後述の方法で解消済)

> pub_web_swc-dir-test

SWCバージョン

  • @swc/core: 1.3.7
  • @swc/cli: 0.1.57

ディレクトリ構成

./
├── .prettierrc
├── .gitignore
├── .swcrc … SWC設定ファイル
├── README.md
├── jest.config.js
├── package.json
├── dist
│   └── assets
│       └── js … -dオプションで指定した出力先。本当はここにjsを出力したい。
│           └── ts … …が、ここにjsが出力されてしまう。
├── src
│   └── ts … SWC対象ファイルの格納先
├── tsconfig.json
└── yarn.lock

(一応の)解決策

つよつよRustエンジニアなら、SWCのソースを読みこんだり、プラグインで解決したりできるんでしょうけども、、
残念ながら、よわよわエンジニアのため、issueにもあるようにコマンドで解決してみる事にしました。

ライブラリ

解決策を講じるために利用したライブラリが下記の通りです。
もともと自分が使っているフロントエンドテンプレートに入っているのをそのまま利用しただけですので、インストール必須ではありません。
普通にcprmコマンドで問題ないと思います。

  • cpx … ディレクトリ・ファイルのコピーのため
  • rimraf … ディレクトリ・ファイルの削除のため
  • watch  … tsファイルに変更を加えた時に、SWCを始め各コマンドを実行するため

コマンド

"scripts": {
  "swc": "yarn type && npx swc ./src/ts/*.ts -d ./dist/assets/js -s --config-file .swcrc && yarn copy:js && yarn clean:ts",
  "swc:w": "npx watch 'yarn swc' ./src/ts/",
  "type": "tsc --noEmit",
  "copy:js": "cpx ./dist/assets/js/ts/**/* ./dist/assets/js/",
  "clean": "rimraf dist",
  "clean:ts": "rimraf ./dist/assets/js/ts",
}

コマンドの内容

解説するほどの事もなく、ただ単純に各種コマンドをつなげて力技で解決しているだけですね。
はい。

swcコマンドは…

  1. TypeScriptの型チェック(一応。VSCode使っているなら不要だと思います。)
  2. swc実行
  3. dist/assets/js/ts/配下のjsファイルを一つ上の階層へコピー
  4. dist/assets/js/tsディレクトリを削除

…ってのを&&でつなげているだけです。

swc:wコマンドはwatchを利用して、src/ts/配下のtsファイルを監視して変更があれば、swcコマンドを実行しているだけですね。


いろいろと腑に落ちない点はありますが、意図した通りに動作させることはできたので、今回はヨシ!とします。
Rustの知識が身についたら、またこの問題を調査してみようかなと思います。

関連するリンク集

Discussion