Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9360

Node.jsのモジュール解決プロセス(和訳)

$
0
0

Node.jsのrequireがどのようにモジュールを探すか、そのプロセスを説明した下記公式ドキュメントの和訳です。

内容に誤りがあればお教えください。

Node.jsのモジュール解決プロセス

require(X) をパス Y にあるモジュールで実行したとき、

  1. もし、 X がコアモジュールなら、
    • a. コアモジュールを返す
    • b. 終了
  2. もし、 X が "/" で始まるなら、
    • a. Y のパスをファイルシステムルートにセットしなおす
  3. もし、 X が "./"、"/"、"../"のどれかで始まるなら、
  4. LOAD_SELF_REFERENCE(X, dirname(Y))
  5. LOAD_NODE_MODULES(X, dirname(Y))
  6. 例外"not found"を投げる

LOAD_AS_FILE(X)

  1. もし、 X がファイルなら、 X をそのファイル拡張子の形式としてロードする。 終了
  2. もし、 X.js がファイルなら、 X.js をJavaScriptテキストとしてロードする。 終了
  3. もし、 X.json がファイルなら、 X.json をパースしてJavaScriptオブジェクトにする。 終了
  4. もし、 X.node がファイルなら、 X.node をバイナリアドオンとしてロードする。 終了

LOAD_INDEX(X)

  1. もし、 X/index.js がファイルなら、 X/index.js をJavaScriptテキストとしてロードする。 終了
  2. もし、 X/index.json がファイルなら、 X/index.json をパースしてJavaScriptオブジェクトにする。 終了
  3. もし、 X/index.node がファイルなら、 X/index.node をバイナリアドオンとしてロードする。 終了

LOAD_AS_DIRECTORY(X)

  1. もし、 X/package.json がファイルなら、
    • a. X/package.json をパースして、mainフィールドを探す。
    • b. もし、mainがfalsyな値なら、2に進む
    • c. let M = X + main
    • d. LOAD_AS_FILE(M)
    • e. LOAD_INDEX(M)
    • f. LOAD_INDEX(X) 非推奨
    • g. 例外"not found"を投げる
  2. LOAD_INDEX(X)

LOAD_NODE_MODULES(X, START)

  1. let DIRS = NODE_MODULES_PATHS(START)
  2. for each DIR in DIRS:

NODE_MODULES_PATHS(START)

1.letPARTS=pathsplit(START)2.letI=countofPARTS-13.letDIRS=[GLOBAL_FOLDERS]4.whileI>=0,a.ifPARTS[I]="node_modules"CONTINUEb.DIR=pathjoin(PARTS[0..I]+"node_modules")c.DIRS=DIRS+DIRd.letI=I-15.returnDIRS

これは、NODE_MODULES_PATHS('/root/a/b/c')を与えたときに、下記のリストを返す処理です。

['$HOME/.node_modules','$HOME/.node_libraries','$PREFIX/lib/node','/root/a/b/c/node_modules','/root/a/b/node_modules','/root/a/node_modules','/root/node_modules','/node_modules',]

LOAD_SELF_REFERENCE(X, START)

  1. STARTに最も近いパッケージのスコープを探す。
  2. もし、スコープが見つからなければ、return。
  3. もし、package.jsonに"exports"がなければ、return。
  4. もし、package.jsonの name が X で始まらないなら、"not found"例外を投げる。
  5. それ以外の場合は、このパッケージに相対的な X の残りの部分を、package.jsonのnameでLOAD_NODE_MODULESを介してロードされたかのようにロードする。

LOAD_PACKAGE_EXPORTS(DIR, X)

このプロセスは右記の規格に対応するものです→jkrems/proposal-pkg-exports: Proposal for Bare Module Specifier Resolution in node.js

  1. X を名前とサブパスの組み合わせとしての解釈を試みる。その名前は @scopeにスラッシュ(/)で始まるサブパスが続く形式を想定する。
  2. もし、 X このパターンにマッチしない、もしくは、DIR/名前/package.jsonがファイルでないなら、return。
  3. DIR/name/package.json をパースして、 "exports" フィールドを探す。
  4. もし、 "exports" が null か undefined なら、return。
  5. もし、 "exports" が object での場合、"." 始まりのキーがありつつ "." 始まりでないキーもあるなら、"invalid config"例外を投げる。
  6. もし、 "exports" が string または "." 始まりのキーが1つもない object なら、それの値を "." として扱う。
  7. もし、 サブパスが "." で "exports" が "." エントリーを持たないなら、return
  8. "exports" の中からサブパスで始まる最も長いキーを探す。
  9. もし、キーが見つからないなら、 "not found" 例外を投げる。
  10. let RESOLVED = fileURLToPath(PACKAGE_EXPORTS_TARGET_RESOLVE(pathToFileURL(DIR/name), exports[key], subpath.slice(key.length), ["node", "require"])) (これはESMリゾルバーで定義されたもの)
  11. もしキーが "/" で終わるなら:
  12. それ以外の場合は、
    • a. もし RESOLVED がファイルなら、そのファイル拡張子フォーマットでロードする。 終了
  13. "not found"例外を投げる

Viewing all articles
Browse latest Browse all 9360

Trending Articles