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

Node.js module管理の仕組み

$
0
0

Node.jsデザインパターンを読んで勉強中なので
そちらの備忘録として投稿していきます。

まず初めにNode.jsがどうやって異なるバージョンの同一モジュールを管理し、
「依存地獄(dependency hell)」を回避しているかを整理します。

Node.jsの依存解決アルゴリズム

Node.jsがモジュールを読み込む時に
指定されたモジュール名をもとにモジュールをコアモジュール、もしくはローカルファイル
から探すために使用されるアルゴリズムは
以下の三段階に分かれている。

  1. コアモジュール
    まずは指定されたモジュール名がNodeのコアモジュールかどうか調べる

  2. ファイルモジュール
    コアモジュールに見つからなかった場合、ローカルファイルシステムを探す。
    モジュール名が「/」で始まる場合は絶対パスとして、「./」、「../」で始まる場合は
    requireを呼び出しているファイ ルからの相対パスとして解釈される。

  3. パッケージモジュール
    モジュール名の開始文字列が「/」、「./」、「../」のいずれでもない場合は、
    requireを呼び出しているファイルと同じディレクトリの下にあるnode_modulesディレクトリの中を探す。

それでも見つからない、もしくはnode_modulesディレクトリがなかった場合
さらに親のディレクトリを探しにいき、上へ上へ探索していき
ローカルファイルシステムのルートに到達するまで探す。

ファイルモジュールとパッケージモジュールのロード時のルール

ファイルモジュールとパッケージモジュールのロード時には
上記のアルゴリズム以外にルールがある。

  • 指定されたモジュール名と同じ名前のファイルがあれば (なければ拡張子.jsもしくは.jsonを補完して確認) そのファイルをロードする。
  • 指定されたモジュール名と同じ名前のディレクトリがあれば、その配下にpackage.jsonファイルがないか調べる。 存在すれば、ファイル中のmainプロパティで指定されたファイルをロードする。
  • 指定されたモジュール名ディレクトリ配下にindex.jsというファイルがあればロードする。

整理

myApp/
├── foo.js
└─┬ node_modules
├── depA
|└── index.js
├── depB
├── bar.js
└── node_modules
└── depA
└── index.js
└── depC
├── foobar.js
└── node_modules
└── depA
└── index.js
上記のようなディレクトリ構成として
各ファイルからモジュールdepAをロードしてみる。

  • /myApp/foo.jsからrequire('depA')を呼び出した場合
    /myApp/node_modules/depA/index.jsをロードする

  • /myApp/node_modules/depB/bar.jsからrequire('depA')を呼び出した場合
    /myApp/node_modules/depB/node_modules/depA/index.jsをロードする

  • /myApp/node_modules/depC/foobar.jsからrequire('depA')を呼び出した場合
    /myApp/node_modules/depC/node_modules/depA/index.jsをロードする

まとめ

依存解決アルゴリズムにより、Nodeは複雑な依存関係も解決でき、
ひいては大規模なアプリケーションにおいて、
バージョン間の衝突なく何百、何千といった依存パッケージをもつことが可能になる

参考書籍
Node.jsデザインパターン 第2版


Viewing all articles
Browse latest Browse all 8862

Trending Articles