1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
|
---
title: import
slug: Web/JavaScript/Reference/Statements/import
tags:
- ECMAScript 2015
- JavaScript
- Language feature
- Modules
- Reference
- Statement
- dynamic import
- import
translation_of: Web/JavaScript/Reference/Statements/import
---
<div>{{jsSidebar("Statements")}}</div>
<p><code><strong>import</strong></code> 文は、他のモジュールによって<a href="/ja/docs/Web/JavaScript/Reference/Statements/export">エクスポート</a>された読み込み専用のライブバインディングをインポートするために使用します。インポートされたモジュールは、宣言するかどうかにかかわらず、{{JSxRef("Strict_mode","Strict モード")}}になります。<code>import</code> 文は、スクリプトに <code>type="module"</code> がない限り、埋め込みスクリプトで使用できません。インポートされたバインディングは、バインディングをエクスポートしたモジュールによって更新されるため、ライブバインディングと呼ばれます。</p>
<p>また、<code>type="module"</code> のスクリプトを必要としない動的 <code><strong>import()</strong></code> という関数のようなものもあります。</p>
<p>{{HTMLElement("script")}} タグの <code>nomodule</code> 属性を使用すると、下位互換性を確保できます。</p>
<h2 id="Syntax" name="Syntax">構文</h2>
<pre class="syntaxbox brush:js notranslate">import <em>defaultExport</em> from "<em>module-name</em>";
import * as <em>name</em> from "<em>module-name</em>";
import { <em>export1</em> } from "<em>module-name</em>";
import { <em>export1</em> as <em>alias1</em> } from "<em>module-name</em>";
import { <em>export1</em> , <em>export2</em> } from "<em>module-name</em>";
import { <em>foo</em> , <em>bar</em> } from "<em>module-name/path/to/specific/un-exported/file</em>";
import { <em>export1</em> , <em>export2</em> as <em>alias2</em> , [...] } from "<em>module-name</em>";
import <em>defaultExport</em>, { export1 [ , [...] ] } from "<em>module-name</em>";
import <em>defaultExport</em>, * as <em>name</em> from "<em>module-name</em>";
import "<em>module-name</em>";
var promise = import("<em>module-name</em>");
</pre>
<dl>
<dt><code>defaultExport</code></dt>
<dd>モジュールからのデフォルトのエクスポートを参照する名前。</dd>
<dt><code>module-name</code></dt>
<dd>インポートするモジュール。モジュールがある <code>.js</code> ファイルへの相対または絶対パス名です。バンドラーによっては、拡張子を加えることが許され、あるいは求められることがあります。環境を確認してください。シングルクォートとダブルクォートだけが使えます。</dd>
<dt><code>name</code></dt>
<dd>インポートを参照するとき名前空間のように用いられるモジュールオブジェクトの名前。</dd>
<dt><code>exportN</code></dt>
<dd>インポートするエクスポートの名前。</dd>
<dt><code>aliasN</code></dt>
<dd>指定されたインポートを参照する名前。</dd>
</dl>
<h2 id="Description" name="Description">説明</h2>
<p><code>name</code> パラメータは、エクスポートを参照する名前空間のように用いられる「モジュールオブジェクト」の名前です。<code>export</code> パラメータは名前がつけられたエクスポートをそれぞれ指定します。それに対して、<code>import * as name</code> 構文はすべてをインポートします。構文の意味を明らかにするため、下記に例を示します。</p>
<h3 id="Import_an_entire_modules_contents" name="Import_an_entire_module's_contents">モジュールのコンテンツすべてをインポートする</h3>
<p>下記のコードは、<code>myModule</code> を現在のスコープに加え、<code>/modules/my-module.js</code> のファイルのモジュールからのエクスポートすべてを含めます。</p>
<pre class="brush: js notranslate">import * as <em>myModule</em> from '/modules/my-module.js';
</pre>
<p>エクスポートにアクセスするには、モジュール名(ここでは「myModule」)を名前空間として用いることになります。たとえば、上記でインポートされたモジュールがエクスポートに <code>doAllTheAmazingThings()</code> を含む場合は、下記のように呼び出します。</p>
<pre class="brush: js notranslate">myModule.doAllTheAmazingThings();</pre>
<h3 id="Import_a_single_export_from_a_module" name="Import_a_single_export_from_a_module">モジュールからエクスポートをひとつインポートする</h3>
<p><code>myExport</code> という名前のオブジェクトまたは値が、<code>my-module</code> から暗黙的 (モジュール全体がエクスポートされた場合) あるいは {{jsxref("Statements/export", "export")}} 文を用いて明示的にエクスポートされると、<code>myExport</code> が現在のスコープに加えられます。</p>
<pre class="brush: js notranslate">import {myExport} from '/modules/my-module.js';</pre>
<h3 id="Import_multiple_exports_from_module" name="Import_multiple_exports_from_module">モジュールから複数のエクスポートをインポートする</h3>
<p>下記のコードは、<code>foo</code> と <code>bar</code> を現在のスコープに加えます。</p>
<pre class="brush: js notranslate">import {foo, bar} from '/modules/my-module.js';</pre>
<h3 id="Import_an_export_with_a_more_convenient_alias" name="Import_an_export_with_a_more_convenient_alias">エクスポートを扱いやすいエイリアスにしてインポートする</h3>
<p>インポートするときエクスポートの名前を変えることができます。例えば下記のコードは、エクスポートを <code>shortName</code> として現在のスコープに加えます。</p>
<pre class="brush: js notranslate">import {reallyReallyLongModuleExportName as shortName}
from '/modules/my-module.js';</pre>
<h3 id="Rename_multiple_exports_during_import" name="Rename_multiple_exports_during_import">インポートする際に複数のエクスポートの名前を変える</h3>
<p>下記のコードは、複数のエクスポートを扱いやすいエイリアスにしてモジュールからインポートします。</p>
<pre class="brush: js notranslate">import {
reallyReallyLongModuleExportName as shortName,
anotherLongModuleName as short
} from '/modules/my-module.js';</pre>
<h3 id="Import_a_module_for_its_side_effects_only" name="Import_a_module_for_its_side_effects_only">副作用のためだけにモジュールをインポートする</h3>
<p>副作用だけのためにモジュール全体をインポートしたときは、何もインポートされません。モジュールのグローバルコードが実行されるだけで、実際の値はインポートされないのです。</p>
<pre class="brush: js notranslate">import '/modules/my-module.js';
</pre>
<p>これは{{anch("Dynamic Imports", "動的インポート")}}にも対応しています。</p>
<pre class="brush: js notranslate">(async () => {
if (somethingIsTrue) {
// 副作用のためのインポートモジュール
await import('/modules/my-module.js');
}
})();</pre>
<p>If your project uses packages that export ESM, you can also import them for side effects only. This will run the code in the package entry point file (and any files it imports) only. </p>
<h3 id="Importing_defaults" name="Importing_defaults">デフォルトをインポートする</h3>
<p>デフォルトの {{jsxref("Statements/export", "export")}}(オブジェクト、関数、クラスなど)にも対応できます。<code>import</code> 文を用いて、そのようなデフォルトをインポートします。</p>
<p>もっとも単純なやり方は、デフォルトを直接インポートすることです。</p>
<pre class="brush: js notranslate">import myDefault from '/modules/my-module.js';</pre>
<p>また、デフォルトの構文とともに上記のエイリアス(名前空間または名前つきのインポート)を用いることもできます。その場合は下記のように、デフォルトのインポートを先に宣言しなければなりません。</p>
<pre class="brush: js notranslate">import myDefault, * as myModule from '/modules/my-module.js';
// myModule は名前空間として使う</pre>
<p>あるいは、次のような書き方もできます。</p>
<pre class="brush: js notranslate">import myDefault, {foo, bar} from '/modules/my-module.js';
// 特定の名前つきのインポート
</pre>
<p>{{anch("Dynamic Imports", "動的インポート")}}を使用してデフォルトのエクスポートをインポートする場合、動作が少し異なります。返されたオブジェクトから "default" キーを破棄して名前を変更する必要があります。</p>
<pre class="brush: js notranslate">(async () => {
if (somethingIsTrue) {
const { default: myDefault, foo, bar } = await import('/modules/my-module.js');
}
})();</pre>
<h3 id="Dynamic_Imports" name="Dynamic_Imports">動的インポート</h3>
<p>標準のインポート構文は静的で、インポートされたモジュールのすべてのコードは、ロード時に常に評価されます。条件付きまたはオンデマンドでモジュールをロードしたい状況では、代わりに動的インポートを使用できます。以下に、動的インポートの使用を検討する必要がある理由をいくつか述べます。</p>
<ul>
<li>静的にインポートすると、コードの読み込みが大幅に遅くなり、インポートするコードが必要になる可能性が低くなるか、後で必要になる可能性が低くなります。</li>
<li>静的にインポートすると、プログラムのメモリー使用量が大幅に増加し、インポートするコードが必要になる可能性が低くなります。</li>
<li>ロード時にインポートするモジュールが存在しない場合。</li>
<li>インポート指定子の文字列を動的に作成する必要がある場合。(静的インポートは静的指定子のみをサポートします。)</li>
<li>インポートするモジュールに副作用があり、何らかの条件が真でない限り、それらの副作用を望まない場合。(モジュールに副作用がないことを推奨しますが、モジュールの依存関係でこれを制御できない場合があります。)</li>
</ul>
<p>動的インポートは必要な場合にのみ使用してください。初期の依存関係をロードするには静的な形式が適していて、静的解析ツールや<a href="/ja/docs/Glossary/Tree_shaking">ツリーシェイク</a>の恩恵をよりよく受けることができます。</p>
<p>モジュールを動的にインポートするために、<code>import</code> キーワードを関数として呼び出すことができます。この方法で使用すると、promise が返されます。</p>
<pre class="brush: js notranslate">import('/modules/my-module.js')
.then((module) => {
// module を使った何らかの処理
});
</pre>
<p>この方法は <code>await</code> キーワードを使えます。</p>
<pre class="brush: js notranslate">let module = await import('/modules/my-module.js');</pre>
<h2 id="Examples" name="Examples">例</h2>
<h3 id="Standard_Import" name="Standard_Import">標準的なインポート</h3>
<p>以下のコードは AJAX JSON リクエストの処理を支援する補助モジュールからインポートする方法を示しています。</p>
<h4 id="The_module_file.js" name="The_module_file.js">モジュール: file.js</h4>
<pre class="brush: js notranslate">function getJSON(url, callback) {
let xhr = new XMLHttpRequest();
xhr.onload = function () {
callback(this.responseText)
};
xhr.open('GET', url, true);
xhr.send();
}
export function getUsefulContents(url, callback) {
getJSON(url, data => callback(JSON.parse(data)));
}</pre>
<h4 id="The_main_program_main.js" name="The_main_program_main.js">メインプログラム: main.js</h4>
<pre class="brush: js notranslate">import { getUsefulContents } from '/modules/file.js';
getUsefulContents('http://www.example.com',
data => { doSomethingUseful(data); });</pre>
<h3 id="Dynamic_Import" name="Dynamic_Import">動的インポート</h3>
<p>この例は、ユーザーのアクション(この場合はボタンクリック)に基づいて機能をページにロードし、そのモジュール内で関数を呼び出す方法を示しています。この機能を実装する方法はこれだけではありません。<code>import()</code> 関数は <code>await</code> もサポートしています。</p>
<pre class="brush: js notranslate">const main = document.querySelector("main");
for (const link of document.querySelectorAll("nav > a")) {
link.addEventListener("click", e => {
e.preventDefault();
import('/modules/my-module.js')
.then(module => {
module.loadPageInto(main);
})
.catch(err => {
main.textContent = err.message;
});
});
}</pre>
<h2 id="Specifications" name="Specifications">仕様</h2>
<table class="standard-table">
<thead>
<tr>
<th scope="col">仕様書</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{SpecName("ESDraft", "#sec-imports", "Imports")}}</td>
</tr>
<tr>
<td>{{SpecName("ESDraft", "#sec-import-calls", "Import Calls")}}</td>
</tr>
</tbody>
</table>
<h2 id="Browser_compatibility" name="Browser_compatibility">ブラウザー実装状況</h2>
<p>{{Compat("javascript.statements.import")}}</p>
<h3 id="Implementation_Progress" name="Implementation_Progress">実装の進捗状況</h3>
<p>この機能はまだブラウザー間の安定性に達していないため、以下の表で、この機能の毎日の実装状況を示しています。このデータは、JavaScript の標準テストスイートである <a href="https://github.com/tc39/test262">Test262</a> で、ナイトリービルド、または各ブラウザーの JavaScript エンジンの最新リリースで、関連する機能テストを実行することで生成されます。</p>
<div>{{EmbedTest262ReportResultsTable("dynamic-import")}}</div>
<h2 id="See_also" name="See_also">関連情報</h2>
<ul>
<li>{{JSxRef("Statements/export", "export")}}</li>
<li><a href="/ja/docs/Web/JavaScript/Reference/Statements/import.meta"><code>import.meta</code></a></li>
<li>Limin Zhu, Brian Terlson and Microsoft Edge Team: <a href="https://blogs.windows.com/msedgedev/2016/05/17/es6-modules-and-beyond/">Previewing ES6 Modules and more from ES2015, ES2016 and beyond</a></li>
<li>Hacks blog post by Jason Orendorff: <a href="https://hacks.mozilla.org/2015/08/es6-in-depth-modules/">ES6 in Depth: Modules</a></li>
<li>Hacks blog post by Lin Clark: <a href="https://hacks.mozilla.org/2018/03/es-modules-a-cartoon-deep-dive/">ES modules: A cartoon deep-dive</a></li>
<li>Axel Rauschmayer's book: <a class="external" href="http://exploringjs.com/es6/ch_modules.html">"Exploring JS: Modules"</a></li>
<li>The Modern JavaScript Tutorial(javascript.info): <a class="external" href="https://javascript.info/import-export">Export and Import</a></li>
</ul>
|