ts-node で TypeScript をバッチスクリプト的に実行したいけどエラーになる話

(2021-04-05追記)
こちらの記事に書かれているエラーはこの日記で解決しています。ネットの検索でたどり着いてしまった稀有な人向けまでに。

(追記ここまで)

---

バッチスクリプトを API で作ろうとしたが、そもそも DB 立ち上げ時に初期データを作成したい希望があったので、今まで作っていたものとは別にバッチスクリプトを書いた。


API での動作確認はできているのでコードは問題ないはずだが、バッチ的に `ts-node bin/initStocks.ts` などと打って実行すると、色々エラーになって結局解決できなかった


エラー1

> ts-node ./bin/initStocks.ts

(node:668) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
/app/bin/initStocks.ts:1
import { AlphaVantage } from "../lib/api/alpha-vantage";
^^^^^^

SyntaxError: Cannot use import statement outside a module
   at wrapSafe (internal/modules/cjs/loader.js:979:16)
   at Module._compile (internal/modules/cjs/loader.js:1027:27)
   at Module.m._compile (/app/node_modules/ts-node/src/index.ts:1056:23)
   at Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
   at Object.require.extensions.<computed> [as .ts] (/app/node_modules/ts-node/src/index.ts:1059:12)
   at Module.load (internal/modules/cjs/loader.js:928:32)
   at Function.Module._load (internal/modules/cjs/loader.js:769:14)
   at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
   at main (/app/node_modules/ts-node/src/bin.ts:198:14)
   at Object.<anonymous> (/app/node_modules/ts-node/src/bin.ts:288:3)
ERROR: 1
make: *** [db_init] Error 1

エラー2

> ts-node ./bin/initStocks.ts

TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for /app/bin/initStocks.ts
   at Loader.defaultGetFormat [as _getFormat] (internal/modules/esm/get_format.js:71:15)
   at Loader.getFormat (internal/modules/esm/loader.js:102:42)
   at Loader.getModuleJob (internal/modules/esm/loader.js:231:31)
   at Loader.import (internal/modules/esm/loader.js:165:17)
   at Object.loadESM (internal/process/esm_loader.js:68:5)
ERROR: 1
make: *** [db_init] Error 1

エラー3

> node --loader ts-node/esm ./bin/initStocks.ts

(node:717) ExperimentalWarning: --experimental-loader is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)

/app/node_modules/ts-node/dist-raw/node-esm-resolve-implementation.js:374
   throw new ERR_MODULE_NOT_FOUND(
         ^
Error: ERR_MODULE_NOT_FOUND /app/lib/api/alpha-vantage /app/bin/initStocks.ts module
   at finalizeResolution (/app/node_modules/ts-node/dist-raw/node-esm-resolve-implementation.js:374:11)
   at moduleResolve (/app/node_modules/ts-node/dist-raw/node-esm-resolve-implementation.js:809:10)
   at Object.defaultResolve (/app/node_modules/ts-node/dist-raw/node-esm-resolve-implementation.js:920:11)
   at /app/node_modules/ts-node/src/esm.ts:55:38
   at Generator.next (<anonymous>)
   at /app/node_modules/ts-node/dist/esm.js:8:71
   at new Promise (<anonymous>)
   at __awaiter (/app/node_modules/ts-node/dist/esm.js:4:12)
   at resolve (/app/node_modules/ts-node/dist/esm.js:31:16)
   at Loader.resolve (internal/modules/esm/loader.js:86:40)
ERROR: 1
make: *** [db_init] Error 1


一度バッチの処理を console.log('test') だけにして実行してみたりしてもエラーは同様だったので、これはもうコードが云々とかいう話ではないところまでは原因の切り分けが済んでいる。


そこで色々調べていると、以下の Issue にたどり着いた。

このトップコメントで詳しく解説してあったが、何にしろ commonjs に ESModule はインポートできないのにどうやってもインポートさせてしまうのでエラーになってしまう既知の問題らしい。

まだ全部のコメントは読み切れていないが、Issue 自体は閉じられていて「機能実装済み」と書いてあるので解決策が確定しているのかも知れない

I'm closing this issue because the feature has been implemented, and feedback is tracked by #1007 .


またここでその後の意見を聴取しているらしいので、併せて見ないといけない


最近英語のドキュメントなどを読むことに抵抗感が少なくなってきたのを感じるが、やっぱり読みづらいし日本語でおkとは強く強く心の底から思う。全人類日本語使えばいいのに。もしくは英語が来い。早く来い。



今回はここまで。

いいなと思ったら応援しよう!