Node.js で相対パス地獄(../../../../)を絶対パスっぽく解決させる

いつもつらい思いをしていたけどそこまでクリティカルじゃなかったから見て見ぬ振りをしてきたけどそろそろ不味くなってきたので解決策はないかと探してみたら結構良さそうなのを見つけたのでメモ。

npm module 編

$ tree src
src
├── lib
│   └── dep1
│       └── dep2
│           └── dep3
│               └── dep4
│                   └── dep5
│                       └── index.js
└── pages
    └── dep1
        └── dep2
            └── dep3
                └── dep4
                    └── dep5
                        └── index.js
// src/pages/dep1/dep2/dep3/dep4/dep5/index.js
import hey from "../../../../../../lib/dep1/dep2/dep3/dep4/dep5";
import hey from "heyapp/lib/dep1/dep2/dep3/dep4/dep5";

下記 npm module を使う https://github.com/Rush/link-module-alias

$ npm i -D link-module-alias
{
  "_moduleAliases": {
    "heyapp": "src"
  }
}
$ link-module-alias
import hey from "heyapp/lib/dep1/dep2/dep3/dep4/dep5";

仕組みとしては、node_modules の下に dir を切って、指定された path に対して fs.symlink で シンボリックリンクを張っているだけっぽい。

万が一競合していたら error 吐いてくれたりしそうなのでそんなに危険じゃなさそう。

https://github.com/Rush/link-module-alias/blob/master/index.js#L187

node_modules 配下を多少なりとも荒らすので、postinstall にこいつをフックさせるようにと READEME に書かれているので従っておこう。

{
  "scripts": {
    "postinstall": "link-module-alias"
  }
}

使い方次第では結構便利な感じになりそうなので良さそう

{
  "_moduleAliases": {
    "heyapp": "src",
    "heyapp:lib": "otherdir/some/lib",
    "heyapp:test": "__test__"
  }
}