tsなのに、.jsという拡張子でimportする必要がある
tsconfigのmoduleでmodule: node16を指定すると、tsなのに.jsでimportする必要がある
拡張子は.js, .mjs, .cjs, .jsx等がある
とにかく.ts, .tjs, .tjs, .tsxではないよということ
参考
TypeScript 4.5 以降で ESM 対応はどうなるのか?
4.5のときの書かれた内容
4.7以降の理解がないと一部誤読するかもしれない
Concerns with TypeScript 4.5's Node 12+ ESM Support · Issue #46452 · microsoft/TypeScript · GitHub
#WIP
前提
TypeSciprtでNative ESMをする場合の話
流れ
tsconfigのmoduleでnode16を指定すると、moduleの扱いがNode.jsに合わせられる
この時点で、tsなのに、.jsという拡張子でimportする必要があるになっている
moduleの扱いがNode.jsに合わせられるということは、
「Node.jsでのmoduleの扱い方法」を別途指定する必要があるということ
それはpackage.jsonのtypeで指定できる
type: moduleを指定したならば、.jsでimportする
type: commonjsを指定したならば、一部ESMを使うときは.mjsでimportする
根本の理由は誰の仕様?
Node.jsの仕様ぽい
Node.jsでES Modulesを使うと拡張子を省略できなくなる
.js, .mjs等を指定する
その仕様の理由はなんだっけ #??
module systemが混在するとか?でもesmって言ってるんだから混在はしてないか
Native ESM + TypeScript 拡張子問題: 歯にものが挟まったようなスッキリしない書き流し
require は省略された拡張子 (.js, .cjs) を補完して読み込むことができます。ref
import は省略された拡張子を補完しません。基本的に拡張子を明示する必要があります。 (index.js や main field, pkg exports などの話は本稿では扱いません)
更に、TypeScriptでどういう扱いになるかと言うと、
TypeScriptのcompile時にmodule specifierは書き換えられることはない
なので、JSのときと同様に、.js, .mjsを指定することになる
VSCode
typescript.preferences.importModuleSpecifierEnding
"typescript.preferences.importModuleSpecifierEnding": "js"
https://blog.s2n.tech/articles/dont-use-moduleresolution-node#node16--nodenext
注意点として Node.js の ES Modules では拡張子の補完やディレクトリパスを指定した際のindex.jsの補完が行われないため、 ES Modules を使用する場合はTypeScript でも import 先を.jsの拡張子を含めたパスで指定する必要があります。
.jsをつけて回る