【Node.jsお役立ちツール紹介】link-module-aliasで快適なモジュールリンクパスのエイリアスを付ける


2020/11/15

Node.jsを利用したブロジェクトでリソースファイルが多くなってきて、フォルダ分け+深い階層化してくると、npmモジュールのインポートの際の
相対パス地獄が問題になってきます。

そんなお悩みを解決してくれるかもしれない
link-module-aliasユーティリティを簡単に解説してみます。


相対パス地獄とは

nodejsを利用したプロジェクト開発が進んでくる段階で、相対パス地獄はふとした時に遭遇してしまいます。

例えば単体テストをソースファイルとは別に、
testフォルダに分けているとして、以下のようなプロジェクトフォルダ構造になってたとしますと、

            
            $ tree
.
├── index.ts
├── src
│   ├── a.ts
│   └── lib
│       ├── a.lib.ts
│       └── model
│           ├── a.model.ts
│           └── base
│                └── a.base.ts
└── test
    ├── index.spec.ts
    └── src
        ├── a.spec.ts
        └── lib
            ├── a.lib.spec.ts
            └── model
                ├── a.model.spec.ts
                └── base
                    └── a.base.spec.ts
        
このプロジェクトの一番深い階層に位置しているa.base.spec.tsのテストを行いたい際に、リソースフォルダにあるa.base.tsの中身をインポートする際には以下のようになると思います。

            
            import {
    hoge,
    piyo,
    fuga
} from '../../../../../src/lib/model/base/a.base';
//...以下略
        
インポートする側のファイルと、エクスポートする側のファイルの階層間距離が遠ければ遠いほど、この相対パスの記述が長々となってしまうのが、nodejsプログラマーが一度は出くわすであろう相対パス地獄問題になります。

VSコードのような高機能エディタにはIntelliSense機能からオートコンプリートでインポートしたいファイルの相対パスを確認できるので、通常この問題も見逃されがちですが、コードの可読性という点ではやはり生産性の高いやり方とは言えません。

そこでもっとより良い相対パスの呼び出し方を提供してくれるライブラリの出番となります。


相対パスをエイリアス化できるユーティリティ・link-module-alias

今回紹介するのはlink-module-aliasという相対パスを独自にエイリアス化してくれるライブラリです。

同列のユーティリティでほぼ同じ機能となる
module-aliasというプロジェクトでも相対パスをエイリアス化できます。

link-module-aliasを使う大きなメリットとして、ビルド前にプロジェクトの全てのモジュールへの静的シンボリックリンクをして、あたかも
node_modulesの中にあるライブラリのように扱えるようになることが特徴です。

module-aliasではソースコード中にrequireしなければならなかったため、パッケージの読み込みが少し技巧的だったのに対し、
link-module-aliasは事前にリンボリックリンクを生成しておけばそういったコーディングの煩わしさから解放してくれます。

ただしまだバグが多い印象で、定期的に問題が報告されていますので、挙動が不安定になったらgithubプロジェクトのissueのページを覗いてみる良いと思います。

前置きはさておき、link-module-aliasをプロジェクトに導入してみます。

なおパッケージマネージャは
yarnにしています。

            
            $ yarn add link-module-alias -D
        
これだけで準備完了です。

パッケージをインストールしただけでは何も起こらないので、次にシンボリックリンクを作成します。

プロジェクトのpackage.jsonを以下のように追加・修正します。

            
            {
    //...中略
    "scripts": {
        //...中略
        //👇postinstallというスクリプトにlink-module-aliasコマンドを指定
        "postinstall": "link-module-alias",
        //...中略
    },
    "_moduleAliases": {
        "~src": "src",
        "~lib": "src/lib",
        "~model": "src/lib/model",
        "~base": "src/lib/model/base"
    }
//以下略
        
package.jsonへ追加する項目もとてもシンプルで、パッケージインストール後に走るpostinstallへlink-module-aliasを登録することで、以降はnpm installyarn installの後に自動でシンボリックリンクが作られます。

_moduleAliasesフィールドがプロジェクトの中で独自に相対パスとして設定したいエイリアスになります。

エイリアスの命名ルールなどは整理されていないのでかなり自由度が高いです。

もともとサードパーティ製のライブラリで利用されていることの多い
@から始まるエイリアス名と被りやすいこともあり、エイリアス名が内部で衝突すると意図としない不具合も出るようです。

もちろん
@のプレフィックスの利用は非推奨ではないのですが、紛らわしい問題を避けるため、~#などの文字を使うのが現時点でベターです。

では
_moduleAliasesで定義した相対パスのエイリアスをお好みにカスタマイズしたら、以下でシンボリックリンクを吐き出すことが出来ます。

            
            $ yarn postinstall
#👇もしくはlink-module-aliasコマンドを直接呼び出す
#$ ./node_modules/.bin/link-module-alias
link-module-alias: ~src -> src, ~lib -> src/lib, ~model -> src/lib/model, ~base -> src/lib/model/base
        
するとnode_modulesフォルダ内に~src, ~lib, ~model, ~baseフォルダが作成され依存性のあるリソースごとにシンボリックリンクが貼られている状態になっていると思います。

早速このエイリアスを利用してインポートをこころみると、先程のソースコードは以下のように短く簡潔に呼び出せるようになります。

            
            import { hoge, piyo, fuga } from '~base/a.base';
//...以下略
        

まとめ

link-module-aliasは、プロジェクトへの導入が早ければ早いほど効果的なプロジェクトの管理に一役買う便利なユーティリティです。

先んじて開発初期からインストールしておくことで、ライブラリの在処をあれこれ気にする必要のない効率的なプロジェクト管理環境構築が可能となります。


参考サイト

Aliasing module paths in Node JS

記事を書いた人

記事の担当:taconocat

ナンデモ系エンジニア

主にAngularでフロントエンド開発することが多いです。 開発環境はLinuxメインで進めているので、シェルコマンドも多用しております。 コツコツとプログラミングするのが好きな人間です。