3
2

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のモジュール入門(Part 2)〜ブラウザ と Node.js〜

Posted at

前回までのあらすじ

この記事は続編となっています。前回の記事はこちら:

Part 1 では JavaScript のモジュール機能の代表的な2つの仕様を紹介しました。

  • ECMAScript のモジュール機能 (通称 ES Modules)
    • ES6(ES2015) で追加された
    • exportimport を使う
  • CommonJS のモジュール機能
    • 2009年ごろから存在する
    • exportsrequire を使う

今回は、それぞれの仕様を実際に使う方法として、以下を紹介します。

  • ブラウザでモジュール機能を使う方法
  • Node.js でモジュール機能を使う方法

ブラウザでモジュール機能を使う方法

ブラウザには様々な種類がありますが、HTML Living Standard という HTML の仕様に従っているブラウザがほとんどです。

HTML Living Standard では HTML 内に <script> タグを記載することで JavaScript を実行できるようになっていて、さらに type="module" 属性を指定することで、ECMAScript のモジュール機能 (ES Modules) が使えます。

例として、以下のように変数を export するコードを main.js に保存して、ブラウザ (HTML) で import してみます。

main.js
export const foo = 1

index.html を作成し <script type="module"> 内で import してみます。

index.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <title>タイトル</title>
  </head>
  <body>
    <script type="module">
      import { foo } from './main.js'
      console.log("foo =", foo)
    </script>
  </body>
</html>

ブラウザで読み込めるか試してみましょう!

index.html をそのままブラウザで開くと CORS の都合でエラーになるので、 http-server を使ってローカルサーバーを立てます。

適当なディレクトリの中に main.jsindex.html を置いて、その中に移動しコマンドを実行します。

$ npx http-server
Starting up http-server, serving ./

(省略)

Available on:
  http://127.0.0.1:8082

上記の例だと http://127.0.0.1:8082 にアクセスすればOKです。
真っ白なページが表示されますが、開発者ツールを開くと foo = 1 が表示されているはずです。

image.png

より詳しい使い方やインポートマップなどについても知りたい方は mdn のモジュールのページも参照してみてください。

ES Modules 以前は、どうやって複数の JS を読み込んでいたの?

ES Modules 登場以前は type="module" なしで単に複数の <script> タグを記載して、主にグローバルスコープで変数や関数を定義し参照していました。

main.js
const foo = 1
index.js
console.log("foo =", foo)
index.html
(省略)
    <script src="main.js"></script>
    <script src="index.js"></script>
(省略)

この方法ではグローバルスコープの汚染などの問題があったので、IIFE (即時実行関数式) などを駆使していましたが、ES Modules の登場により安全にモジュール化ができるようになりました。

Node.js でモジュール機能を使う方法

Node.js は JavaScript 実行環境の一つです。Node.js がリリースされた当初は ES Modules がなかったので、 CommonJS のモジュール機能 が長い間使用されてきました。ES2015 で ES Modules が登場した後は、 Node.js でも ECMAScript のモジュール機能 が使用できるようになりました。

Node.js で CommonJS のモジュール機能を使う

まずは CommonJS のモジュール機能を Node.js で使ってみましょう。

まずは CommonJS の module.exports で変数をエクスポートする main.js を用意します。

main.js
const foo = 1

module.exports = { foo }

次に、それを require でインポートする index.js を作成しましょう。

index.js
const { foo } = require('./main.js')

console.log("foo =", foo)

node をインストールした環境で、 index.js を実行してみましょう。

$ node index.js
foo = 1

無事にインポートできました。

Node.js で ECMAScript のモジュール機能を使う

上で記載の通り、 Node.js は CommonJS のモジュール機能 が長い間使用されてきたため、そのままでは ECMAScript のモジュール機能が使えません。方法はいくつかありますが、ここではファイルの拡張子を .mjs にする方法を紹介します。

ES Modules の記法でインポート/エクスポートを記載した、拡張子 .mjs のファイルを用意します。

main.mjs
export const foo = 1
index.mjs
import { foo } from './main.mjs'

console.log("foo =", foo)

先程と同様に index.mjs を実行してみましょう。

$ node index.mjs
foo = 1

ES Modules でもインポートできました :tada:

ES Modules で CommonJS のインポート、またはその逆はできるの?

ES Modules で CommonJS のインポート

できます。普通に import するだけです。

↓ CommonJS のモジュール

main.js
const foo = 1

module.exports = { foo }

↓ ES Modules のモジュール

index.mjs
import { foo } from './main.js'

console.log("foo =", foo)

CommonJS で ES Modules のインポート

逆に、CommonJS のモジュール内で ES Modules のモジュールもインポートできますが、こちらは Node.js のバージョンによって異なるので注意が必要です。

以前は Dynamic import でのみ CommonJS で ES Modules のインポートが可能でした。

index.js
(async () => {
  const { foo } = await import('./main.mjs')

  console.log("foo =", foo)
})()

Node.js v22 では --experimental-require-module オプション指定時のみ require による ES Module のインポートができるようになりました。

index.js
const { foo } = require('./main.mjs')

console.log("foo =", foo)

そして2024年12月にリリースされた Node.js v22.12.0 では、デフォルトで require による ES Module のインポートがサポートされました :tada:

ここまでのまとめ

  • ブラウザ
    • ECMAScript のモジュール機能 (通称 ES Modules) が使用可能
      • <script type="module"> を指定する
  • Node.js
    • CommonJS のモジュール機能が使用可能
    • ECMAScript のモジュール機能も使用可能
      • 拡張子を .mjs にするなど工夫が必要
    • CommonJS <-> ECMAScript で互いにインポート可能
      • CommonJS で ECMAScript のモジュールをインポートする場合は Node.js のバージョンに注意

Part 2 はここまでです。Part 3 以降では以下について書こうと思います。

  • npm パッケージのインポート・エクスポート
  • TypeScript のモジュール機能
  • Webpack や Babel でモジュールはどのように扱われるか
3
2
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
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?