1. 導入:なぜnpm/pnpm linkが必要なのか
ライブラリや共通コンポーネントを開発する際、修正のたびにビルドしてレジストリへ公開(npm publish)し、利用側プロジェクトでインストールし直すのは非常に非効率です。この「ビルド・公開・再インストール」のループは開発速度を著しく低下させます。npm linkやpnpm linkを使用すれば、ローカル上のディレクトリをシンボリックリンクとして直接参照できるため、ライブラリ側の変更を即座に利用側で反映・検証可能です。共通基盤開発においては必須のテクニックです。
2. 基礎知識:シンボリックリンクの仕組み
これらは、OSの機能である「シンボリックリンク」を利用しています。通常、node_modules内のパッケージは実体を持ちますが、linkを使うことで、指定したライブラリの実体ディレクトリをnode_modules内に「ショートカット」として配置します。これにより、Node.jsのモジュール解決アルゴリズムを騙し、あたかもインストール済みのパッケージであるかのように振る舞わせます。
3. 実装/解決策:具体的な手順
開発フローは以下の2ステップです。
1. ライブラリ側でリンクを作成:ライブラリのディレクトリでコマンドを実行し、グローバル領域(またはpnpmのストア)にリンクを登録します。
2. 利用側プロジェクトでリンクを接続:利用側プロジェクトで特定のパッケージ名に対してリンクを紐付けます。
4. サンプルプログラム:実践的なセットアップ例
以下は、`my-ui-library`を`my-web-app`で利用する場合の手順です。
ライブラリ側 (my-ui-library)
[ディレクトリ: /path/to/my-ui-library]
1. ローカルでのリンク登録
npm link
またはpnpmの場合(より安全で推奨)
pnpm link –global
利用側プロジェクト (my-web-app)
[ディレクトリ: /path/to/my-web-app]
2. リンクをインストール(パッケージ名を指定)
npm link my-ui-library
またはpnpmの場合
pnpm link –global my-ui-library
動作確認用のコード (利用側)
// src/index.js
// リンクが成功していれば、通常のパッケージと同様にインポート可能
import { sampleFunction } from ‘my-ui-library’;
// 実際にライブラリのコードを書き換えた後、
// 利用側でビルドツールが自動検知してホットリロードされることを確認してください
console.log(sampleFunction());
5. 応用・注意点:現場で陥りやすい罠
実務で利用する際に気をつけるべきポイントは以下の通りです。
・Reactなどのシングルトン問題
Reactやstyled-componentsなど、インスタンスが複数存在するとエラーになるライブラリでは、npm linkを使うと「ライブラリ側のReact」と「利用側のReact」が重複し、予期せぬエラー(Invalid hook callなど)が発生することがあります。その場合は、ライブラリ側のnode_modulesを削除するか、ビルド時にライブラリ側をpeerDependenciesとして適切に扱う設定が必要です。
・pnpmの利点
npm linkはグローバル領域を汚染しやすいため、可能な限りpnpm linkを使用することを推奨します。pnpmはハードリンクとシンボリックリンクを巧妙に管理するため、npm linkよりも依存関係の解決が安定しており、プロジェクトごとに隔離された環境を維持しやすいです。
・後片付けを忘れずに
開発が終わったら、`npm unlink`でリンクを解除しましょう。そのまま放置すると、他のプロジェクトで誤って古いバージョンのライブラリを参照し続ける原因となり、デバッグの迷宮入りを招くことになります。

コメント