-
Notifications
You must be signed in to change notification settings - Fork 3
Description
背景
現在は.mjs拡張子を使用することで、コードをESMとしてNode.jsに解釈させるようにしています。cf.
utcode-learn/docs/3-web-servers/04-module/index.mdx
Lines 24 to 35 in 27d5138
| Node.jsでは、ファイルの拡張子が`.mjs`の場合、`export`文や`import`文を用いて他の<Term>モジュール</Term>とのやりとりを行います。 | |
| ```javascript title="sub.mjs" | |
| export default function add(a, b) { | |
| return a + b; | |
| } | |
| ``` | |
| ```javascript title="main.mjs" | |
| import add from "./sub.mjs"; | |
| console.log(add(3, 4)); | |
| ``` |
しかし、現在ではpackage.jsonに"type": "module"と書くことでコードをESMとして解釈させることが多く、.mjs拡張子を使用することによる問題が顕在化してきたため、package.jsonに"type": "module"とする方法に変更することを考えています。
コードをESMとしてNode.jsに解釈させる方法について
2026年2月現在Node.jsは以下のようにして、ESMとして解釈するかCJSとして解釈するかを決定しています。cf. https://nodejs.org/api/esm.html#enabling https://nodejs.org/api/packages.html#determining-module-system
Authors can tell Node.js to interpret JavaScript as an ES module via the .mjs file extension, the package.json "type" field with a value "module", or the --input-type flag with a value of "module". These are explicit markers of code being intended to run as an ES module.
次の3つの方法でコードをESMとして解釈するように伝えることができる。
.mjs拡張子を使うpackage.jsonに"type": "module"と記載する--input-typeフラグを使用する
When code lacks explicit markers for either module system, Node.js will inspect the source code of a module to look for ES module syntax. If such syntax is found, Node.js will run the code as an ES module; otherwise it will run the module as CommonJS. See Determining module system for more details.
明示していない場合はESMのみの構文があれば、ESMとして解釈する。
それぞれの方法の良し悪し
.mjs拡張子を使う- シンプルなためわかりやすく明示することを忘れにくい 👍
package.jsonがない場合でも明示可能 👍- ブラウザで動くJSの拡張子は
.jsでありそれと拡張子が異なるため混乱を招く 👎 - あまり一般的ではない 👎
例えば、Prismaが自動生成するファイルの拡張子は.mtsではなく.tsになっており、後から自分で変更する必要が出てくる。
package.jsonに"type": "module"と記載する- 一般的 👍
package.jsonがない場合には使えない 👎- 明示することを忘れやすい 👎
--input-typeフラグを使用するpackage.jsonがない場合でも明示可能 👍- 毎回指定することはあまり現実的ではない 👎
- あまり一般的ではない 👎
方針
package.jsonに"type": "module"と記載する方法を採用します。これは、一般的に採用されている方法であり、問題が起きにくいからです。また、前述したようにNode.js 22.7.0以降では明示していなくてもESM構文があればESMとして解釈されるためpackage.jsonがない場合などにESMとして解釈されるように明示していなくてもそれほど問題がなくなったことも大きな理由となります。さらに、npm 11からnpm initをする際にtypeの値が聞かれるようになったため、そこで指定するだけでよくなったことも理由の1つです。