npm 2.0.0でローカルモジュールを使ってrequire('../../../')を回避する
概要
npm 1.xの時はローカルにあるディレクトリへの相対パスをdependencyフィールドで指定できなかった。
そのため、ローカルにあるモジュールをたどるにはrequire("../../../")のような指定が必要になっていた(ライブラリに切り出せればいいけど、アプリケーション固有のUtilsなどがある場合これ面倒になる)
- Better local require() paths for Node.js
- avoiding ../../../../../../..
- How I Work Around The require(“../../../../../../../”) Problem In NodeJS | ThoughtStream.new :derick_bailey
そのため、npm linkやnode_modulesにそのまま追加してやるなど、微妙なハックがひつようだった。
しかし、npm 2.0.0でdependencyフィールドにLocal Pathsの指定がサポートされた。
そのため、ローカルに置いたディレクトリをモジュールとして使うことができ、require("local-library");みたいな書き方が可能になる。
要はプロジェクトに依存したUtilsとかを定義するのに便利という話。
ローカルモジュールの作成
今回のサンプルプロジェクトは以下においてあります。
ローカルモジュールの作り方は普通にnpmで公開するモジュールと全く同じです。
今回は、example-utilsというローカルのモジュールを作成しました。
- example-utils.js
- package.json
があるだけのシンプルなディレクトリをローカルに作ります。
相対パスで参照するので、プロジェクト内にlocal_modulesのような場所を作って置くのが、
シンプルな方法だと思います。
example-utils.js の中身は普通のnode moduleのコードです。
この例だとfsモジュールをラップしただけのシンプルなコードです。
var Utils = {};
Utils.loadFile = function (filePath) {
    return require("fs").readFileSync(filePath, "utf-8");
};
module.exports = Utils;
package.jsonの中身も普通のモジュールと同じですが、npm publishする予定は無いので、
"repository"フィールドを外して、"private": trueというフィールドをつけておくといいです。
{
  "name": "example-utils",
  "version": "1.0.1",
  "description": "local module",
  "main": "example-utils.js",
  "private": true,
  "author": "azu",
  "license": "MIT"
}
こうすることでインストールする時以下のような警告がでなくなります。
No repository field.
ローカルモジュールの使い方
作ったローカルモジュールは普通にnpmでインストールすることが出来ます。
npm install --save local_modules/example-utils
でインストール出来ます。
mainのpackage.jsonに以下のように追加されていればOKですね。
  "dependencies": {
    "example-utils": "file:local_modules/example-utils"
  }
後は、普通にrequire("example-utils")という感じで参照することが出来ます。
"use strict";
var main = {};
main.help = function () {
    var message = require("example-utils").loadFile(__filename + ".txt");
    console.log(message);
};
module.exports = main;
ローカルモジュールの注意点
ローカルモジュールはnpm installをするとnode_modulesにコピーされます。
そのため、ローカルモジュールを更新した場合は自動では反映されません。
ローカルモジュールのバージョンを書き換えて、npm installし直す必要があります。
後、名前の衝突が起きるかもしれないので、分かりやすいprefixをつけるといいのかもしれません。
ローカルモジュールの利点
ローカルモジュールを使うことで、
require('../../../utils/log.js'); のような相対パスを辿る必要がなくなります。
特にUtils系のコードは色んな所で参照するため、ローカルモジュールを使うとかなり楽になります。
デメリットとしては更新したらもう一度installしないといけないので、忘れていてハマる可能性があること。
npm 2.0.0からこのLocal Pathsが指定できるようになったので、 積極的に使っていきたい気がします。
お知らせ欄
JavaScript Primerの書籍版がAmazonで購入できます。
JavaScriptに関する最新情報は週一でJSer.infoを更新しています。
GitHub Sponsorsでの支援を募集しています。
 
