left-padに依存していたプロジェクトの数と、Babelで採用されたことの影響について

問題は、たった17行のコードに、こんなに明らかな問題があるのに、事件が起こるまで誰にも気づかれずに、 Babel を始めとした大量のプロジェクトで利用されていたことだ。 僕は JSer じゃないので憶測だが、この開発者がJS界で超有名人で信頼されていたというよりも、「Babelも使ってるし」といった感じでどんどん依存が広まっていったのでは無いだろうか? Babel の中の人はそこまで考えて依存するライブラリを選んでいただろうか。(Babelよりも先に left-pad に依存していた有名プロジェクトがあったらごめんなさい)

依存するパッケージは厳選しよう - methaneのブログ

この部分を読んでいて

  1. Babelはleft-padにどのような経路で依存していたのか
  2. left-padが削除された時点で、Babel以外でleft-padに依存していたプロジェクトがどれほどあったのか
  3. Babelに依存されたことが、他のプロジェクトの採用の後押しになったのか

が気になったので調べてみた。

Babelはleft-padにどのような経路で依存していたのか

最初にleft-padの依存が入ったコミットではbabel → line-numbers → left-padという依存関係だった。

3/22のBabelからleft-padの依存を取り除いたコミットの時点では、Babelがモジュール化されて(babel-core, babel-helper-transform-fixture-test-runner, babel-traverse) → babel-code-frame → line-numbers → left-padという依存関係になっている。

Babelのパッケージがleft-padに直接依存したことはなかったと思う。git clone https://github.com/babel/babel.git && cd babel && git log -p --full-diff -- '*package.json' | grep left-padを実行してもマッチしなかった。

left-padに依存していたプロジェクトがどれほどあったのか

https://www.npmjs.com/package/left-padで、left-padを直接のdependencies*1 に含むパッケージ(dependents)の一覧を見ることができる。このdependentsを再帰的にたどることでleft-padに依存しているパッケージの一覧が取得できる。

left-padがnpmから削除された当時のdependentsを確認したいところだが、npmjs.comには過去のdependentsを表示する機能はなさそう。

アーカイブサイトを探すと、Wayback Machinehttps://www.npmjs.com/package/left-pad2015年9月のスナップショットがあった*2。このスナップショットを出発点にして、left-padに依存していたパッケージをたどってみる。指定した日時に一番近いスナップショットを検索するAPI*3を使って、できるだけ出発点のleft-padのスナップショットに近い日時のスナップショットを取得した。Wayback Machineに保存されていなければnpmjs.comを参照する。*4

graphvizで依存ツリーを描画してみた様子がこれ。ページの保存時期がバラバラなので正確な内容ではないけれど、line-numbersとprettify-error(これはleft-padの作者によるパッケージ)をハブにして依存が広がっているらしい。left-padが削除されたのは2016年3月なので、半年間で状況が変わっていた可能性はある。

line-numbersの影響

Babelがline-numbersに依存してからは、line-numbersがleft-padのダウンロード数の大半を集めるという状況がずっと続いていたようだ。left-padとline-numbersの月間ダウンロード数をグラフにしてみると*5、ほとんど一致している。一致しすぎてleft-padの線がほとんど隠れた。

ただし、月間ダウンロード数はleft-padのほうが数千から1万数千ほど多いので、line-numbers以外からもそれなりに利用されていたとは言えそう。

Babelが依存したことでleft-padが使われるようになったのか

2015年9月22日の時点でleft-padに直接依存していたパッケージを対象に、left-padが依存に追加されたコミットの時期を調べた。タイムゾーンは揃えていないので日付に±1日の誤差がある。

日付 名前 できごと
2014-03-14 left-pad 0.0.0がpublishされる
2014-03-14 prettify-error left-padに依存する(最初のコミット)(left-padの作者によるパッケージ)
2014-09-21 format-date left-padに依存する(最初のコミット)(left-padの作者によるパッケージ)
2014-12-20 line-numbers left-padに依存する(最初のコミット)
2015-01-13 textlint-formatter left-padに依存する(最初のコミット)
2015-02-21 babel line-numbersに依存する
2015-04-15 component-counter 1.1.0でleft-padに依存する*6
2015-05-20 simple-timestamp left-padに依存する(最初のコミット)
2015-06-11 color2 left-padに依存する
2015-09-11 date-prompt left-padに依存する
2015-09-14 time-tracking left-padに依存する

微妙な結果になった。Babelに依存されてから依存パッケージの増えるペースが早くなっているようにも見える。

Babelが間接的に依存するようになってからleft-padのダウンロード数が激増している*7ので、見た目の信頼度のようなものが高まった感じはあるが、実際にどれぐらいleft-padの普及に貢献したのかは分からない。

Babelが依存したことでline-numbersが使われるようになったのか

http://web.archive.org/web/*/https://www.npmjs.com/package/line-numbers

line-numbersに依存しているパッケージはBabel関連ツールを除けばcastborgしか確認できなかった。大きな影響はなかったように見える。

感想

「依存するパッケージは厳選しよう」という主張はもっともだと思う。有名なプロジェクトが使っているパッケージを参照するというのは自分もよくやるので、Babelの影響でleft-padが使われるようになったという結果がはっきり出るかと予想していたが、意外とそうでもなかった。

line-numbersがleft-padのダウンロード数の大半を集めていたのも予想外だった。もしもline-numberがleft-padに依存していなかったら、騒ぎはもっと小さくなっていたかもしれない。

ところでgraphvizの描画結果、入力上は1本しかないはずなのに、provaからprettify-errorに矢印が2本伸びているように見えるのが気になる。

*1:npmにはdependencies, devDependencies, peerDependencies, bundledDependencies, optionalDependenciesの5種類の依存がある。https://docs.npmjs.com/files/package.json

*2:他にarchive.is, webcite, ウェブ魚拓を確認したが、保存されていなかった。

*3:https://archive.org/help/wayback_api.php

*4:ソースコードはGitHubに置いた。汚くて何をやっているかわからないかもしれない。

*5:集計に使ったコードもGitHubに置いた。

*6:component-counterはリポジトリが更新されていないようだったのでnpmのtarballを確認した。

*7:http://npm-stat.com/charts.html?package=left-pad&author=&from=2014-03-14&to=2016-04-01