結論: 以下を .git/hooks/post-checkout に追加
#!/bin/sh PREV_BRANCH=`git reflog show -q | head -n1 | awk '{print $6}'` CACHE_DIR=~/.cache/my_project_node_modules mkdir -p $CACHE_DIR prev_node_modules_cache="$CACHE_DIR/$(git show $PREV_BRANCH:package.json | shasum | awk '{print $1}')-$(git show $PREV_BRANCH:package-lock.json | shasum | awk '{print $1}')" cur_node_modules="$CACHE_DIR/$(shasum package.json | awk '{print $1}')-$(shasum package-lock.json |awk '{print $1}')" if [ "$prev_node_modules_cache" = "$cur_node_modules" ]; then exit fi mv node_modules $prev_node_modules_cache if [ -d "$cur_node_modules" ]; then mv $cur_node_modules node_modules else npm ci fi
解説
package.json と package-lock.json をキーに、node_modules を ~/.cache/my_project_node_modules
へ保存している。
- 切り替え前のブランチと package.json も package-lock.json も同一の場合: 特に何もしない (同じ node_modules を使う)
- 切り替え前のブランチと package.json か package-lock.json が異なる場合:
- まず、今の node_modules をキャッシュディレクトリに移動する
- 既にキャッシュが存在する場合: キャッシュディレクトリから適切な node_modules を持ってくる
- キャッシュが存在しない場合: npm ci を行う
node_modules をコピーではなく移動させているだけなので、かなり軽快に動作する。
(ざっとしか検証してないので、動かなかったらコメントお願いします)