Amplify ConsoleでNode.jsのバージョンをアップデートする (追記あり)

f:id:Keisuke69:20180529112807j:plain

(Update)このブログは最後の追記だけを見れば事足ります。

Amplify ConsoleでとあるReact、Next.jsベースのアプリケーションをホストしているんだけど、最新のプッシュで動いたデプロイがビルドのフェーズで落ちてしまった。

ログは以下。

2022-01-12T01:20:42.950Z [WARNING]: error @typescript-eslint/experimental-utils@5.9.0: The engine "node" is incompatible with this module. Expected version "^12.22.0 || ^14.17.0 || >=16.0.0". Got "12.21.0"
2022-01-12T01:20:42.958Z [WARNING]: error Found incompatible module.
2022-01-12T01:20:42.958Z [INFO]: info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.
2022-01-12T01:20:42.979Z [ERROR]: !!! Build failed
2022-01-12T01:20:42.979Z [ERROR]: !!! Non-Zero Exit Code detected

これはつまりインストールしようとしているライブラリ(ここでは@typescript-eslint/experimental-utils@5.9.0)と互換性のあるNode.jsのバージョンがインストールされていないってこと。どうやらAmplify Consoleで使われているNode.jsのバージョンはこのメッセージに表示されているように 12.21.0 のようだ。本記事執筆時点のv12系の最新LTSが 12.22.9 なのでちょっと古い。そしてできれば14と16も選べるようにしてほしいところ。

そもそも @typescript-eslint/experimental-utils@5.9.0 をAmplify Consoleに本番デプロイするときにインストールする必要ないよねって話もあるのでそこは後ほどちゃんとするとして。

この問題に対応する方法として大きく2つ。1つはAmplify Consoleはカスタムイメージ使えるのでそれを使うパターン。もう1つはAmplify Consoleが使うNode.jsのバージョンを自分の使いたいものにアップデートすること。

カスタムイメージの方法は自分でコンテナイメージ作ったりするのが面倒なので今回はナシかな。普段Remote Containersで使ってるDockerfileをそのまま使えばいいのかもだけど。

後者のAmplify Consoleで使うNode.jsのバージョンをあげる方法については以下でも言及されている。

github.com

要約すると、

  • Amplifyのbuild settingで使いたいバージョンをインストールするよう指定する
  • preBuildのフェーズで行う

というわけで早速やっていく。

Amplifyのビルド周りの設定は amplify.ymlというファイルに定義していく。このファイルはAWSのマネジメントコンソール上で編集することも可能だけどソースリポジトリのルートフォルダに置いておくことも可能だ。バージョン管理の観点では手元で管理したほうがいいだろう。

これが変更前の amplify.yml

version: 1
frontend:
  phases:
    preBuild:
      commands:
        - yarn install
    build:
      commands:
        - yarn build
  artifacts:
    baseDirectory: .next
    files:
      - '**/*'
  cache:
    paths:
      - node_modules/**/*

見ての通り、preBuildのコマンドでyarn installとしか指定していないためdevDependenciesに指定されているライブラリもインストールされてしまっている。なのでここもついでに変更する。

実際にNode.jsのバージョンを変更するには同じくpreBuildnvmを使って使いたいバージョンをインストールするだけだ。

というわけでこんな感じにする。

    preBuild:
      commands:
        - nvm install --lts --latest-npm
        - nvm use stable

実際にこれで実行してみるとこんな感じでログが出力されていて最新のLTSである16.13.2が無事にインストールされたことがわかる。

                                 # Starting phase: preBuild
                                 # Executing command: nvm install --lts --latest-npm
2022-01-12T03:07:17.052Z [INFO]: Installing latest LTS version.
2022-01-12T03:07:17.192Z [INFO]: Downloading and installing node v16.13.2...
2022-01-12T03:07:17.253Z [WARNING]: Downloading https://nodejs.org/dist/v16.13.2/node-v16.13.2-linux-x64.tar.gz...
2022-01-12T03:07:17.368Z [WARNING]: #########################
2022-01-12T03:07:17.369Z [WARNING]: 35.3%
2022-01-12T03:07:17.439Z [WARNING]: ####################
2022-01-12T03:07:17.439Z [WARNING]: #################################################### 100.0%
2022-01-12T03:07:17.453Z [WARNING]: Computing checksum with sha256sum
2022-01-12T03:07:17.563Z [WARNING]: Checksums matched!
2022-01-12T03:07:18.825Z [INFO]: Now using node v16.13.2 (npm v8.1.2)
2022-01-12T03:07:18.855Z [INFO]: Attempting to upgrade to the latest working version of npm...
2022-01-12T03:07:19.112Z [INFO]: * Installing latest `npm`; if this does not work on your node version, please report a bug!
2022-01-12T03:07:22.965Z [INFO]: removed 8 packages, changed 24 packages, and audited 215 packages in 4s
2022-01-12T03:07:22.969Z [INFO]: 10 packages are looking for funding
                                 run `npm fund` for details
                                 3 moderate severity vulnerabilities
                                 To address all issues, run:
                                 npm audit fix
                                 Run `npm audit` for details.
2022-01-12T03:07:23.202Z [INFO]: * npm upgraded to: v8.3.0
2022-01-12T03:07:23.203Z [INFO]: # Executing command: nvm use stable
2022-01-12T03:07:23.797Z [INFO]: Now using node v16.13.2 (npm v8.3.0)

特定のバージョンを指定したい場合はnvm installでそれを指定すればいい。これだけで今回の問題は解決しているものの冒頭でも書いたようにそもそもdevDependenciesの内容も含めてインストールされているのも少し問題なのでそこも修正した。が、よく考えてみるとAmplify ConsoleでのデプロイのビルドプロセスではNext.jsのビルド処理も含まれているのでやっぱりdevDependencies必要じゃん!ってなったのでやっぱり修正しない。というかできない。

というわけで最終的には以下のようなamplify.ymlになった。

version: 1
frontend:
  phases:
    preBuild:
      commands:
        - nvm install --lts --latest-npm
        - nvm use stable
        - yarn install
    build:
      commands:
        - yarn build
  artifacts:
    baseDirectory: .next
    files:
      - '**/*'
  cache:
    paths:
      - node_modules/**/*

こんな感じでひとまず今回の問題は解決したが、気になるのはビルドのたびに毎回インストールするのか?ってこと。実際に今回試した感じではそれほど時間はかからなかったもののビルドの時間がかかるようになるのは嫌だなとも思う。とはいえAmplify自体がお目当てのバージョンに対応するまでだけの暫定対応とも言えるが。

でもできればLambdaみたいにNode.jsのバージョンを選べるようになると嬉しい。 => 追記参照

最後に余談だけどamplify.ymlで指定できるcacheとしてnvmでインストールしたNode.jsのランタイムのフォルダとかを指定しておくと毎回ビルドでインストールされる問題は解決するのかもしれない、なんて話をAWSの人とした。でもまだ試してない。

ここから追記

上記のような感じで対応して満足してたところ、ツイッターで僕の心の友からこんな情報が寄せられた。

そういえば、Next.jsのSSRに対応したって話のときにこのあたりの設定をしたことがある遠い記憶が。

f:id:Keisuke69:20220112125648p:plain

これはLive package updatesというものでAmplify Consoleが利用するデフォルトイメージのライブラリとかをオーバーライドできるそう。そしてここにNode.js versionというのがあった!

というわけで早速ここを16.13.2に指定して再度デプロイしてみることに。

f:id:Keisuke69:20220112125756p:plain

f:id:Keisuke69:20220112125811p:plain

無事に通った!というわけで

Amplify ConsoleでNode.jsのバージョン選ぶことできました!

というわけでこのブログの前半部分はほぼ意味がないものにw

でもこの設定をバージョン管理できないのでamplify.ymlで指定できるようになるといいね。実はできるのかな?

©Keisuke Nishitani, 2020   プライバシーポリシー