# モジュール: ECMAScript モジュール
> 安定性: 2 - 安定 ## はじめにECMAScript モジュールは、JavaScript コードを再利用のためにパッケージ化する[公式標準フォーマット][]です。モジュールは、様々な [`import`][] および [`export`][] ステートメントを使用して定義されます。次の ES モジュールの例では、関数をエクスポートしています。 ```js // addTwo.mjs function addTwo(num) { return num + 2; } export { addTwo }; ``` 次の ES モジュールの例では、`addTwo.mjs` から関数をインポートしています。 ```js // app.mjs import { addTwo } from './addTwo.mjs'; // Prints: 6 console.log(addTwo(4)); ``` Node.js は、現在指定されている ECMAScript モジュールを完全にサポートしており、元のモジュールフォーマットである [CommonJS][] との相互運用性を提供しています。
## 有効化Node.js には、[CommonJS][] モジュールと ECMAScript モジュールの 2 つのモジュールシステムがあります。作成者は、`.mjs` ファイル拡張子、値が `"module"` の `package.json` [`"type"`][] フィールド、値が `"module"` の [`--input-type`][] フラグ、または値が `"module"` の [`--experimental-default-type`][] フラグを介して、JavaScript を ES モジュールとして解釈するように Node.js に指示できます。これらは、コードが ES モジュールとして実行されることを意図している明確なマーカーです。逆に、作成者は、`.cjs` ファイル拡張子、値が `"commonjs"` の `package.json` [`"type"`][] フィールド、値が `"commonjs"` の [`--input-type`][] フラグ、または値が `"commonjs"` の [`--experimental-default-type`][] フラグを介して、JavaScript を CommonJS として解釈するように Node.js に指示できます。コードにどちらのモジュールシステムの明示的なマーカーもない場合、Node.js はモジュールのソースコードを調べて ES モジュールの構文を探します。そのような構文が見つかった場合、Node.js はコードを ES モジュールとして実行します。それ以外の場合は、モジュールを CommonJS として実行します。詳細については、[モジュールシステムの決定][]を参照してください。
## パッケージ このセクションは、[モジュール: パッケージ](packages.md) に移動しました。 ## `import` 指定子 ### 用語 `import` ステートメントの _指定子_ は、`from` キーワードの後の文字列です。例えば、`import { sep } from 'node:path'` の `'node:path'` のようなものです。指定子は、`export from` ステートメントや、`import()` 式の引数としても使用されます。指定子には 3 つのタイプがあります。 * `'./startup.js'` や `'../config.mjs'` のような _相対指定子_ 。これらは、インポートするファイルの場所からの相対パスを参照します。 _この場合、ファイル拡張子は常に必要です。_ * `'some-package'` や `'some-package/shuffle'` のような _ベア指定子_ 。これらは、パッケージ名でパッケージのメインエントリポイントを参照したり、それぞれの例のようにパッケージ名がプレフィックスされたパッケージ内の特定機能モジュールを参照できます。 _[`"exports"`][] フィールドのないパッケージの場合のみ、ファイル拡張子を含める必要があります。_ * `'file:///opt/nodejs/config.js'` のような _絶対指定子_ 。これらは、完全なパスを直接かつ明示的に参照します。ベア指定子の解決は、[Node.js モジュール解決およびロードアルゴリズム][]によって処理されます。他のすべての指定子の解決は、常に標準の相対 [URL][] 解決セマンティクスのみで解決されます。CommonJS と同様に、パッケージ内のモジュールファイルには、パッケージの [`package.json`][] に [`"exports"`][] フィールドが含まれていない限り、パッケージ名にパスを追加することでアクセスできます。`"exports"` フィールドが含まれている場合、パッケージ内のファイルには、[`"exports"`][] で定義されたパスを介してのみアクセスできます。Node.js モジュール解決におけるベア指定子に適用されるこれらのパッケージ解決規則の詳細については、[パッケージのドキュメント](packages.md)を参照してください。 ### 必須のファイル拡張子 相対または絶対指定子を解決するために `import` キーワードを使用する場合は、ファイル拡張子を指定する必要があります。ディレクトリインデックス (例: `'./startup/index.js'`) も完全に指定する必要があります。この動作は、通常構成されたサーバーを想定すると、ブラウザ環境での `import` の動作と一致します。 ### URL ES モジュールは、URL として解決およびキャッシュされます。つまり、`#` は `%23`、`?` は `%3F` のように、特殊文字は [パーセントエンコード][]する必要があります。`file:`、`node:`、および `data:` URL スキームがサポートされています。 `'https://example.com/app.js'` のような指定子は、[カスタム HTTPS ローダー][]を使用しない限り、Node.js ではネイティブにサポートされていません。 #### `file:` URL モジュールは、解決に使用される `import` 指定子に異なるクエリまたはフラグメントがある場合、複数回ロードされます。 ```js import './foo.mjs?query=1'; // ./foo.mjs をクエリ "?query=1" でロードします import './foo.mjs?query=2'; // ./foo.mjs をクエリ "?query=2" でロードします ``` ボリュームルートは、`/`、`//`、または `file:///` で参照できます。[URL][] とパス解決 (パーセントエンコードの詳細など) の違いを考えると、パスをインポートするときは [url.pathToFileURL][] を使用することをお勧めします。 #### `data:` インポート[`data:` URL][] は、次の MIME タイプでインポートするためにサポートされています。 * ES モジュール用の `text/javascript` * JSON 用の `application/json` * Wasm 用の `application/wasm` ```js import 'data:text/javascript,console.log("hello!");'; import _ from 'data:application/json,"world!"' with { type: 'json' }; ``` `data:` URL は、組み込みモジュールと [絶対指定子][用語] の [ベア指定子][用語] のみを解決します。[相対指定子][用語] の解決は、`data:` が [特殊スキーム][] でないため、機能しません。たとえば、`data:text/javascript,import "./foo";` から `./foo` をロードしようとしても、`data:` URL には相対解決の概念がないため、解決できません。 #### `node:` インポート`node:` URL は、Node.js の組み込みモジュールをロードする代替手段としてサポートされています。この URL スキームにより、組み込みモジュールを有効な絶対 URL 文字列で参照できます。 ```js import fs from 'node:fs/promises'; ``` ## インポート属性> 安定性: 1.1 - アクティブな開発 > この機能は以前は "インポートアサーション" という名前で、`with` の代わりに `assert` > キーワードを使用していました。以前の `assert` キーワードをコードで使用している場合は、 > 代わりに `with` を使用するように更新する必要があります。[インポート属性の提案][] は、モジュール指定子と一緒に詳細な情報を渡すためのインライン構文をモジュールインポートステートメントに追加します。 ```js import fooData from './foo.json' with { type: 'json' }; const { default: barData } = await import('./bar.json', { with: { type: 'json' } }); ``` Node.js は、属性が必須である次の `type` 値をサポートしています。 | 属性 `type` | 必要なもの | | ---------------- | ---------------- | | `'json'` | [JSON モジュール][] | ## 組み込みモジュール [コアモジュール][] は、パブリック API の名前付きエクスポートを提供します。また、CommonJS エクスポートの値であるデフォルトのエクスポートも提供されます。デフォルトのエクスポートは、とりわけ、名前付きエクスポートの変更に使用できます。組み込みモジュールの名前付きエクスポートは、[`module.syncBuiltinESMExports()`][] を呼び出すことによってのみ更新されます。 ```js import EventEmitter from 'node:events'; const e = new EventEmitter(); ``` ```js import { readFile } from 'node:fs'; readFile('./foo.txt', (err, source) => { if (err) { console.error(err); } else { console.log(source); } }); ``` ```js import fs, { readFileSync } from 'node:fs'; import { syncBuiltinESMExports } from 'node:module'; import { Buffer } from 'node:buffer'; fs.readFileSync = () => Buffer.from('Hello, ESM'); syncBuiltinESMExports(); fs.readFileSync === readFileSync; ``` ## `import()` 式 [動的 `import()`][] は、CommonJS と ES モジュールの両方でサポートされています。CommonJS モジュールでは、ES モジュールをロードするために使用できます。 ## `import.meta` * {Object} `import.meta` メタプロパティは、次のプロパティを含む `Object` です。 ### `import.meta.dirname`> 安定性: 1.2 - リリースカンディデート * {string} 現在のモジュールのディレクトリ名。これは、[`import.meta.filename`][] の [`path.dirname()`][] と同じです。 > **注意**: `file:` モジュールにのみ存在します。 ### `import.meta.filename`> 安定性: 1.2 - リリースカンディデート * {string} 現在のモジュールの完全な絶対パスとファイル名で、シンボリックリンクは * 解決されています。 * これは、[`import.meta.url`][] の [`url.fileURLToPath()`][] と同じです。 > **注意** ローカルモジュールのみがこのプロパティをサポートします。`file:` > プロトコルを使用しないモジュールは、それを提供しません。 ### `import.meta.url` * {string} モジュールの絶対 `file:` URL。これは、現在のモジュールファイルの URL を提供するブラウザと同じように正確に定義されています。これにより、相対的なファイルロードなどの便利なパターンが可能になります。 ```js import { readFileSync } from 'node:fs'; const buffer = readFileSync(new URL('./data.proto', import.meta.url)); ``` ### `import.meta.resolve(specifier)`> 安定性: 1.2 - リリースカンディデート * `specifier` {string} 現在のモジュールを基準に解決するモジュール指定子。 * 戻り値: {string} 指定子が解決する絶対 URL 文字列。[`import.meta.resolve`][] は、モジュールごとにスコープされたモジュール相対解決関数で、URL 文字列を返します。 ```js const dependencyAsset = import.meta.resolve('component-lib/asset.css'); // file:///app/node_modules/component-lib/asset.css import.meta.resolve('./dep.js'); // file:///app/dep.js ``` Node.js モジュール解決のすべての機能がサポートされています。依存関係の解決は、パッケージ内で許可されているエクスポートの解決に従います。 **注意**: * これにより、`require.resolve` と同様にパフォーマンスに影響を与える可能性のある同期ファイルシステム操作が発生する可能性があります。 * この機能は、カスタムローダー内では利用できません (デッドロックが発生する可能性があります)。 **非標準API**: `--experimental-import-meta-resolve` フラグを使用すると、その関数は2番目の引数を受け入れます。 * `parent` {string|URL} 解決元のオプションの絶対親モジュール URL。 **デフォルト**: `import.meta.url` ## CommonJS との相互運用性 ### `import` ステートメント `import` ステートメントは、ES モジュールまたは CommonJS モジュールを参照できます。`import` ステートメントは ES モジュールでのみ許可されていますが、動的な [`import()`][] 式は、ES モジュールをロードするために CommonJS でサポートされています。[CommonJS モジュール](#commonjs-namespaces) をインポートする場合、`module.exports` オブジェクトはデフォルトのエクスポートとして提供されます。より良いエコシステム互換性のための便宜として、静的分析によって提供される名前付きエクスポートが利用可能な場合があります。 ### `require` CommonJS モジュールの `require` は、常に参照するファイルを CommonJS として扱います。ES モジュールは非同期実行であるため、`require` を使用して ES モジュールをロードすることはサポートされていません。代わりに、[`import()`][] を使用して CommonJS モジュールから ES モジュールをロードしてください。 ### CommonJS 名前空間 CommonJS モジュールは、任意のタイプにできる `module.exports` オブジェクトで構成されます。CommonJS モジュールをインポートする場合、ES モジュールのデフォルトインポートまたは対応するシュガー構文を使用して、確実にインポートできます。```js import { default as cjs } from 'cjs'; // 次のインポートステートメントは、上記のインポートステートメントの `{ default as cjsSugar }` に対する「シンタックスシュガー」(同等だがより甘い)です: import cjsSugar from 'cjs'; console.log(cjs); console.log(cjs === cjsSugar); // Prints: //// true ``` CommonJS モジュールの ECMAScript モジュール名前空間表現は、常に CommonJS の `module.exports` 値を指す `default` エクスポートキーを持つ名前空間です。このモジュール名前空間エキゾチックオブジェクトは、`import * as m from 'cjs'` または動的インポートを使用するときに直接観察できます。```js import * as m from 'cjs'; console.log(m); console.log(m === await import('cjs')); // Prints: // [Module] { default} // true ``` JavaScriptのエコシステムにおける既存の利用法との互換性を向上させるため、Node.jsは、すべてのインポートされたCommonJSモジュールのCommonJS名前付きエクスポートを特定しようと試み、静的解析プロセスを使用して、それらを個別のESモジュールエクスポートとして提供します。例えば、次のように書かれたCommonJSモジュールを考えてみましょう。 ```cjs // cjs.cjs exports.name = 'exported'; ``` 上記のモジュールは、ESモジュールでの名前付きインポートをサポートします。```js import { name } from './cjs.cjs'; console.log(name); // Prints: 'exported' import cjs from './cjs.cjs'; console.log(cjs); // Prints: { name: 'exported' } import * as m from './cjs.cjs'; console.log(m); // Prints: [Module] { default: { name: 'exported' }, name: 'exported' } ``` 最後のモジュール名前空間エキゾチックオブジェクトのログ出力例からわかるように、`name`エクスポートは`module.exports`オブジェクトからコピーされ、モジュールがインポートされるときにESモジュール名前空間に直接設定されます。ライブバインディングの更新や、`module.exports`に追加された新しいエクスポートは、これらの名前付きエクスポートでは検出されません。名前付きエクスポートの検出は、一般的な構文パターンに基づいていますが、常に名前付きエクスポートを正しく検出できるとは限りません。そのような場合は、上記で説明したデフォルトのインポート形式を使用する方が良いでしょう。名前付きエクスポートの検出は、多くの一般的なエクスポートパターン、再エクスポートパターン、およびビルドツールやトランスパイラの出力をカバーします。実装されている正確なセマンティクスについては、[cjs-module-lexer][]を参照してください。 ### ESモジュールとCommonJSの違い #### `require`、`exports`、または`module.exports`がない ほとんどの場合、ESモジュールの`import`を使用してCommonJSモジュールをロードできます。必要な場合は、[`module.createRequire()`][]を使用して、ESモジュール内に`require`関数を構築できます。 #### `__filename`または`__dirname`がない これらのCommonJS変数は、ESモジュールでは使用できません。`__filename`と`__dirname`のユースケースは、[`import.meta.filename`][]と[`import.meta.dirname`][]を介して再現できます。 #### アドオンのロードがない [アドオン][]は、現在ESモジュールインポートではサポートされていません。代わりに、[`module.createRequire()`][]または[`process.dlopen`][]を使用してロードできます。 #### `require.resolve`がない 相対的な解決は、`new URL('./local', import.meta.url)`を介して処理できます。完全な`require.resolve`の代替としては、[import.meta.resolve][] APIがあります。あるいは、`module.createRequire()`を使用することもできます。 #### `NODE_PATH`がない `NODE_PATH`は、`import`指定子の解決の一部ではありません。この動作が必要な場合は、シンボリックリンクを使用してください。 #### `require.extensions`がない `require.extensions`は、`import`では使用されません。モジュールのカスタマイズフックで代替を提供できます。 #### `require.cache`がない `require.cache`は、ESモジュールローダーに独自の個別のキャッシュがあるため、`import`では使用されません。 ## JSONモジュール > 安定性: 1 - 実験的 JSONファイルは、`import`で参照できます。 ```js import packageConfig from './package.json' with { type: 'json' }; ``` `with { type: 'json' }`構文は必須です。[インポート属性][]を参照してください。インポートされたJSONは、`default`エクスポートのみを公開します。名前付きエクスポートのサポートはありません。重複を避けるために、CommonJSキャッシュにキャッシュエントリが作成されます。JSONモジュールが同じパスからすでにインポートされている場合、CommonJSでも同じオブジェクトが返されます。 ## Wasmモジュール > 安定性: 1 - 実験的 WebAssemblyモジュールのインポートは、`--experimental-wasm-modules`フラグの下でサポートされており、`.wasm`ファイルを通常のモジュールとしてインポートできると同時に、モジュールインポートもサポートします。この統合は、[WebAssemblyのESモジュール統合提案][]に沿ったものです。例えば、次のような内容を含む`index.mjs`があるとします。 ```js import * as M from './module.wasm'; console.log(M); ``` これは、次のコマンドで実行されます。 ```bash node --experimental-wasm-modules index.mjs ``` これにより、`module.wasm`のインスタンス化のためのエクスポートインターフェイスが提供されます。 ## トップレベル`await`The `await` keyword may be used in the top level body of an ECMAScript module. Assuming an `a.mjs` with ```js export const five = await Promise.resolve(5); ``` And a `b.mjs` with ```js import { five } from './a.mjs'; console.log(five); // Logs `5` ``` ```bash node b.mjs # works ``` If a top level `await` expression never resolves, the `node` process will exit with a `13` [status code][]. ```js import { spawn } from 'node:child_process'; import { execPath } from 'node:process'; spawn(execPath, [ '--input-type=module', '--eval', // Never-resolving Promise: 'await new Promise(() => {})', ]).once('exit', (code) => { console.log(code); // Logs `13` }); ``` ## HTTPS and HTTP imports > Stability: 1 - Experimental Importing network based modules using `https:` and `http:` is supported under the `--experimental-network-imports` flag. This allows web browser-like imports to work in Node.js with a few differences due to application stability and security concerns that are different when running in a privileged environment instead of a browser sandbox. ### Imports are limited to HTTP/1 Automatic protocol negotiation for HTTP/2 and HTTP/3 is not yet supported. ### HTTP is limited to loopback addresses `http:` is vulnerable to man-in-the-middle attacks and is not allowed to be used for addresses outside of the IPv4 address `127.0.0.0/8` (`127.0.0.1` to `127.255.255.255`) and the IPv6 address `::1`. Support for `http:` is intended to be used for local development. ### Authentication is never sent to the destination server. `Authorization`, `Cookie`, and `Proxy-Authorization` headers are not sent to the server. Avoid including user info in parts of imported URLs. A security model for safely using these on the server is being worked on. ### CORS is never checked on the destination server CORS is designed to allow a server to limit the consumers of an API to a specific set of hosts. This is not supported as it does not make sense for a server-based implementation. ### Cannot load non-network dependencies These modules cannot access other modules that are not over `http:` or `https:`. To still access local modules while avoiding the security concern, pass in references to the local dependencies: ```mjs // file.mjs import worker_threads from 'node:worker_threads'; import { configure, resize } from 'https://example.com/imagelib.mjs'; configure({ worker_threads }); ``` ```mjs // https://example.com/imagelib.mjs let worker_threads; export function configure(opts) { worker_threads = opts.worker_threads; } export function resize(img, size) { // Perform resizing in worker_thread to avoid main thread blocking } ``` ### Network-based loading is not enabled by default For now, the `--experimental-network-imports` flag is required to enable loading resources over `http:` or `https:`. In the future, a different mechanism will be used to enforce this. Opt-in is required to prevent transitive dependencies inadvertently using potentially mutable state that could affect reliability of Node.js applications. ## Loaders The former Loaders documentation is now at [Modules: Customization hooks][Module customization hooks]. ## Resolution and loading algorithm ### Features The default resolver has the following properties: * FileURL-based resolution as is used by ES modules * Relative and absolute URL resolution * No default extensions * No folder mains * Bare specifier package resolution lookup through node\_modules * Does not fail on unknown extensions or protocols * Can optionally provide a hint of the format to the loading phase The default loader has the following properties * Support for builtin module loading via `node:` URLs * Support for "inline" module loading via `data:` URLs * Support for `file:` module loading * Fails on any other URL protocol * Fails on unknown extensions for `file:` loading (supports only `.cjs`, `.js`, and `.mjs`) ### Resolution algorithm The algorithm to load an ES module specifier is given through the **ESM\_RESOLVE** method below. It returns the resolved URL for a module specifier relative to a parentURL. The resolution algorithm determines the full resolved URL for a module load, along with its suggested module format. The resolution algorithm does not determine whether the resolved URL protocol can be loaded, or whether the file extensions are permitted, instead these validations are applied by Node.js during the load phase (for example, if it was asked to load a URL that has a protocol that is not `file:`, `data:`, `node:`, or if `--experimental-network-imports` is enabled, `https:`). The algorithm also tries to determine the format of the file based on the extension (see `ESM_FILE_FORMAT` algorithm below). If it does not recognize the file extension (eg if it is not `.mjs`, `.cjs`, or `.json`), then a format of `undefined` is returned, which will throw during the load phase. The algorithm to determine the module format of a resolved URL is provided by **ESM\_FILE\_FORMAT**, which returns the unique module format for any file. The _"module"_ format is returned for an ECMAScript Module, while the _"commonjs"_ format is used to indicate loading through the legacy CommonJS loader. Additional formats such as _"addon"_ can be extended in future updates. In the following algorithms, all subroutine errors are propagated as errors of these top-level routines unless stated otherwise. _defaultConditions_ is the conditional environment name array, `["node", "import"]`. The resolver can throw the following errors: * _Invalid Module Specifier_: Module specifier is an invalid URL, package name or package subpath specifier. * _Invalid Package Configuration_: package.json configuration is invalid or contains an invalid configuration. * _Invalid Package Target_: Package exports or imports define a target module for the package that is an invalid type or string target. * _Package Path Not Exported_: Package exports do not define or permit a target subpath in the package for the given module. * _Package Import Not Defined_: Package imports do not define the specifier. * _Module Not Found_: The package or module requested does not exist. * _Unsupported Directory Import_: The resolved path corresponds to a directory, which is not a supported target for module imports. ### Resolution Algorithm Specification **ESM\_RESOLVE**(_specifier_, _parentURL_) > 1. Let _resolved_ be **undefined**. > 2. If _specifier_ is a valid URL, then > 1. Set _resolved_ to the result of parsing and reserializing > _specifier_ as a URL. > 3. Otherwise, if _specifier_ starts with _"/"_, _"./"_, or _"../"_, then > 1. Set _resolved_ to the URL resolution of _specifier_ relative to > _parentURL_. > 4. Otherwise, if _specifier_ starts with _"#"_, then > 1. Set _resolved_ to the result of > **PACKAGE\_IMPORTS\_RESOLVE**(_specifier_, > _parentURL_, _defaultConditions_). > 5. Otherwise, > 1. Note: _specifier_ is now a bare specifier. > 2. Set _resolved_ the result of > **PACKAGE\_RESOLVE**(_specifier_, _parentURL_). > 6. Let _format_ be **undefined**. > 7. If _resolved_ is a _"file:"_ URL, then > 1. If _resolved_ contains any percent encodings of _"/"_ or _"\\"_ (_"%2F"_ > and _"%5C"_ respectively), then > 1. Throw an _Invalid Module Specifier_ error. > 2. If the file at _resolved_ is a directory, then > 1. Throw an _Unsupported Directory Import_ error. > 3. If the file at _resolved_ does not exist, then > 1. Throw a _Module Not Found_ error. > 4. Set _resolved_ to the real path of _resolved_, maintaining the > same URL querystring and fragment components. > 5. Set _format_ to the result of **ESM\_FILE\_FORMAT**(_resolved_). > 8. Otherwise, > 1. Set _format_ the module format of the content type associated with the > URL _resolved_. > 9. Return _format_ and _resolved_ to the loading phase **PACKAGE\_RESOLVE**(_packageSpecifier_, _parentURL_) > 1. Let _packageName_ be **undefined**. > 2. If _packageSpecifier_ is an empty string, then > 1. Throw an _Invalid Module Specifier_ error. > 3. If _packageSpecifier_ is a Node.js builtin module name, then > 1. Return the string _"node:"_ concatenated with _packageSpecifier_. > 4. If _packageSpecifier_ does not start with _"@"_, then > 1. Set _packageName_ to the substring of _packageSpecifier_ until the first > _"/"_ separator or the end of the string. > 5. Otherwise, > 1. If _packageSpecifier_ does not contain a _"/"_ separator, then > 1. Throw an _Invalid Module Specifier_ error. > 2. Set _packageName_ to the substring of _packageSpecifier_ > until the second _"/"_ separator or the end of the string. > 6. If _packageName_ starts with _"."_ or contains _"\\"_ or _"%"_, then > 1. Throw an _Invalid Module Specifier_ error. > 7. Let _packageSubpath_ be _"."_ concatenated with the substring of > _packageSpecifier_ from the position at the length of _packageName_. > 8. If _packageSubpath_ ends in _"/"_, then > 1. Throw an _Invalid Module Specifier_ error. > 9. Let _selfUrl_ be the result of > **PACKAGE\_SELF\_RESOLVE**(_packageName_, _packageSubpath_, _parentURL_). > 10. If _selfUrl_ is not **undefined**, return _selfUrl_. > 11. While _parentURL_ is not the file system root, > 1. Let _packageURL_ be the URL resolution of _"node\_modules/"_ > concatenated with _packageSpecifier_, relative to _parentURL_. > 2. Set _parentURL_ to the parent folder URL of _parentURL_. > 3. If the folder at _packageURL_ does not exist, then > 1. Continue the next loop iteration. > 4. Let _pjson_ be the result of **READ\_PACKAGE\_JSON**(_packageURL_). > 5. If _pjson_ is not **null** and _pjson_._exports_ is not **null** or > **undefined**, then > 1. Return the result of **PACKAGE\_EXPORTS\_RESOLVE**(_packageURL_, > _packageSubpath_, _pjson.exports_, _defaultConditions_). > 6. Otherwise, if _packageSubpath_ is equal to _"."_, then > 1. If _pjson.main_ is a string, then > 1. Return the URL resolution of _main_ in _packageURL_. > 7. Otherwise, > 1. Return the URL resolution of _packageSubpath_ in _packageURL_. > 12. Throw a _Module Not Found_ error. **PACKAGE\_SELF\_RESOLVE**(_packageName_, _packageSubpath_, _parentURL_) > 1. Let _packageURL_ be the result of **LOOKUP\_PACKAGE\_SCOPE**(_parentURL_). > 2. If _packageURL_ is **null**, then > 1. Return **undefined**. > 3. Let _pjson_ be the result of **READ\_PACKAGE\_JSON**(_packageURL_). > 4. If _pjson_ is **null** or if _pjson_._exports_ is **null** or > **undefined**, then > 1. Return **undefined**. > 5. If _pjson.name_ is equal to _packageName_, then > 1. Return the result of **PACKAGE\_EXPORTS\_RESOLVE**(_packageURL_, > _packageSubpath_, _pjson.exports_, _defaultConditions_). > 6. Otherwise, return **undefined**. **PACKAGE\_EXPORTS\_RESOLVE**(_packageURL_, _subpath_, _exports_, _conditions_) > 1. If _exports_ is an Object with both a key starting with _"."_ and a key not > starting with _"."_, throw an _Invalid Package Configuration_ error. > 2. If _subpath_ is equal to _"."_, then > 1. Let _mainExport_ be **undefined**. > 2. If _exports_ is a String or Array, or an Object containing no keys > starting with _"."_, then > 1. Set _mainExport_ to _exports_. > 3. Otherwise if _exports_ is an Object containing a _"."_ property, then > 1. Set _mainExport_ to _exports_\[_"."_]. > 4. If _mainExport_ is not **undefined**, then > 1. Let _resolved_ be the result of **PACKAGE\_TARGET\_RESOLVE**( > _packageURL_, _mainExport_, **null**, **false**, _conditions_). > 2. If _resolved_ is not **null** or **undefined**, return _resolved_. > 3. Otherwise, if _exports_ is an Object and all keys of _exports_ start with > _"."_, then > 1. Assert: _subpath_ begins with _"./"_. > 2. Let _resolved_ be the result of **PACKAGE\_IMPORTS\_EXPORTS\_RESOLVE**( > _subpath_, _exports_, _packageURL_, **false**, _conditions_). > 3. If _resolved_ is not **null** or **undefined**, return _resolved_. > 4. Throw a _Package Path Not Exported_ error. **PACKAGE\_IMPORTS\_RESOLVE**(_specifier_, _parentURL_, _conditions_) > 1. Assert: _specifier_ begins with _"#"_. > 2. If _specifier_ is exactly equal to _"#"_ or starts with _"#/"_, then > 1. Throw an _Invalid Module Specifier_ error. > 3. Let _packageURL_ be the result of **LOOKUP\_PACKAGE\_SCOPE**(_parentURL_). > 4. If _packageURL_ is not **null**, then > 1. Let _pjson_ be the result of **READ\_PACKAGE\_JSON**(_packageURL_). > 2. If _pjson.imports_ is a non-null Object, then > 1. Let _resolved_ be the result of > **PACKAGE\_IMPORTS\_EXPORTS\_RESOLVE**( > _specifier_, _pjson.imports_, _packageURL_, **true**, _conditions_). > 2. If _resolved_ is not **null** or **undefined**, return _resolved_. > 5. Throw a _Package Import Not Defined_ error. **PACKAGE\_IMPORTS\_EXPORTS\_RESOLVE**(_matchKey_, _matchObj_, _packageURL_, _isImports_, _conditions_) > 1. If _matchKey_ is a key of _matchObj_ and does not contain _"\*"_, then > 1. Let _target_ be the value of _matchObj_\[_matchKey_]. > 2. Return the result of **PACKAGE\_TARGET\_RESOLVE**(_packageURL_, > _target_, **null**, _isImports_, _conditions_). > 2. Let _expansionKeys_ be the list of keys of _matchObj_ containing only a > single _"\*"_, sorted by the sorting function **PATTERN\_KEY\_COMPARE** > which orders in descending order of specificity. > 3. For each key _expansionKey_ in _expansionKeys_, do > 1. Let _patternBase_ be the substring of _expansionKey_ up to but excluding > the first _"\*"_ character. > 2. If _matchKey_ starts with but is not equal to _patternBase_, then > 1. Let _patternTrailer_ be the substring of _expansionKey_ from the > index after the first _"\*"_ character. > 2. If _patternTrailer_ has zero length, or if _matchKey_ ends with > _patternTrailer_ and the length of _matchKey_ is greater than or > equal to the length of _expansionKey_, then > 1. Let _target_ be the value of _matchObj_\[_expansionKey_]. > 2. Let _patternMatch_ be the substring of _matchKey_ starting at the > index of the length of _patternBase_ up to the length of > _matchKey_ minus the length of _patternTrailer_. > 3. Return the result of **PACKAGE\_TARGET\_RESOLVE**(_packageURL_, > _target_, _patternMatch_, _isImports_, _conditions_). > 4. Return **null**. **PATTERN\_KEY\_COMPARE**(_keyA_, _keyB_) > 1. Assert: _keyA_ ends with _"/"_ or contains only a single _"\*"_. > 2. Assert: _keyB_ ends with _"/"_ or contains only a single _"\*"_. > 3. Let _baseLengthA_ be the index of _"\*"_ in _keyA_ plus one, if _keyA_ > contains _"\*"_, or the length of _keyA_ otherwise. > 4. Let _baseLengthB_ be the index of _"\*"_ in _keyB_ plus one, if _keyB_ > contains _"\*"_, or the length of _keyB_ otherwise. > 5. If _baseLengthA_ is greater than _baseLengthB_, return -1. > 6. If _baseLengthB_ is greater than _baseLengthA_, return 1. > 7. If _keyA_ does not contain _"\*"_, return 1. > 8. If _keyB_ does not contain _"\*"_, return -1. > 9. If the length of _keyA_ is greater than the length of _keyB_, return -1. > 10. If the length of _keyB_ is greater than the length of _keyA_, return 1. > 11. Return 0. **PACKAGE\_TARGET\_RESOLVE**(_packageURL_, _target_, _patternMatch_, _isImports_, _conditions_) > 1. If _target_ is a String, then > 1. If _target_ does not start with _"./"_, then > 1. If _isImports_ is **false**, or if _target_ starts with _"../"_ or > _"/"_, or if _target_ is a valid URL, then > 1. Throw an _Invalid Package Target_ error. > 2. If _patternMatch_ is a String, then > 1. Return **PACKAGE\_RESOLVE**(_target_ with every instance of _"\*"_ > replaced by _patternMatch_, _packageURL_ + _"/"_). > 3. Return **PACKAGE\_RESOLVE**(_target_, _packageURL_ + _"/"_). > 2. If _target_ split on _"/"_ or _"\\"_ contains any _""_, _"."_, _".."_, > or _"node\_modules"_ segments after the first _"."_ segment, case > insensitive and including percent encoded variants, throw an _Invalid > Package Target_ error. > 3. Let _resolvedTarget_ be the URL resolution of the concatenation of > _packageURL_ and _target_. > 4. Assert: _packageURL_ is contained in _resolvedTarget_. > 5. If _patternMatch_ is **null**, then > 1. Return _resolvedTarget_. > 6. If _patternMatch_ split on _"/"_ or _"\\"_ contains any _""_, _"."_, > _".."_, or _"node\_modules"_ segments, case insensitive and including > percent encoded variants, throw an _Invalid Module Specifier_ error. > 7. Return the URL resolution of _resolvedTarget_ with every instance of > _"\*"_ replaced with _patternMatch_. > 2. Otherwise, if _target_ is a non-null Object, then > 1. If _target_ contains any index property keys, as defined in ECMA-262 > [6.1.7 Array Index][], throw an _Invalid Package Configuration_ error. > 2. For each property _p_ of _target_, in object insertion order as, > 1. If _p_ equals _"default"_ or _conditions_ contains an entry for _p_, > then > 1. Let _targetValue_ be the value of the _p_ property in _target_. > 2. Let _resolved_ be the result of **PACKAGE\_TARGET\_RESOLVE**( > _packageURL_, _targetValue_, _patternMatch_, _isImports_, > _conditions_). > 3. If _resolved_ is equal to **undefined**, continue the loop. > 4. Return _resolved_. > 3. Return **undefined**. > 3. Otherwise, if _target_ is an Array, then > 1. If \_target.length is zero, return **null**. > 2. For each item _targetValue_ in _target_, do > 1. Let _resolved_ be the result of **PACKAGE\_TARGET\_RESOLVE**( > _packageURL_, _targetValue_, _patternMatch_, _isImports_, > _conditions_), continuing the loop on any _Invalid Package Target_ > error. > 2. If _resolved_ is **undefined**, continue the loop. > 3. Return _resolved_. > 3. Return or throw the last fallback resolution **null** return or error. > 4. Otherwise, if _target_ is _null_, return **null**. > 5. Otherwise throw an _Invalid Package Target_ error. **ESM\_FILE\_FORMAT**(_url_) > 1. Assert: _url_ corresponds to an existing file. > 2. If _url_ ends in _".mjs"_, then > 1. Return _"module"_. > 3. If _url_ ends in _".cjs"_, then > 1. Return _"commonjs"_. > 4. If _url_ ends in _".json"_, then > 1. Return _"json"_. > 5. If `--experimental-wasm-modules` is enabled and _url_ ends in > _".wasm"_, then > 1. Return _"wasm"_. > 6. Let _packageURL_ be the result of **LOOKUP\_PACKAGE\_SCOPE**(_url_). > 7. Let _pjson_ be the result of **READ\_PACKAGE\_JSON**(_packageURL_). > 8. Let _packageType_ be **null**. > 9. If _pjson?.type_ is _"module"_ or _"commonjs"_, then > 1. Set _packageType_ to _pjson.type_. > 10. If _url_ ends in _".js"_, then > 1. If _packageType_ is not **null**, then > 1. Return _packageType_. > 2. If `--experimental-detect-module` is enabled and the source of > module contains static import or export syntax, then > 1. Return _"module"_. > 3. Return _"commonjs"_. > 11. If _url_ does not have any extension, then > 1. If _packageType_ is _"module"_ and `--experimental-wasm-modules` is > enabled and the file at _url_ contains the header for a WebAssembly > module, then > 1. Return _"wasm"_. > 2. If _packageType_ is not **null**, then > 1. Return _packageType_. > 3. If `--experimental-detect-module` is enabled and the source of > module contains static import or export syntax, then > 1. Return _"module"_. > 4. Return _"commonjs"_. > 12. Return **undefined** (will throw during load phase). **LOOKUP\_PACKAGE\_SCOPE**(_url_) > 1. Let _scopeURL_ be _url_. > 2. While _scopeURL_ is not the file system root, > 1. Set _scopeURL_ to the parent URL of _scopeURL_. > 2. If _scopeURL_ ends in a _"node\_modules"_ path segment, return **null**. > 3. Let _pjsonURL_ be the resolution of _"package.json"_ within > _scopeURL_. > 4. if the file at _pjsonURL_ exists, then > 1. Return _scopeURL_. > 3. Return **null**. **READ\_PACKAGE\_JSON**(_packageURL_) > 1. Let _pjsonURL_ be the resolution of _"package.json"_ within _packageURL_. > 2. If the file at _pjsonURL_ does not exist, then > 1. Return **null**. > 3. If the file at _packageURL_ does not parse as valid JSON, then > 1. Throw an _Invalid Package Configuration_ error. > 4. Return the parsed JSON source of the file at _pjsonURL_. ### Customizing ESM specifier resolution algorithm [Module customization hooks][] provide a mechanism for customizing the ESM specifier resolution algorithm. An example that provides CommonJS-style resolution for ESM specifiers is [commonjs-extension-resolution-loader][].[6.1.7 配列インデックス]: https://tc39.es/ecma262/#integer-index [アドオン]: addons.md [CommonJS]: modules.md [コアモジュール]: modules.md#core-modules [モジュールシステムの決定]: packages.md#determining-module-system [動的`import()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import [WebAssemblyのESモジュール統合提案]: https://github.com/webassembly/esm-integration [インポート属性]: #import-attributes [インポート属性提案]: https://github.com/tc39/proposal-import-attributes [JSONモジュール]: #json-modules [モジュールカスタマイズフック]: module.md#customization-hooks [Node.jsモジュール解決とローディングアルゴリズム]: #resolution-algorithm-specification [用語]: #terminology [URL]: https://url.spec.whatwg.org/ [`"exports"`]: packages.md#exports [`"type"`]: packages.md#type [`--experimental-default-type`]: cli.md#--experimental-default-typetype [`--input-type`]: cli.md#--input-typetype [`data:` URL]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs [`export`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export [`import()`]: #import-expressions [`import.meta.dirname`]: #importmetadirname [`import.meta.filename`]: #importmetafilename [`import.meta.resolve`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import.meta/resolve [`import.meta.url`]: #importmetaurl [`import`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import [`module.createRequire()`]: module.md#modulecreaterequirefilename [`module.syncBuiltinESMExports()`]: module.md#modulesyncbuiltinesmexports [`package.json`]: packages.md#nodejs-packagejson-field-definitions [`path.dirname()`]: path.md#pathdirnamepath [`process.dlopen`]: process.md#processdlopenmodule-filename-flags [`url.fileURLToPath()`]: url.md#urlfileurltopathurl [cjs-module-lexer]: https://github.com/nodejs/cjs-module-lexer/tree/1.2.2 [commonjs-extension-resolution-loader]: https://github.com/nodejs/loaders-test/tree/main/commonjs-extension-resolution-loader [カスタムhttpsローダー]: module.md#import-from-https [import.meta.resolve]: #importmetaresolvespecifier [パーセントエンコード]: url.md#percent-encoding-in-urls [特別なスキーム]: https://url.spec.whatwg.org/#special-scheme [ステータスコード]: process.md#exit-codes [公式標準フォーマット]: https://tc39.github.io/ecma262/#sec-modules [url.pathToFileURL]: url.md#urlpathtofileurlpath