<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ja">
	<id>https://mochiu.net/index.php?action=history&amp;feed=atom&amp;title=JavaScript%E3%81%AE%E5%9F%BA%E7%A4%8E_-_ES%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB</id>
	<title>JavaScriptの基礎 - ESモジュール - 版の履歴</title>
	<link rel="self" type="application/atom+xml" href="https://mochiu.net/index.php?action=history&amp;feed=atom&amp;title=JavaScript%E3%81%AE%E5%9F%BA%E7%A4%8E_-_ES%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB"/>
	<link rel="alternate" type="text/html" href="https://mochiu.net/index.php?title=JavaScript%E3%81%AE%E5%9F%BA%E7%A4%8E_-_ES%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB&amp;action=history"/>
	<updated>2026-04-25T20:48:24Z</updated>
	<subtitle>このウィキのこのページに関する変更履歴</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://mochiu.net/index.php?title=JavaScript%E3%81%AE%E5%9F%BA%E7%A4%8E_-_ES%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB&amp;diff=14377&amp;oldid=prev</id>
		<title>Wiki: ページの作成:「== 概要 == ESモジュール (ECMAScript Modules, ESM) は、ES2015 (ES6) で導入されたJavaScriptの標準モジュールシステムである。&lt;br&gt; 各ファイルが独立したスコープを持ち、&lt;code&gt;export&lt;/code&gt; で値を公開し、&lt;code&gt;import&lt;/code&gt; で他のモジュールの値を利用する仕組みを提供する。&lt;br&gt; &lt;br&gt; ESモジュールの主な特性を以下に示す。&lt;br&gt; * strictモードの自動適用 *: モジュールファ…」</title>
		<link rel="alternate" type="text/html" href="https://mochiu.net/index.php?title=JavaScript%E3%81%AE%E5%9F%BA%E7%A4%8E_-_ES%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB&amp;diff=14377&amp;oldid=prev"/>
		<updated>2026-02-20T20:29:14Z</updated>

		<summary type="html">&lt;p&gt;ページの作成:「== 概要 == ESモジュール (ECMAScript Modules, ESM) は、ES2015 (ES6) で導入されたJavaScriptの標準モジュールシステムである。&amp;lt;br&amp;gt; 各ファイルが独立したスコープを持ち、&amp;lt;code&amp;gt;export&amp;lt;/code&amp;gt; で値を公開し、&amp;lt;code&amp;gt;import&amp;lt;/code&amp;gt; で他のモジュールの値を利用する仕組みを提供する。&amp;lt;br&amp;gt; &amp;lt;br&amp;gt; ESモジュールの主な特性を以下に示す。&amp;lt;br&amp;gt; * strictモードの自動適用 *: モジュールファ…」&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新規ページ&lt;/b&gt;&lt;/p&gt;&lt;div&gt;== 概要 ==&lt;br /&gt;
ESモジュール (ECMAScript Modules, ESM) は、ES2015 (ES6) で導入されたJavaScriptの標準モジュールシステムである。&amp;lt;br&amp;gt;&lt;br /&gt;
各ファイルが独立したスコープを持ち、&amp;lt;code&amp;gt;export&amp;lt;/code&amp;gt; で値を公開し、&amp;lt;code&amp;gt;import&amp;lt;/code&amp;gt; で他のモジュールの値を利用する仕組みを提供する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
ESモジュールの主な特性を以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
* strictモードの自動適用&lt;br /&gt;
*: モジュールファイルは自動的にstrictモードで実行される。&amp;lt;code&amp;gt;&amp;quot;use strict&amp;quot;&amp;lt;/code&amp;gt; を明示する必要はない。&lt;br /&gt;
* プライベートスコープ&lt;br /&gt;
*: &amp;lt;code&amp;gt;export&amp;lt;/code&amp;gt; されない限り、モジュール内の宣言は外部からアクセスできない。&lt;br /&gt;
* 遅延実行 (defer)&lt;br /&gt;
*: ブラウザでは、モジュールスクリプトはHTMLのパース完了後に実行される。&lt;br /&gt;
* 一度だけ評価&lt;br /&gt;
*: 同一モジュールが複数回 &amp;lt;code&amp;gt;import&amp;lt;/code&amp;gt; されても、コードは初回のみ実行されキャッシュされる。&lt;br /&gt;
* 静的解析とTree Shaking&lt;br /&gt;
*: &amp;lt;code&amp;gt;import&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;export&amp;lt;/code&amp;gt; 文はファイルの先頭に記述し、静的に解析できる。バンドラーによるTree Shaking (未使用コードの除去) に対応する。&lt;br /&gt;
* トップレベルawait対応&lt;br /&gt;
*: モジュール内では、関数の外でも &amp;lt;code&amp;gt;await&amp;lt;/code&amp;gt; を使用できる。&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
ブラウザでは &amp;lt;code&amp;gt;&amp;amp;lt;script type=&amp;quot;module&amp;quot;&amp;amp;gt;&amp;lt;/code&amp;gt; と指定することでESMを利用できる。&amp;lt;br&amp;gt;&lt;br /&gt;
Node.jsでは、ファイルの拡張子を &amp;lt;code&amp;gt;.mjs&amp;lt;/code&amp;gt; にするか、&amp;lt;code&amp;gt;package.json&amp;lt;/code&amp;gt; に &amp;lt;code&amp;gt;&amp;quot;type&amp;quot;: &amp;quot;module&amp;quot;&amp;lt;/code&amp;gt; を指定することでESMを有効化できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== モジュールの基本 ==&lt;br /&gt;
==== モジュールとは ====&lt;br /&gt;
&amp;lt;u&amp;gt;モジュールとは、関連するコードを一纏めにしたファイル単位の独立した単位である。&amp;lt;/u&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
モジュールシステムを使用することにより、コードを機能ごとに分割して管理して、再利用性と保守性を高めることができる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
ESモジュールでは、各ファイルがそれ自体のスコープを持つ。&amp;lt;br&amp;gt;&lt;br /&gt;
あるモジュール内で定義した変数や関数は、明示的に &amp;lt;code&amp;gt;export&amp;lt;/code&amp;gt; しない限り他のモジュールからは参照できない。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== モジュールの特性 ====&lt;br /&gt;
下表に、ESモジュールが持つ主要な特性を示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ ESモジュールの特徴&lt;br /&gt;
! 特徴 !! 説明&lt;br /&gt;
|-&lt;br /&gt;
| 自動strictモード || モジュールスコープは自動的にstrictモードとなる。&amp;lt;br&amp;gt;暗黙的なグローバル変数の作成やその他のstrictモード違反がエラーになる。&lt;br /&gt;
|-&lt;br /&gt;
| プライベートスコープ || &amp;lt;code&amp;gt;export&amp;lt;/code&amp;gt; されない宣言はモジュール内でのみ有効である。&amp;lt;br&amp;gt;グローバルスコープを汚染しない。&lt;br /&gt;
|-&lt;br /&gt;
| 遅延評価とキャッシュ || モジュールは、初回 &amp;lt;code&amp;gt;import&amp;lt;/code&amp;gt; 時に評価され、以降は評価済みの結果がキャッシュとして再利用される。&amp;lt;br&amp;gt;そのため、副作用を持つモジュールが複数箇所から &amp;lt;code&amp;gt;import&amp;lt;/code&amp;gt; されても、副作用は1度しか実行されない。&lt;br /&gt;
|-&lt;br /&gt;
| 静的な構造 || &amp;lt;code&amp;gt;import&amp;lt;/code&amp;gt; 文と &amp;lt;code&amp;gt;export&amp;lt;/code&amp;gt; 文は静的に解析される。&amp;lt;br&amp;gt;コードの実行前にモジュール間の依存関係が確定するため、循環依存の検出やTree Shakingが可能になる。&lt;br /&gt;
|-&lt;br /&gt;
| トップレベルawait || ESモジュールでは、非同期関数の外側 (トップレベル) でも &amp;lt;code&amp;gt;await&amp;lt;/code&amp;gt; を使用できる。&amp;lt;br&amp;gt;CommonJSにはない機能である。&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== エクスポート ==&lt;br /&gt;
エクスポートとは、モジュールから値を公開することである。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 名前付きエクスポート ====&lt;br /&gt;
名前付きエクスポートは、1つのモジュールから複数の値をエクスポートする方法である。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
エクスポートした名前がそのままインポート時の識別子となる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
* 宣言と同時にエクスポートする方法&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 // math.js&lt;br /&gt;
 &lt;br /&gt;
 // 宣言と同時にエクスポートする&lt;br /&gt;
 export function add(a, b) {&lt;br /&gt;
    return a + b;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 export function subtract(a, b) {&lt;br /&gt;
    return a - b;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 export const PI = 3.14159;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*: &amp;lt;br&amp;gt;&lt;br /&gt;
* 宣言後にまとめてエクスポートする方法&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 // string-utils.js&lt;br /&gt;
 &lt;br /&gt;
 function capitalize(str) {&lt;br /&gt;
    return str.charAt(0).toUpperCase() + str.slice(1);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 function trim(str) {&lt;br /&gt;
    return str.trim();&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 // エイリアス付きでエクスポートすることもできる&lt;br /&gt;
 function _internalHelper(str) {&lt;br /&gt;
    return str.toLowerCase();&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 // まとめてエクスポートする&lt;br /&gt;
 export { capitalize, trim };&lt;br /&gt;
 &lt;br /&gt;
 // エイリアス付きエクスポート : 内部名とは異なる名前で公開する&lt;br /&gt;
 export { _internalHelper as helper };&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== デフォルトエクスポート ====&lt;br /&gt;
デフォルトエクスポートは、1つのモジュールにつき1つだけ定義できるエクスポートである。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;u&amp;gt;インポート時に任意の名前を付けることができるため、モジュールの主要な機能を公開する場合に適している。&amp;lt;/u&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
デフォルトエクスポートの例を以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
* 関数のデフォルトエクスポート&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 // logger.js&lt;br /&gt;
 &lt;br /&gt;
 // 関数のデフォルトエクスポート&lt;br /&gt;
 export default function log(message) {&lt;br /&gt;
    console.log(&amp;quot;[LOG]&amp;quot;, message);&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*: &amp;lt;br&amp;gt;&lt;br /&gt;
* クラスのデフォルトエクスポート&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 // User.js&lt;br /&gt;
 &lt;br /&gt;
 // クラスのデフォルトエクスポート&lt;br /&gt;
 export default class User {&lt;br /&gt;
    constructor(name, email) {&lt;br /&gt;
       this.name  = name;&lt;br /&gt;
       this.email = email;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    toString() {&lt;br /&gt;
       return this.name + &amp;quot; &amp;lt;&amp;quot; + this.email + &amp;quot;&amp;gt;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*: &amp;lt;br&amp;gt;&lt;br /&gt;
* 値のデフォルトエクスポート&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 // config.js&lt;br /&gt;
 &lt;br /&gt;
 // 値のデフォルトエクスポート (export defaultの後に直接値を記述する)&lt;br /&gt;
 export default {&lt;br /&gt;
    apiUrl  : &amp;quot;https://api.example.com&amp;quot;,&lt;br /&gt;
    timeout : 5000,&lt;br /&gt;
    retries : 3&lt;br /&gt;
 };&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 名前付きエクスポート と デフォルトエクスポートの比較 ====&lt;br /&gt;
下表に、名前付きエクスポートとデフォルトエクスポートの違いを示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ 名前付きエクスポート vs デフォルトエクスポート&lt;br /&gt;
! 項目 !! 名前付きエクスポート !! デフォルトエクスポート&lt;br /&gt;
|-&lt;br /&gt;
| 1モジュールあたりの個数 || 複数可能 || 1つのみ&lt;br /&gt;
|-&lt;br /&gt;
| インポート時の名前 || エクスポート名と一致する。(&amp;lt;code&amp;gt;as&amp;lt;/code&amp;gt; で変更可能) || 任意の名前を指定できる。&lt;br /&gt;
|-&lt;br /&gt;
| インポート構文 || &amp;lt;u&amp;gt;import { name } from &amp;#039;module&amp;#039;&amp;lt;/u&amp;gt; || &amp;lt;u&amp;gt;import name from &amp;#039;module&amp;#039;&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Tree Shaking || 容易 || 限定的&lt;br /&gt;
|-&lt;br /&gt;
| リネームの必要性 || &amp;lt;code&amp;gt;as&amp;lt;/code&amp;gt; キーワードが必要 || インポート時に自由に命名できる。&lt;br /&gt;
|-&lt;br /&gt;
| 主な用途 || ユーティリティ関数群、定数群 || モジュールの単一のメイン機能&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== インポート ==&lt;br /&gt;
==== 名前付きインポート ====&lt;br /&gt;
名前付きエクスポートされた値は、波括弧 &amp;lt;code&amp;gt;{ }&amp;lt;/code&amp;gt; を使用してインポートする。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 import { add, subtract } from &amp;#039;./math.js&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
 console.log(add(10, 3));       // 13&lt;br /&gt;
 console.log(subtract(10, 3));  // 7&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== デフォルトインポート ====&lt;br /&gt;
デフォルトエクスポートされた値は、波括弧なしでインポートする。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
インポート時の名前は任意に決めることができる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 import log  from &amp;#039;./logger.js&amp;#039;;&lt;br /&gt;
 import User from &amp;#039;./User.js&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
 log(&amp;quot;アプリケーション起動&amp;quot;);  // &amp;quot;[LOG]アプリケーション起動&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 const user = new User(&amp;quot;太郎&amp;quot;, &amp;quot;taro@example.com&amp;quot;);&lt;br /&gt;
 console.log(user.toString());  // &amp;quot;太郎 &amp;lt;taro@example.com&amp;gt;&amp;quot;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
名前付きインポートとデフォルトインポートを1行で組み合わせることもできる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 // デフォルトインポートと名前付きインポートを同時に行う&lt;br /&gt;
 &lt;br /&gt;
 import React, { useState, useEffect } from &amp;#039;react&amp;#039;;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== エイリアス (as) ====&lt;br /&gt;
&amp;lt;code&amp;gt;as&amp;lt;/code&amp;gt; キーワードを使用することにより、インポートする値に別名 (エイリアス) を付けることができる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
これは、名前の衝突を避けたい場合や、より分かりやすい名前で使用したい場合に有用である。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 import { capitalize as capitalizeString } from &amp;#039;./string-utils.js&amp;#039;;&lt;br /&gt;
 import { helper     as stringHelper }     from &amp;#039;./string-utils.js&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
 console.log(capitalizeString(&amp;quot;hello&amp;quot;));  // &amp;quot;Hello&amp;quot;&lt;br /&gt;
 console.log(stringHelper(&amp;quot;WORLD&amp;quot;));      // &amp;quot;world&amp;quot;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 名前空間インポート ====&lt;br /&gt;
&amp;lt;code&amp;gt;* as&amp;lt;/code&amp;gt; 構文を使用することで、モジュールの全エクスポートを1つのオブジェクトにまとめてインポートできる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
名前空間として利用することで、複数のエクスポートを整理して管理できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 import * as MathUtils from &amp;#039;./math.js&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
 console.log(MathUtils.add(5, 3));       // 8&lt;br /&gt;
 console.log(MathUtils.subtract(5, 3));  // 2&lt;br /&gt;
 console.log(MathUtils.PI);              // 3.14159&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 副作用のみのインポート ====&lt;br /&gt;
インポートする値を指定せずに &amp;lt;code&amp;gt;import&amp;lt;/code&amp;gt; 文を記述すると、モジュールのコードを実行するだけで何もインポートしない。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
これは、ポリフィルや、グローバルに副作用を適用するモジュールで使用される。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 // モジュールのコードを実行するだけで、何もインポートしない&lt;br /&gt;
 &lt;br /&gt;
 import &amp;#039;./polyfills.js&amp;#039;;&lt;br /&gt;
 import &amp;#039;./global-styles.css&amp;#039;;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 再エクスポート ==&lt;br /&gt;
再エクスポートとは、他のモジュールからインポートした値を、そのまま別のモジュールとして公開する方法である。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 基本構文 ====&lt;br /&gt;
&amp;lt;code&amp;gt;export ... from&amp;lt;/code&amp;gt; 構文を使用することにより、インポートした値を再エクスポートできる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
1度インポートしてから再エクスポートする場合と比較して、変数に束縛されないため簡潔に記述できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 // 特定の名前付きエクスポートを再エクスポートする&lt;br /&gt;
 export { add, subtract } from &amp;#039;./math.js&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
 // エイリアスを付けて再エクスポートする&lt;br /&gt;
 export { capitalize as cap } from &amp;#039;./string-utils.js&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
 // モジュールの全エクスポートを再エクスポートする&lt;br /&gt;
 export * from &amp;#039;./math.js&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
 // デフォルトエクスポートを名前付きで再エクスポートする&lt;br /&gt;
 export { default as User } from &amp;#039;./User.js&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
 // デフォルトエクスポートをデフォルトのまま再エクスポートする&lt;br /&gt;
 export { default } from &amp;#039;./logger.js&amp;#039;;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== バレルファイル (index.js) パターン ====&lt;br /&gt;
複数のモジュールを1つのエントリポイントにまとめて公開するパターンをバレルファイルパターンと呼ぶ。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;index.jsファイル&amp;lt;/code&amp;gt; (または &amp;lt;code&amp;gt;index.tsファイル&amp;lt;/code&amp;gt;) に再エクスポートをまとめることにより、利用側のインポートパスを短くできる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 // components/index.js (バレルファイル)&lt;br /&gt;
 &lt;br /&gt;
 export { Button }    from &amp;#039;./Button.js&amp;#039;;&lt;br /&gt;
 export { Modal }     from &amp;#039;./Modal.js&amp;#039;;&lt;br /&gt;
 export { TextInput } from &amp;#039;./TextInput.js&amp;#039;;&lt;br /&gt;
 export { default as Icon } from &amp;#039;./Icon.js&amp;#039;;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 // 利用側: バレルファイルを通じて複数のコンポーネントを1行でインポートできる&lt;br /&gt;
 import { Button, Modal, TextInput } from &amp;#039;./components&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
 // 個別パスを指定する場合と比べて記述が簡潔になる&lt;br /&gt;
 // import { Button }    from &amp;#039;./components/Button.js&amp;#039;;&lt;br /&gt;
 // import { Modal }     from &amp;#039;./components/Modal.js&amp;#039;;&lt;br /&gt;
 // import { TextInput } from &amp;#039;./components/TextInput.js&amp;#039;;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
バレルファイルを使用する時の注意点を以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;u&amp;gt;Tree Shakingへの影響&amp;lt;/u&amp;gt;&lt;br /&gt;
*: バンドラーによっては、バレルファイルを経由したインポートでTree Shakingが効きにくくなる場合がある。&lt;br /&gt;
*: 特に大規模なライブラリでは、バレルファイルのインポートがバンドルサイズの増加につながる場合がある。&lt;br /&gt;
* &amp;lt;u&amp;gt;循環依存のリスク&amp;lt;/u&amp;gt;&lt;br /&gt;
*: バレルファイルを多用すると、モジュール間の循環依存が発生しやすくなる。&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 動的インポート ==&lt;br /&gt;
動的にインポートとは、実行時に必要に応じてモジュールを非同期でロードする方法である。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== import()の基本 ====&lt;br /&gt;
&amp;lt;code&amp;gt;import()&amp;lt;/code&amp;gt; は関数のような構文で呼び出す動的インポートである。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
通常の &amp;lt;code&amp;gt;import&amp;lt;/code&amp;gt; 文と異なり、コードの任意の場所に記述でき、条件分岐やイベントに応じてモジュールを遅延ロードできる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;import()&amp;lt;/code&amp;gt; はPromiseを返し、モジュールオブジェクトに解決される。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 // Promiseチェーンを使用した動的インポート&lt;br /&gt;
 import(&amp;#039;./math.js&amp;#039;)&lt;br /&gt;
    .then(mathModule =&amp;gt; {&lt;br /&gt;
       console.log(mathModule.add(5, 3));  // 8&lt;br /&gt;
    });&lt;br /&gt;
 &lt;br /&gt;
 // async/awaitを使用した動的インポート&lt;br /&gt;
 const math = await import(&amp;#039;./math.js&amp;#039;);&lt;br /&gt;
 console.log(math.add(5, 3));  // 8&lt;br /&gt;
 &lt;br /&gt;
 // デフォルトエクスポートにアクセスする場合は .default を使用する&lt;br /&gt;
 const logModule = await import(&amp;#039;./logger.js&amp;#039;);&lt;br /&gt;
 logModule.default(&amp;quot;メッセージ&amp;quot;);&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 使用例 ====&lt;br /&gt;
動的インポートの代表的な使用場面を以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
* 条件に応じたモジュールの読み込み&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 // ユーザのロールに応じて異なるモジュールを読み込む&lt;br /&gt;
 async function loadUserModule(userRole) {&lt;br /&gt;
    if (userRole === &amp;#039;admin&amp;#039;) {&lt;br /&gt;
       const { AdminPanel } = await import(&amp;#039;./admin-panel.js&amp;#039;);&lt;br /&gt;
       return new AdminPanel();&lt;br /&gt;
    }&lt;br /&gt;
    else {&lt;br /&gt;
       const { UserDashboard } = await import(&amp;#039;./user-dashboard.js&amp;#039;);&lt;br /&gt;
       return new UserDashboard();&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*: &amp;lt;br&amp;gt;&lt;br /&gt;
* ユーザの操作をトリガーとした遅延読み込み&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 // ボタンが押下された時にのみモジュールを読み込む&lt;br /&gt;
 button.addEventListener(&amp;#039;click&amp;#039;, async () =&amp;gt; {&lt;br /&gt;
    const { initChart } = await import(&amp;#039;./chart-library.js&amp;#039;);&lt;br /&gt;
    initChart(document.getElementById(&amp;#039;chart-container&amp;#039;));&lt;br /&gt;
 });&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*: &amp;lt;br&amp;gt;&lt;br /&gt;
* React.lazyを使用したコンポーネントの遅延読み込み&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 import React, { lazy, Suspense } from &amp;#039;react&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
 // 動的インポートによる遅延読み込み&lt;br /&gt;
 const HeavyComponent = lazy(() =&amp;gt; import(&amp;#039;./HeavyComponent.js&amp;#039;));&lt;br /&gt;
 &lt;br /&gt;
 function App() {&lt;br /&gt;
    return (&lt;br /&gt;
       &amp;lt;Suspense fallback={&amp;lt;div&amp;gt;読み込み中...&amp;lt;/div&amp;gt;}&amp;gt;&lt;br /&gt;
          &amp;lt;HeavyComponent /&amp;gt;&lt;br /&gt;
       &amp;lt;/Suspense&amp;gt;&lt;br /&gt;
    );&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Import Attributes (ES2025) ==&lt;br /&gt;
Import Attributesは、モジュールの読み込み時にメタデータを指定する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 基本構文 ====&lt;br /&gt;
Import Attributesは、&amp;lt;code&amp;gt;import&amp;lt;/code&amp;gt; 文に &amp;lt;code&amp;gt;with&amp;lt;/code&amp;gt; キーワードを付加して属性を指定する構文である。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
以前の仕様ではImport Assertions (&amp;lt;code&amp;gt;assert&amp;lt;/code&amp;gt; キーワード) と呼ばれていたが、ES2025でImport Attributes (&amp;lt;code&amp;gt;with&amp;lt;/code&amp;gt; キーワード) に変更された。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 // 静的インポートでの使用&lt;br /&gt;
 import data   from &amp;#039;./data.json&amp;#039;  with { type: &amp;#039;json&amp;#039; };&lt;br /&gt;
 import styles from &amp;#039;./styles.css&amp;#039; with { type: &amp;#039;css&amp;#039; };&lt;br /&gt;
 &lt;br /&gt;
 // 動的インポートでの使用&lt;br /&gt;
 const config = await import(&amp;#039;./config.json&amp;#039;, { with: { type: &amp;#039;json&amp;#039; } });&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== JSONモジュールの読み込み ====&lt;br /&gt;
&amp;lt;code&amp;gt;type: &amp;#039;json&amp;#039;&amp;lt;/code&amp;gt; を指定することにより、JSONファイルをモジュールとして安全に読み込むことができる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 // JSONファイルをインポートする (type: &amp;#039;json&amp;#039; を指定する)&lt;br /&gt;
 import packageJson from &amp;#039;./package.json&amp;#039; with { type: &amp;#039;json&amp;#039; };&lt;br /&gt;
 &lt;br /&gt;
 console.log(packageJson.name);     // パッケージ名&lt;br /&gt;
 console.log(packageJson.version);  // バージョン番号&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
セキュリティ上のメリットとして、&amp;lt;code&amp;gt;type: &amp;#039;json&amp;#039;&amp;lt;/code&amp;gt; を明示指定されたリソースはJavaScriptコードとして実行されない。&amp;lt;br&amp;gt;&lt;br /&gt;
悪意あるサーバがJSONを返すべき場所でJavaScriptを返した場合でも、コードが実行されることを防ぐことができる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== CSSモジュールの読み込み ====&lt;br /&gt;
&amp;lt;code&amp;gt;type: &amp;#039;css&amp;#039;&amp;lt;/code&amp;gt; を指定することで、CSSファイルをCSSStyleSheetオブジェクトとしてインポートできる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
これは、Web ComponentsのShadow DOMでスタイルを適用する時に活用できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 // CSSファイルをモジュールとしてインポートする&lt;br /&gt;
 import styles from &amp;#039;./component.css&amp;#039; with { type: &amp;#039;css&amp;#039; };&lt;br /&gt;
 &lt;br /&gt;
 // Web ComponentsのShadow DOMにスタイルを適用する&lt;br /&gt;
 class MyComponent extends HTMLElement {&lt;br /&gt;
    constructor() {&lt;br /&gt;
       super();&lt;br /&gt;
       const shadow = this.attachShadow({ mode: &amp;#039;open&amp;#039; });&lt;br /&gt;
       shadow.adoptedStyleSheets = [styles];&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Webブラウザの対応状況 および Node.jsサポートを以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
* Webブラウザ&lt;br /&gt;
*: Chrome 121以降、Edge 121以降、Safari 17.4以降でサポートされている。&lt;br /&gt;
* Node.js&lt;br /&gt;
*: v22以降で &amp;lt;code&amp;gt;with&amp;lt;/code&amp;gt; 構文が標準サポートされている。&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CommonJSとの比較 ==&lt;br /&gt;
下表に、JavaScriptのもう1つの主要なモジュールシステムであるCommonJS (CJS) とESモジュール (ESM) の違いを示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ CommonJS と ESモジュール&lt;br /&gt;
! 項目 !! CommonJS !! ESモジュール&lt;br /&gt;
|-&lt;br /&gt;
| 読み込み構文 || &amp;lt;u&amp;gt;require(&amp;#039;module&amp;#039;)&amp;lt;/u&amp;gt; || &amp;lt;u&amp;gt;import ... from &amp;#039;module&amp;#039;&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| エクスポート構文 || &amp;lt;u&amp;gt;module.exports&amp;lt;/u&amp;gt; / &amp;lt;u&amp;gt;exports.name&amp;lt;/u&amp;gt; || &amp;lt;u&amp;gt;export&amp;lt;/u&amp;gt; / &amp;lt;u&amp;gt;export default&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| ロードタイミング || 同期・実行時 || 非同期・解析時&lt;br /&gt;
|-&lt;br /&gt;
| 静的解析 || 困難 (動的) || 容易 (静的)&lt;br /&gt;
|-&lt;br /&gt;
| Tree Shaking || 困難 || 容易&lt;br /&gt;
|-&lt;br /&gt;
| トップレベルawait || 不可 || 可能&lt;br /&gt;
|-&lt;br /&gt;
| strictモード || 手動指定 (&amp;lt;u&amp;gt;&amp;quot;use strict&amp;quot;&amp;lt;/u&amp;gt;) || 自動適用&lt;br /&gt;
|-&lt;br /&gt;
| ブラウザサポート || なし (バンドラーが必要) || ネイティブサポート&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;u&amp;gt;__dirname&amp;lt;/u&amp;gt; / &amp;lt;u&amp;gt;__filename&amp;lt;/u&amp;gt; || 利用可能 || &amp;lt;u&amp;gt;import.meta.url&amp;lt;/u&amp;gt; で代替&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
下表に、Node.jsでのESMサポートに関する設定を示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Node.jsでのESMサポートに関する設定&lt;br /&gt;
! 設定 !! 説明&lt;br /&gt;
|-&lt;br /&gt;
| .mjs拡張子 || ファイルをESMとして扱う。&lt;br /&gt;
|-&lt;br /&gt;
| .cjs拡張子 || ファイルをCommonJSとして扱う。&lt;br /&gt;
|-&lt;br /&gt;
| package.jsonファイルへの &amp;lt;code&amp;gt;&amp;quot;type&amp;quot;: &amp;quot;module&amp;quot;&amp;lt;/code&amp;gt; の指定 || ディレクトリ内の &amp;lt;u&amp;gt;.js拡張子&amp;lt;/u&amp;gt; のファイルをESMとして扱う。&lt;br /&gt;
|-&lt;br /&gt;
| Node.js v22以降 || CommonJSモジュールからESMを &amp;lt;code&amp;gt;require()&amp;lt;/code&amp;gt; で読み込めるようになった。&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Node.jsにおける &amp;lt;code&amp;gt;__dirname&amp;lt;/code&amp;gt; の代替方法を以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 // ESMでは __dirname が使用できないため、import.meta.url で代替する&lt;br /&gt;
 import { fileURLToPath } from &amp;#039;url&amp;#039;;&lt;br /&gt;
 import { dirname }       from &amp;#039;path&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
 const __filename = fileURLToPath(import.meta.url);&lt;br /&gt;
 const __dirname  = dirname(__filename);&lt;br /&gt;
 &lt;br /&gt;
 console.log(__dirname);  // 現在のファイルが存在するディレクトリのパス&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 関連情報 ==&lt;br /&gt;
* [[JavaScriptの基礎 - クラス]]&lt;br /&gt;
* [[JavaScriptの基礎 - 関数宣言と関数式]]&lt;br /&gt;
* [[JavaScriptの基礎 - パッケージ管理]]&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{#seo:&lt;br /&gt;
|title={{PAGENAME}} : Exploring Electronics and SUSE Linux | MochiuWiki&lt;br /&gt;
|keywords=MochiuWiki,Mochiu,Wiki,Mochiu Wiki,Electric Circuit,Electric,pcb,Mathematics,AVR,TI,STMicro,AVR,ATmega,MSP430,STM,Arduino,Xilinx,FPGA,Verilog,HDL,PinePhone,Pine Phone,Raspberry,Raspberry Pi,C,C++,C#,Qt,Qml,MFC,Shell,Bash,Zsh,Fish,SUSE,SLE,Suse Enterprise,Suse Linux,openSUSE,open SUSE,Leap,Linux,uCLnux,電気回路,電子回路,基板,プリント基板&lt;br /&gt;
|description={{PAGENAME}} - 電子回路とSUSE Linuxに関する情報 | This page is {{PAGENAME}} in our wiki about electronic circuits and SUSE Linux&lt;br /&gt;
|image=/resources/assets/MochiuLogo_Single_Blue.png&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
__FORCETOC__&lt;br /&gt;
[[カテゴリ:Web]]&lt;/div&gt;</summary>
		<author><name>Wiki</name></author>
	</entry>
</feed>