ESMに依存するモジュール(CJS/ESM)をts-mochaに入力すると、何故かエラーが出てくる現象について色々実験した
結論
code:neat-csv-tester.ts
import neatCsv from "neat-csv"
neatCsv('Header1,Header2\ncell1, cell2\ncell3,cell4')
.then(data => console.log(data))
.catch(e => console.error(e))
この記事の目的
CJSあるいはESMと扱った上で、ts-mochaに渡すとどうなるかを実験する。 追記:
現在のファイルは CommonJS モジュールであり、このインポートでは 'require' 呼び出しが生成されますが、参照ファイルは ECMAScript モジュールであるため、'require' ではインポートできません。代わりに動的な 'import("neat-csv")' 呼び出しを記述することを検討してください。 (エラーメッセージ)
moduleオプションを使えばコンパイル後のコードもimportにできそうなもんだけど、CJSだからそれは無効になるのか...? わからん。
それをそのまま実行するとTypeError: Unknown file extension ".cts" for /src/neat-csv-tester.ctsが出てくる。
このエラーが出てくるのもなんか変なような...。
TypeError: Unknown file extension ".mts" for /Users/AppleBird/Downloads/timetable/src/neat-csv-tester.mtsが出力される。
CJSからESMの読み込みはともかく、こちらのESMからESMの読み込みはimportによる呼び出しコードが生成されるはず。 だから、モジュールの読み込みの制約に引っかかることはないはず....。
#疑問 どうして同じ問題が出てきているのかが理解できない。 単体でコンパイルした後のコードがCJS方式になってる? でもこれって関係あるのかな...?
まあ一応確かめてみる
code:neat-csv-tester.mjs
"use strict";
exports.__esModule = true;
var neat_csv_1 = require("neat-csv");
(0, neat_csv_1"default")('Header1,Header2\ncell1, cell2\ncell3,cell4') .then(function (data) { return console.log(data); })"catch"(function (e) { return console.error(e); }); でも、全体でコンパイルするとそうでもなく、ESM方式になっている。 code:build/neat-csv-tester.mjs
import neatCsv from "neat-csv";
neatCsv('Header1,Header2\ncell1, cell2\ncell3,cell4')
.then(data => console.log(data))
.catch(e => console.error(e));
//# sourceMappingURL=neat-csv-tester.mjs.map
...もしかしてこれ、単体でコンパイルするとプロジェクトtsconfig.jsonの設定が無効になる?
そうらしい。
When input files are specified on the command line, tsconfig.json files are ignored.
今なお議論が続いてるみたいだ....。
動的なimportへ書き換えたらいずれも正しく実行される。
code:neat-csv-tester.ts
// 実際にはctsファイル
import("neat-csv").then(neatCsv => {
neatCsv.default('Header1,Header2\ncell1, cell2\ncell3,cell4')
.then(data => console.log(data))
.catch(e => console.error(e))
})