Node.js
npm
CodeBuild

AWS CodeBuildでnode_modulesをキャッシュしたらハマった

はじめに

CodeBuildでnode_modulesをキャッシュしたらバイナリ(実行ファイル?用語がわからない・・・)が使えなくなったので、解決方法のメモ。
バイナリを使わない場合には関係の無い話かもしれません。

何がおこったのか

  • 一回目は成功するが、二回目以降に実行するとsh: 1: webpack: not foundとエラーが発生
package.json
{
  "scripts": {
    "build": "webpack --optimize-minimize"
  },
  "dependencies": {
    "webpack": "^3.10.0"
  }
}
buildspec.yml
version: 0.2

phases:
  install:
    commands:
      - npm install

  build:
    commands:
      - npm run build

artifacts:
  files:
    - '**/*'
  base-directory: dist

cache:
  paths:
    - 'node_modules/**/*'
error_log
[Container] 2018/02/02 06:58:40 Running command npm run build

> XXX@0.1.0 build /codebuild/output/src015426277/src/github.com/XXX/XXX
> webpack --optimize-minimize

sh: 1: webpack: not found
npm ERR! file sh
npm ERR! code ELIFECYCLE
npm ERR! errno ENOENT
npm ERR! syscall spawn
npm ERR! XXX@0.1.0 build: `webpack --optimize-minimize`
npm ERR! spawn ENOENT
npm ERR! 
npm ERR! Failed at the XXX@0.1.0 build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR! /root/.npm/_logs/2018-02-02T06_58_41_015Z-debug.log

[Container] 2018/02/02 06:58:41 Command did not exit successfully npm run build exit status 1

原因

  • node_modules/.binにはsymlinkが配置されているが、相対パスではなく絶対パスに書き換わっていた
  • 作業ディレクトリはビルドの度に変わる
  • バイナリの宛先を見たところcacheされた時点の絶対パスになっていた

上記が原因でコケていた

解決策

  • node_modulesをtarでアーカイブしたところ無事解決
buildspec.yml
version: 0.2

phases:
  install:
    commands:
      - if [ -e /tmp/node_modules.tar ]; then tar xf /tmp/node_modules.tar; fi
      - npm install

  build:
    commands:
      - npm run build

  post_build:
    commands:
      - tar cf /tmp/node_modules.tar node_modules

artifacts:
  files:
    - '**/*'
  base-directory: dist

cache:
  paths:
    - /tmp/node_modules.tar

最後に

ハマって調べたけど類似する情報が見つからなかったので、備忘録として残しました!
お役に立てれば幸いです。