追記: [email protected]で別のパッケージを特定のパッケージ名で指定できるpackage aliasesが追加されました。


注意: この手法はnpm ciで壊れてる場合があります


Add support for ESLint v2 by Daniel15 · Pull Request #107 · fkling/astexplorerを見ていて、一つのプロジェクト内で複数のバージョンの同じライブラリを使う面白い方法が使われてたのでメモです。

前述したAST explorerの場合だと、ESLint@1とESLint@2の両方に対応したPlaygroundを作りたいため、一つのプロジェクトに両方のバージョンをインストールする必要があるという話です。

他にも、同じライブラリでもβ版は別の名前空間(require("other-name-space"))で使って試したいというケースもあると思います。

ブラウザだとちょっとファイルサイズ的に避けたい気がしますが、jQuery@1jquery@3を混在させて使うプロジェクトとかにも応用できそうな気がします。

やり方

サンプルプロジェクトは以下においてあります。

このプロジェクトのゴールはlodash@3lodash@4を同時にひとつのプロジェクトで使うことです(実用性は置いておきます)

1. それぞれのバージョンのローカルパッケージを作る

npm@2 からはLocal Pathsを依存関係として定義することができます。

簡単にいうと、相対パスで指定したディレクトリをモジュールとしてdependenciesに追加できる機能です。

これを使って、lodash@3lodash@4のローカルパッケージを作ります。

サンプルプロジェクトを見るのが分かりやすいですが、lodash3lodash4というディレクトリを手動で作って、それぞれnpm initしてmainindex.jsを指定しただけのモジュールです。

packages
├── lodash3
│   ├── index.js
│   └── package.json
└── lodash4
    ├── index.js
    └── package.json

index.jsには以下のようにlodashをexportしているだけです。

// lodash@3
module.exports = require("lodash");

lodash3のモジュールでrequire("lodash")したのはpackages/lodash3/package.jsonで依存関係に定義されているlodashなので、lodash@3がexportされているという事になります。

{
  "name": "lodash3",
  "version": "1.0.0",
  "description": "lodash@3",
  "main": "index.js",
  "author": "azu",
  "license": "MIT",
  "dependencies": {
    "lodash": "^3.0.0"
  }
}

2. ローカルパッケージをインストールする

後は、プロジェクトにローカルパッケージとして作ったlodash3lodash4への依存を定義するだけです。

npm i -S packages/lodash3 packages/lodash4

でインストールできます。 npmのバージョンによってnpm i -Sでちゃんと相対パスにならないバグがありますが、直接以下のように書けば同じ結果が得られます。

  "dependencies": {
    "lodash3": "file:packages/lodash3",
    "lodash4": "file:packages/lodash4"
  }

3. それぞれのバージョンを使う

後は、プロジェクトからrequire("lodash3")のような感じでrequireして使うだけです。

"use strict";
var assert = require("assert");
var lodash3 = require("lodash3");
var lodash4 = require("lodash4");

assert(lodash3.VERSION.includes("3"));
assert(lodash4.VERSION.includes("4"));

lodashには.VERSIONにバージョン番号が入ってるので、それぞれ@3と@4のバージョンが読み込めてることが確認できます。

おわり

ローカルパッケージを使って、一つのプロジェクト内で複数バージョンのnpmパッケージを使い分ける方法を紹介しました。

astexplorerみたいなツール系だと結構実用的なユースケースだと思います。 普通のウェブサイトとかプロダクトなら、最新のバージョン使おうねって感じです。 (ワークアラウンドとして覚えておくと便利なことがあるかもしれないという感じです)

他にも過去のバージョンとのパフォーマンス比較ポイントを作ったりなどの色々使い道があるかもしれません。