プログラミング 美徳の不幸

Ruby, Rails, JavaScriptなどのプログラミングまとめ、解説、備忘録。

npmでパッケージの複数バージョンがサポートされると幸せなんだけど

とうとうbrowserify-railsを入れてしまいました。 で、jsのライブラリがnpmで管理されるようになったんですが、一つ問題が。

僕はふだん app/assets/javascripts/recipe.js app/assets/javascripts/kitchen.js app/assets/javascripts/restaurant.js

みたいにある程度ページ構成とかで同一アプリの中でも住み分けができるものをこのように分割して、jsからcssからcontrollerに至るまで疎結合にしてます。 これには大きく理由が2つあって

app/assets/javascripts/application.js

のように単体のjsに全て圧縮するとPVの少ないマイナーなページだけで使う巨大なライブラリなども含まれた時に無駄な読み込みが増えてしまうこと。

ある程度の画面構成をサブアプリとして捉えれば、サブアプリごとにjsのライブラリを変えていって「今までBackbone.jsを使っていたから今後も使い続ける」のような保守的な理由でモチベーションが下がることを予防するためです。

例えばRailsの場合だと

vendor/assets/javascripts/vue@0.12.1 vendor/assets/javascripts/vue@1.0.0

のようにライブラリを複数バージョン入れておけば、それぞれのrequireで読み込み先を変えて古いページでは古いバージョンをそのままで、新しいページでは新しいバージョンを使用、ということもカジュアルにできました。

時間があったときに古いページのjsもアップデートするか、そもそも古いページでフルリニューアルが合った際などに一気に古いバージョンを捨てるだけなので新規の実装への縛りが減ることやコードの廃棄可能性(他への依存が少なくまるっとリプレイスできる)が上がるので大変気に入ってる仕組みです。

ところが、npmだと現状package.jsonに書いたライブラリのバージョンは一つしか入らないようなんですね。

このことで議論になっているissueを見つけました。

github.com

要約すると例えば

{
  "jquery as jquery1.8" : "1.8";
  "jquery as 2.1" : "2.1"
}

みたいにできたら良くない?っていう主張に対して、isaacs氏が「リファクタリングが足りない」「npmの責務はdependenciesの中のものをnode_modulesの中にぶち込んでrequireできるようにするだけ」と突っぱねてる感じ。

ユースケースとして上で上げてるのが一つ目、あるモジュールで複数のバージョンに互換性があるか検証したいというのが二つ目、2つ以上のプロジェクトをマージしたケースなどが3つ目として上げられている。やっぱり同じことを考えている要望は多いようだが・・・。

個人的には将来的にマイクロサービスにしていきたいものを現実問題として結合させたままにしておこうというノリなのでクライアントサイドはなるべく分けたいのだがどうしようか・・。