LoginSignup
39
38

More than 5 years have passed since last update.

npm v3.x 試してみた & 注意する点

Last updated at Posted at 2015-07-14

ふと思い立って npm install -g npm@3 した。3.1.2 は VERY BETA とのこと(ニュアンスがよくわからん。アルファとの対比なのか、アルファ相当なのか) ので、そのうち出るでしょう。

node_modulesのフラットな展開

npm@3 だとnode_modulesの依存がパッケージ間のバージョンが衝突しない限り、トップレベルのnode_modulesにフラットに展開される。これによって同一のモジュールを依存ツリー間でモジュールが重複した時にnode_modules以下のサイズが膨らむのを抑えることができる。

衝突した場合はそのモジュールの子のnode_modulesに格納されて衝突は回避される。

気になるrequireの仕様

とはいえ、requireの仕様が変わってるわけじゃないので、トップレベルから子だけじゃなく孫モジュールも直接requireできてしまう。手元でたとえば a -> b な依存のときに、今までは require('b') できなかったのができるようになる。

これはある時点でrequireできたモジュールが何の依存だったのかあとでわからないという、将来的に禍根になる可能性があるケースがあるのではないか。怖い。

壊れるケース

気にしないといけないのが一点。

子と孫で同じバージョンの場合はrequireキャッシュに引っかかって同一参照になる。依存自身からみた場合に子が孫をシングルトンだと想定してグローバルオプションをセットしている場合npm3にしたことで壊れる。

ちょうどmarkedが判りやすく壊れそうだったので、例に出す。

gfm-marked/gfm-marked.js

var marked = require('marked');
marked.setOptions({
  renderer: new marked.Renderer(),
  gfm: true
});
module.exports = marked

not-gfm-marked/not-gfm-marked.js

var marked = require('marked');
marked.setOptions({
  renderer: new marked.Renderer(),
  gfm: false
});
module.exports = marked

index.js

var notGfm = require('not-gfm-marked');
var gfm = require('gfm-marked');
notGfm('```aaa```'); // fenced code block はgfmでないと存在しないが、参照が同一な為あとで読み込んだsetOptionsで有効になってしまう。

まあ意図しないとなかなか起こせないとは思うんだけど、ハマった時の根は深そう。他に気づいた点としてはbrowserifyが対応してなかったので、browserify使っている人も対応待ちになるはず。

そういえば es modules と commonjs の関係ってどうなるか話進んでるんだろうか。

39
38
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
39
38