音の鳴るブログ

鳴らないこともある

内部モジュールを依存順に並べる

内部モジュールを依存順に並べる node.js のモジュールを作りました。

たとえば以下のようなファイル構成のとき、

  +---------+
  | main.js |
  +---------+
    | require
    V
  +---------+    +---------+
  | foo.js  | -> | baz.js  |
  +---------+    +---------+
    |               |    ^
    |     +---------+    |
    |     |              |
    V     V              |
  +---------+    +---------+
  | bar.js  |    | qux.js  |
  +---------+    +---------+

main.js から見た依存関係で並び替えると以下のようになります。下にあるモジュールは上にあるモジュールに依存しているといった按配です。

[ 
  "path/to/bar.js", 
  "path/to/baz.js", 
  "path/to/foo.js", 
  "path/to/main.js" 
]

そういうことをしてくれます。

仕組み

ソースファイルから require 式を抽出してグラフをつくってトポロジカルソートしています。

  • esprima ソースファイルをASTにして
  • estraverse require式を抽出、
  • toposort トポロジカルソートをする

require("./path/to/module") のように文字リテラルで指定してる部分のみ対応していて、require("module-name") のような外部モジュールや require(filepath) のように文字リテラル以外で読み込んでいる場合は無視しています。

使いどころ

結構あると思うのだけど、個人的には以前に書いたこの記事、

大雑把に説明すると(リンク先を読んでも大雑把だけど)

  • モジュール化した JavaScript をブラウザ向けにビルドするとき
  • 各モジュールの依存順で並べて単純に結合すると簡単
  • require で名前空間の拡張だけして結果を代入しなければその行ごと削除できる

こういうケースで使えます。