Movatterモバイル変換


[0]ホーム

URL:


LoginSignup
557

Go to list of users who liked

317

Share on X(Twitter)

Share on Facebook

Add to Hatena Bookmark

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

npm ciを使おう あるいはより速く

Last updated atPosted at 2018-03-12

人類はより高速にCIを回していくべきだと思っている りんご(@mstssk)です。

先日、 npm のv5.7がリリースされnpm ci というサブコマンドが新たに追加されました。

The npm Blog — Introducingnpm ci for faster, more reliable...http://blog.npmjs.org/post/171556855892/introducing-npm-ci-for-faster-more-reliable

CI/CDを開発プロセスに組み込んでいる場合により整合性があり高速なエクスペリエンスを提供する、と公式ブログでは紹介しています。

npm ci は何をするのか

npm ci を実行すると常に package-lock.json から依存関係をインストールします。
既に node_modules フォルダの中身があっても一旦削除します。

従来のnpm install コマンドを実行すると、 package.json と package-lock.json の両方を見て依存関係の解決と依存パッケージの node_modules へのインストールを行います。 package.json を解決して必要に応じてロックファイルである package-lock.json の更新もします。

一方でnpm ci は package.json の依存関係の解決を行わず、常に package-lock.json を見て依存パッケージをダウンロードし node_modules の洗い替えを行います。
しかし、 package.json を完全に無視するというわけではなく、 package-lock.json と依存バージョン指定が食い違っているとエラーにしてくれます。例えば、あるパッケージをv0.8.9でインストールし package-lock.json まで作成済みの時に、そのパッケージを更新しようとして package.json だけv0.9.0 に書き換えてしまった状態でnpm ci を実行するとエラーになります。

このように、依存関係の更新をせずに整合性チェックと依存パッケージのダウンロードのみを行うためnpm install より高速に動作し、CIで必要なことだけを行うのがnpm ci コマンドです。

npm ci は銀の弾丸ではない

npm ci が package.json と package-lock.json の整合性をチェックしてくれるのは嬉しいです。
一方で、依存パッケージのダウンロード・インストールの高速化については、爆速になるというほどではありません。

私が普段触っているWebサイト構築プロジェクトいくつかで時間を計測してみました。

npm installnpm ci
プロジェクトA25.515s16.656s
プロジェクトB29.761s20.676s
プロジェクトC54.380s40.710s

※いずれも node_modules が存在しない状態で計測。

どの場合でも早くなるのは10秒前後でした。この10秒が package.json を見て依存関係の解決を行う時間なのでしょう。

削減できなかった時間が何なのかというと、ログを見ている限りでは各依存パッケージのpreinstall /postinstall のスクリプトの実行時間のようです。
例えば node-sass パッケージは実行環境ごとのバイナリのインストールや動作チェックを行っているようですし、その他にもインストール時にnode-gyp を使ってネイティブモジュールをビルドしている、なんてものもありました。

思い切って node_modules をキャッシュすると早い

CIの速度を重視するならnpm ci を使うのではなく、もっと愚直に node_modules をキャッシュしてしまうという手段もあります。

例えば、私は普段CircleCIの config.yml で次のように設定して、node_modules をキャッシュさせています。

.circleci/config.yml
version:2jobs:build:steps:-checkout-restore_cache:keys:-npm-cache-{{ checksum "package-lock.json" }}-run:npm install-save_cache:key:npm-cache-{{ checksum "package-lock.json" }}paths:-./node_modules/* 後略 */

この方法によって、通常npm install に54秒かかっていたプロジェクトも、キャッシュのレストアとnpm install の時間あわせて15秒程度で済んでいます。
もちろん、最初の1回や package-lock.json を更新した際は時間がかかってしまいますが、多くの場合で大幅に速度改善になります。

ただし、この方法ではnpm ci が提供する package.json と package-lock.json の整合性チェックが使えません。
npm ci は node_modules があると一旦消して洗い替えしてしまうのでキャッシュと一緒に使用できません。
CIで何を担保するのかを考慮した上でキャッシュの使用を検討するとよいでしょう。

まとめ

npm ci は既にCIでnpmを使っているプロジェクトへの強力なサポートとなります。
どうしても速度を改善したい場合は node_modules をキャッシュしてしまう方法もあります。

みなさんもプロジェクトにあわせてCIをメンテしていきましょう。

追記 2018-07-18

この記事を書いた後に気づいたことなど。

~/.npm をキャッシュしよう

npm ci の公式ドキュメントでは、Travis CIを使う場合に ~/.npm フォルダをキャッシュする例を記載しています。

前述のとおり node_modules をキャッシュしてもnpm ci が消してしまい意味がありません。
しかし、 npm が依存関係解決をする際にダウンロードしてきたものをキャッシュしている ~/.npm フォルダをCIのキャッシュに含むことでより速度改善を図ることができます。

今は私が携わっているプロジェクトでも、 ~/.npm をキャッシュしつつnpm ci コマンドを使うよう CircleCI の設定を変えています。

npm ci は人間の attention というリソースの消費も改善する

どんなツールでもサービスでも同じなのですが、何かを行う・行わせるというのは人間の attention1(注意とか意識とか集中力とか)を消費します。

npm install コマンドを使うと、 package.json を変えていなくても npm のバージョンが違っていれば package-lock.json は変更されてしまいます。
更には、 package.json を変えたのに package-lock.json をコミットし忘れてしまったといった場合にCIで気づくことができません。
特に開発メンバーが多いプロジェクトではメンバー間の技術力・意識の差により問題が顕著になります。
それを防ぐために開発者がいちいち頑張るのはリソースを余計に消費していることになります。

npm ci を使えば、速度の改善と依存関係の整合性のチェックを一息に行ってくれますので、上記の問題について開発者が気を揉む必要がなくなります。

そもそも、 npm 公式の Blog 記事のタイトルにも "for faster, more reliable builds" とあり、依存関係解決について速度と信頼性向上のための機能であるとわかります。
本qiita記事を書いたときは速度改善にばかり目が行ってしまっていましたが、実際運用してみてnpm ci が何を提供してくれるのかを再認識しました。

  1. Lolipopの頃のAndroidの通知機能の公式ドキュメントに「通知を出してユーザーの注意を向けさせたりするのは、ユーザーの注意や関心を奪い消費しているということを認識しよう」といったことが書いてあって、通知に限った話ではないなと思い、私はその言い回しをたまに使っています。

557

Go to list of users who liked

317
1

Go to list of comments

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
557

Go to list of users who liked

317

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?


[8]ページ先頭

©2009-2025 Movatter.jp