0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【JavaScript】CommonJSとES Modulesって何が違うの?

0
Posted at

はじめに

現在「プロを目指す人のためのTypeScript入門」の学習を進めています。第1章の環境構築の段階で、生成されたpackage.json"type": "module"を追加するように、という記述がありました。(実際にはデフォルトでcommonjsが指定されていたので、それをmoduleに書き換えました)
そこで、typecommonjsを指定した時とmoduleを指定した時の違いについて疑問を持ちました。調べたことを整理して書いていきたいと思います。

typeとは

Node.jsは、拡張子が.jsのファイルをどのモジュールシステムで解釈するかをpackage.jsontypeで指定します。
この記事では詳しくは説明しませんが、モジュールとは機能を再利用しやすいように分割したものを指し、モジュールシステムとは複数のモジュールからなるプログラムを作るための仕組みを指します。

  • commonjsを指定した・またはtypeを省略した場合:プロジェクト内のファイルはCommonJSとして扱われる
  • moduleを指定した場合:プロジェクト内のファイルはES Modulesとして扱われる

これらは拡張子で上書きすることも可能で、.cjsはCommonJSとして、.mjsはES Modulesとして扱われます。

CommonJSについて

Node.jsが長く使ってきたモジュールシステムです。そのままではWebブラウザでの動作には対応しておらず、バンドラを使って変換を行う必要があります。
構文の特徴は以下の通りです。

  • module.exports/exportsでモジュールをエクスポートする

例①(module.exports):

math.js
function add(a, b) {
  return a + b;
}

module.exports = { add };

例②(exports):

math.js
exports.add = (a, b) => a + b;
  • require("...")で他のモジュールをインポートする

例:

const math = require("./math");
console.log(math.add(2, 3));

requireは通常の関数呼び出しとして実行時に評価されるため、条件分岐の中で呼び出すといった書き方が可能です。
CommonJSではモジュールの読み込みが同期的に行われ、読み込みが完了するまではそのほかの処理はブロックされます。

ES Modulesについて

ES2015で追加されたモジュールシステムです。Node.js・Webブラウザ両方に対応しています。
構文の特徴は以下の通りです。

  • exportでモジュールのエクスポートを宣言する

例:

math.js
export const add = (a, b) => a + b;
export const sub = (a, b) => a - b;
  • importでモジュールのインポートを宣言する

例:

import { add } from "./math.js";
console.log(add(2, 3));
  • import()で動的にモジュールをインポートする

例:

const math = await import("./math.js");
console.log(math.add(2, 3));

import宣言はモジュールのトップレベルにしか書くことができません。CommonJSのrequireのように実行時に動的にモジュールを読み込みたい場合にはimport()を使います。
また、ES Modulesではモジュールの読み込みが非同期的に行われます。

以下の形でES ModulesからCommonJSをインポートすることも可能です。

import math from "./math.cjs";
console.log(math.add(2, 3));

対応関係の整理

観点 CommonJS ES Modules
インポート require import / import()
エクスポート module.exports, exports export
package.json type 未指定または "type": "commonjs" "type": "module"
拡張子 .cjs .mjs

おわりに

普段はES Modulesしか使う機会がなく、モジュールシステムについて意識することも特になかったため、CommonJSの構文は見慣れず新鮮に感じました。
最近はES Modulesを使うのが主流になってきているとのことですが、CommonJSについてもJavaScriptの基本知識として押さえておきたいと思います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?