フロントエンド開発を長年悩ましてきたInternet Explorer 11(以下IE11)のサポートが2022年6月15日ついに終了となります。
これを受けて、サポートを続けていた既存のWebアプリもサポートを切る流れが現在進行系で加速していることでしょう。
ソース管理にGitHubを使用している場合、Dependabot Alertsが何十件、下手したら何百件と溜まっているかもしれません。npmパッケージをアップデートしてくれというメッセージを添えて。
npmパッケージは数年経つとバージョンが大きく上がるケースは多いです。規模の大きいパッケージになっていくと、いわゆるbreaking change(破壊的変更)が複数回含まれることも少なくありません。
この点を踏まえて、何も考えずアップデートしてDependabot Alertsをすべて解消したらアプリがビルドすら出来ずに動かなくなりました!一般にも公開するのにどうしましょう!な展開を避けるためにはどう対処すれば良いのでしょうか?今回は私自身の経験も踏まえてまとめていきます1。
本記事で紹介する手順はパッケージ管理がyarn(1.x系)であることを前提としています。npmなど別のパッケージ管理ツールを使用している場合は、都度コマンドを置き換えていただければと思います。またnpmに関して、パッケージ管理ツールとコマンドの意味を区別するため、後者を表す場合はnpm
と記載しています。
GitHubのDependabot Alertsとは?
GitHub上で運用しているリポジトリの設定がOn(デフォルトもOn)になっていると、リポジトリページに表示される警告です。
アプリにインストールされている依存パッケージの脆弱性を自動で検知・警告&場合によってはPRを自動で生成してくれる便利機能です。ここで言う依存パッケージはpackage.json
に明記されているパッケージだけでなく、package.lock.json
/yarn.lock
といったlockファイルにしか記載されていないパッケージも対象となります。
詳しく知りたい方は以下のページを読んでみてください。
npm audit fix
を使ってアップデートし、Dependabot Alertsを解消する
解消するためにターミナルで叩くコマンドは以下のとおりです。
$ yarn audit
$ npm i --package-lock-only
$ npm audit fix --force
$ rm yarn.lock
$ yarn import
$ rm package-lock.json
$ rm -rf node_modules
$ yarn # yarn install でも可能
何をしているのか、順を追って説明します。
Dependabot Alertsの一覧を確認
$ yarn audit
これはDependabot Alertsの一覧にターミナル上で吐き出してくれるコマンドです。--level [info|low|moderate|high|critical]
フラグをつけると指定した警告度のものだけ表示されます。アップデートする度にalerts数の確認のためにこまめに叩いておきましょう。
npm audit fix
で実際にパッケージのアップデートを行う
$ npm i --package-lock-only
$ npm audit fix --force
$ rm yarn.lock
$ yarn import
$ rm package-lock.json
npm audit fix
コマンドはpackage.json
に明記されているパッケージの子パッケージのalerts解消も考慮した状態までアップデートしてくれるコマンドです。
ただし、npm audit fix
コマンドに該当するコマンドがyarn
にはないため、npm i --package-lock-only
でまずpackage.json
の内容を基にpackage-lock.json
を生成します。
そしてnpm audit fix --force
でパッケージのアップデートを行います。この際、package-lock.json
の内容も書き換わります。
ここで--force
フラグの有無の違いについて質問が飛んできそうなので、説明します。正直npmのドキュメント読んでも分かりづらいため、ここは説明が難しいところですが、私はこんな風に解釈しています。
-
--force
フラグなし:package.json
に明記されているパッケージに限り、パッケージそのものにalertsが出ていれば、修正したバージョンへアップデートを行う。 -
--force
フラグあり:package.json
に明記されているパッケージの依存パッケージでalertsが出ている→package.json
に明記されているパッケージについて、その依存パッケージがalertsの出ないバージョンへ修正された状態のバージョンへアップデートを行う。
--force
フラグありの意味が自分で書いておいてよくわからなくなっていますが、要はpackage.json
に明記されているパッケージの子パッケージのalerts解消も考慮した状態までアップデートしてくれるよ、の意味で取っていただければと思います。
package-lock.json
の内容をyarn.lock
に反映させたいので、一旦既存のものを削除しyarn import
で再度生成します。
アップデート後、ビルド出来るかなどを確認
$ rm -rf node_modules
$ yarn # yarn install でも可能
node_modules
にはまだアップデート前の情報が残ったままなので一旦消して、再度生成しましょう。
終わったら、ビルドしてみたりアプリ起動したりして、正常に既存アプリが動作するかを確認しましょう。yarn audit
での確認も忘れずに。またLinter/Formatter/テストコードが入っている場合はこちらも合わせて確認しておきましょう。
流れとしては以上です。コマンドの説明を終えたので、ここから具体的な対処方法の解説をしていきます。
依存パッケージ数別アップデート手順
package.json
にいるパッケージ数の規模によってアップデート手順が少し違ってくるので分けて説明します。
※パッケージ数はあくまで私の経験則による目安です。パッケージが大きいものばかりという可能性もあるので、目安はケースバイケースで変更してください。
パッケージ数が小規模(<=15くらい)
まだ数が少ないので、こちらの節で解説した方法のみで問題ありません。時間もかからない&万が一何か合った場合に原因の特定が難しくないからです。
パッケージ数が中〜大規模(>15くらい)
規模が大きくなるので、一辺にアップデートしてしまうと万が一何か合った場合の原因特定/原因となったライブラリの切り分けが難しくなっていきます。ですので私の経験上、以下の方法をオススメします。
- 基本的に前述のアップデートコマンドを叩いて、
npm audit fix --force
ではなく、npm audit fix
で叩く - ビルドエラー等出ないか確認
- 前述のアップデートコマンドそのまま叩く
- 再度ビルドエラー等出ないか確認
こんなときどうすればいいの?集
npm audit fix
の方法だけですんなり上手くいけばいいのですが、やはり上手くいかない場合も多々あります。私の経験で実際に対処したケースをここにまとめておきます。
npm audit fix
でアップデートしたのにDependabot Alertsが解消されない
このケースは残念ながら度々発生します。この場合、alertsが出ているパッケージはpackage.json
に明記されているパッケージから更に枝分かれ形式で依存しているものであるケースがほとんどです。
この場合、yarnのresolutions
機能を使ってalertsが出ているパッケージを指定する方法で対処する方法があります。
まずyarn audit
などでalerts一覧を確認し、そこでpatched versionに書かれたバージョンをpackage.json
のresolutions
欄に追記しましょう。
コード例では以下のことを行っています(パッケージ名はあくまで例です)。
- hogehogeというパッケージのバージョンが
2.1.3
で固定されてインストールされる - fugaというパッケージのバージョンが
1.1.5
<2.0.0
の間でインストールされる
{
"devDependencies": {
...
},
+ "resolutions": {
+ "hogehoge": "2.1.3"
+ "fuga": "^1.1.5"
+ }
}
これで再度yarn
もしくはyarn install
コマンドでパッケージをインストールし、yarn auditするとresolutions
したパッケージのalertsが消えます。
resolutions
機能をもう少し詳しく知りたい方は以下のページを参考にしてみてください。
※npm
を使用している場合、version8.3以降限定ですが、overrides
機能で代用可能なようです。
ESLintとPrettierが喧嘩する
ESLintとPrettierはモダンフロント開発におけるLinter/Formatterのデファクトスタンダードです。
そんなESLintとPrettierですが、アップデートを行うと、ESLint的にはOKだが、PrettierとしてはNGとなる現象も多々発生します(私は遭遇したことないですが、逆のケースも勿論存在すると思います)。この場合、vscodeなどで出るエラー解消ボタンを押してコードを修正しても今度はESLintとしてNGになってしまいます。なぜこんなことが起こるようになってしまったのでしょうか?
Prettierはversion 2.x系以降において末尾カンマの有無などデフォルト設定が大きく変更されました。詳しい変更点の内容は以下の記事を参考にしてもらえばと思います。
Prettier側の設定で上記変更点を一部offにすることは可能なのですが、残念ながらPrettier側から変更出来る設定は少なく全部の競合の制御は不可能な仕様となっています。ですので、ESLint側の方を上手く制御してあげる必要があります。
Prettier側としては、eslint-config-prettierというPrettier側のルールと競合しうるESLintルールをoffしてくれるライブラリを使って競合を避けることが推奨されています2。もしこのeslint-config-prettierが入っていても、競合が発生するのであればpluginも含めたESLint関連のパッケージのバージョン指定を一度見直しましょう。
Node.jsのバージョンが指定されているため、パッケージのバージョンを上げたくても上げられない
プロジェクトによっては、使用するNode.jsのバージョンが指定されている場合があります。この場合、パッケージによってはアップデート出来ないケースがあり得ます。
私が出会ったパッケージではnode-sassがこれに該当します。README見てもらえばわかると思いますが、Node.jsのバージョンによってインストールするバージョンが指定されています。
(引用:node-sassのREADMEより)
もう非推奨なんだし、さっさとdart-sassに乗り換えればいいのにの声が聞こえてきそうですが、現実はそんなわけにはいきません。以下のページを見てもらえばと思いますが、@import
から@use
への変更を筆頭に文法が一部変更されています。
アプリの規模が大きい場合、既存の大量のsass/scssファイルの精査/書き換え作業が必要になります。もはやこのレベルならアップデート作業が完了した後に、別タスクとしてやるかnode-sassのままにしておくべきでしょう(正直dart-sassへの移行は、E2E Test環境やVisual Regression Testing環境が完備されているとかでもない限り、山積みの手動テストが必要になるのでかなり難しい)。
そんなわけでalertsを消すだけなら、前述のyarnのresolutions
機能を活用しましょう。(もしalertsを全て消してくれという要求がされているのであれば、今回はNode.jsのバージョンの影響で解消出来なかったです、Node.jsのバージョン云々は今後相談させてくださいみたいな話をマネジメント層を通してきちんと相談しましょう。)
まとめ
今回は私の経験則を基にnpmパッケージのアップデート対応方法をまとめてみました。alertsを一掃するだけならそんなに難しくないのですが、アプリを動かすまでのパッケージバージョンの指定/設定の追記修正がなかなか難しいです。
また対処集もいくつか載せてみましたが、こんなケースもあった、もっとこうすれば楽に進められるなどのご意見があればコメントいただけると非常に嬉しいです。ではIEに苦しめられない良いフロント開発ライフを願って!
参考ページ