LoginSignup
0
0

More than 3 years have passed since last update.

Node.js module管理の仕組み

Posted at

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版

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0