CJSとESMの挙動早見表

2023 / 12 / 30

Edit

以下の条件での比較となります。

  • cjsの場合は、デフォルトは厳格モードではないため厳格モードを利用しません

モジュール

使えるモジュールのシンタックスです。

CodeCJSESM
require('x')okerror
import('x')okok
import 'x';errorok
exportsokerror
module.exportsokerror
export {};errorok

タイミング

モジュールの実行タイミングです。

CodeTimingHoistedBlocking
require('x');syncnoyes
import 'x';untimed (async generally)yesyes
import('x');asyncnono

ESM では使えないメソッド・変数

以下のメソッド・変数は、CJS でのみ存在し、ESM では存在しないため、エラーになります。

  • __dirname
  • __filename
  • require
  • exports
  • module
  • arguments

予約語への操作

予約語が変数として操作可能かどうかです。 e.g. var let = 1;

CodeCJSESM
argumentsscope::localerror
arguments = []okerror
try {} catch (arguments) {}okerror
evalscope::localerror
eval = evalokerror
try {} catch (eval) {}okerror
implementsokerror
interfaceokerror
packageokerror
privateokerror
protectedokerror
publicokerror
staticokerror
awaitokerror
letokerror
returnerrorerror
yieldokerror
awaitokerror

厳格モード時に変数として使えなくなる予約語です。

  • arguments
  • eval
  • implements
  • interface
  • package
  • private
  • protected
  • public
  • static
  • let
  • yield
// index.js
var arguments;
arguments = [];

var eval = 1;
eval = eval;

// constは予約語ですが、letは違います
var implements,
  interface,
  package,
  private,
  protected,
  public,
  static,
  let,
  yield,
  await;

上記以外の許容されない記法

特殊な記法のケースです。

CodeCJSESMSCRIPT
with({}){}okerrorok
<!--\nokerrorok
-->\nokerrorok
01, 0111, etc..okerrorok
(function (_, _) {})okerrorok
// index.js
// HTMLコメントはCJSでは使えますが、ESMでは使えません
<!--\n
-->\n
# CJS
$
# ESM
$ Module build failed: SyntaxError: Unexpected token (1:0)
> 1 | <!--\n
    | ^
  2 | -->\n
// index.js
0111;
# CJS
$
# ESM
$ SyntaxError: Octal literals are not allowed in strict mode.

評価に関する違い

パース、実行はできるが、評価結果が異なります。

CodeCJSESMSCRIPT
thismodule({})undefinedglobal
(function (){return this}())globalundefinedglobal
(function () {return typeof this;}).call(1)objectnumberobject
var xlocallocalglobal
var x = 0; eval('var x = 1'); x101
console.log(
  function () {
    return typeof this;
  }.call(1),
);
# CJS
$ object
# ESM
$ number

このケースでは、callthisを 1 として束縛し、スコープで包んだfunctionthisを返しその型を評価します。 thisの束縛がない場合は、スコープで包まれているため、typeof this === '[Function]'です。 CJS の場合は、[Number: 1]となり、ESM のときは 1 となります。 つまり、ESM のときはnew Number(1)とならないので、numberとなります。



過去のブログからのコピーですが、よく見るので検索しやすいように別の記事として残しておきます。 内容が古い可能性があるので注意してください。

Node.jsとECMAScript Modules - hiroppy's site Node.jsに入るECMAScript Mdoulesの特徴を紹介します