🌟

Node.jsにおけるモジュールシステム

1 min read

Node.jsにおけるモジュールシステム

モジュールシステムとは外部ファイル(モジュール)を読み込むときの仕様である。
Node.jsで使えるモジュールシステムとして、CJSとESMがある、現在はCJSがデフォルトになっている。

拡張子が.cjsのものはCJS。
拡張子が.mjsのものはECM。

拡張子が.jsのファイルは、package.jsontypeフィールドの値によって判断される。
具体的にはtypemoduleであれば.jsファイルがECMとして扱われる。commonjsにするとCJSとして扱われる。記述しない場合もCJSとして扱われる。

TypeScript

tsconfig.jsonmoduleフィールドの値によってどのようなモジュールシステムのJavaScriptが生成されるのかを決めることができる。

  • 未指定、commonjsの時はCJS
  • es6, es2015, esnextの時はECM

挙動

CJS(CommonJS)

ファイルのインポート、エスクポート。

// ./src/utils/hello.cjs
module.exports = {
  msg: "hello",
}
// ./src/index.cjs
const Hello = require('./utils/hello.cjs');

console.log(Hello); // { msg: "hello" }

ESM(ES Modules)

// ./src/utils/hello.mjs
export default "hello";
export const x = 1;
// ./src/index.mjs
import Hello, {x} from './utils/hello.mjs';

console.log(Hello); // "hello"
console.log(x); // 1

$ node --es-module-specifier-resolution=node src/index.mjsで実行してあげるとファイル拡張子が省略できる。
また、指定したディレクトリのindex.jsを読みにいくこともできる。

CJSからECM

  • ECMをCJS内でrequireでは読み込めない。
Error [ERR_REQUIRE_ESM]
  • CJS内でimportは使えない。
SyntaxError: Cannot use import statement outside a module
import('./utils/Hello.mjs').then(res => {
  console.log(res); // [Module] { default: "hello", x: 1 }
});

ECMからCJS

  • デフォルトインポートはできる。
    • CJSから読み込むものはdefaultでラップされるため。
  • 名前付きインポートはシンタックスエラーになる。
  • 標準モジュールは名前付きインポートができる。

Discussion

ログインするとコメントできます