小さめのWEBフロントのツール周りのアップデートで友達としゃべるときのネタ帳

# 概要

このエントリでは、小規模なWEBフロントで、作ってしばらくたったものについて、JS系のツール周りを見直す時の考え方の例について扱います。
筆者が、とある友人と会話する前に、自分でちょっと考えてみたことをダンプしたものです。


## 前提

このエントリでは、以下を前提とします。

- "絶対バージョンを上げられない"などの制約がない
- 変化を受け入れ、よりよいものにするにあたり、心の準備と実際に使える時間がある
- 脆弱性対応はさっさと対応、フレームワークのサポート切れに起因するアップデートも早めに対応

## 対象読者

- WEBフロントをメインのお仕事とはしていないが、たまに触る方
- 特定のSPA向けの「全部入り」スターターキットを使っている状態でなく、自分でツールを選んで組み合わせている方
- WEBフロントで数年って、かなり昔のことだよね、という感覚に理解がある方


## ツール前提

- Nodeはエントリ執筆時点のLTS(v12.16.1)を使っています
- ツールの動作OSは問わない範囲で書いています

## このエントリの版

- 2020/03/03 とりあえず初版。"テスト"のところはTODOとしておいたもの。


# 考え方の例

## 目的を設定する

「作ってしばらくたったWEBフロント」に対して何を検討したいかについて目的を設定すると、議論が進みやすくなります。

### 目的の例

このエントリでは、下記のような目的を想定します。

|No|目的の例|
|:---|:---|
|1|外部から確認できる脆弱性が気になる|
|2|アプリ内部やツール周りの脆弱性が気になる|
|3|アプリが依存するツール群のバージョンアップに対応したい|
|4|特定のツール・ライブラリが「不便に」感じるので他の物を試したい|
|5|特定のツール・ライブラリが「古臭く」感じるので他の物を試したい|
|2147483647|とにかく何かを新しくしたい|

### 目的に対する検討タスクの例

上記の"目的例"に対して、下記のようなタスクが考えられます。このエントリでは、下表の「このエントリで扱うもの」列でチェック「x」をつけたもののみ扱います。

|No|検討タスクの例|上記の"目的例"への対応|このエントリで扱うもの|
|:---|:---|:---|:---|
|1|WEBサイトの脆弱性チェックサービスを使ってみる|1,2|N/A|
|2|セキュリティチェック用のツールで自分で手元で動かせるものを使ってみる|1,2|x|
|3|ツール類をアップデートしたり乗り換えてみる|4,5|x|
|4|SPA用フレームワークをアップデートしたり乗り換えてみる|4,5|N/A|
|2147483647|思いとどまる|5,2147483647|N/A|
|9223372036854775807|がんばってください|2147483647|N/A|

# 検討タスク例での具体例

## セキュリティチェック用のツールで自分で手元で動かせるものを使ってみる

### GitHubのSecurity Advisoryを使う

2019年ころから、GitHubでセキュリティチェックのためのツールが使えるようになっています([GitHubブログでの説明"Announcing Security Lab"](https://github.blog/jp/2019-11-18-announcing-github-security-lab-securing-the-worlds-code-together/))。

確認するには、GitHubリポジトリで「Security」のタブを選択します（下図）。
下図の例で対象としたリポジトリは、筆者が2017年の春頃に書いていたコード断片です。

「Security」![GitHub_Security_Check.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65002/62ce80b8-402d-b33c-7c88-bdf1488f6a46.png)

Securityタブまでいかずとも、リポジトリのトップページにAlertが表示されているのでそこでも気づけます。

![We found a security potential alert.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65002/36716496-3b3a-a506-7a5a-27ef76fb41be.png)


### npm

作ってしばらくたったWEBフロントで、npm installすると、下記のようにWARNが出ていることに気づくことも多いと思います。

```console
$ npm install
npm WARN deprecated babel-preset-es2015@6.24.1: 🙌  Thanks for using Babel: we recommend using babel-preset-env now: please read https://babeljs.io/env to update!
npm WARN deprecated json3@3.3.2: Please use the native JSON object instead of JSON 3
npm WARN deprecated coffee-script@1.4.0: CoffeeScript on NPM has moved to "coffeescript" (no hyphen)
npm WARN deprecated core-js@2.6.11: core-js@<3 is no longer maintained and not recommended for usage due to the number of issues. Please, upgrade your dependencies to the actual version of core-js@3.

（中略）

added 1086 packages from 1302 contributors and audited 8617 packages in 342.609s

35 packages are looking for funding
  run `npm fund` for details

found 20 vulnerabilities (4 low, 7 moderate, 8 high, 1 critical)
  run `npm audit fix` to fix them, or `npm audit` for details
```

上記例では「added 1086 packages from 1302 contributors and audited 8617 packages」と、いっぱいチェックしてくれていますね。

同等のチェックは、「[npm audit](file:///C:/Program%20Files/nodejs/node_modules/npm/docs/public/cli-commands/npm-audit/index.html)」で確認できます。下図に実行例を示します

```console
$ npm audit

                       === npm audit security report ===

# Run  npm install --save-dev mocha@7.1.0  to resolve 2 vulnerabilities
SEMVER WARNING: Recommended action is a potentially breaking change

  Critical        Command Injection

  Package         growl

  Dependency of   mocha [dev]

  Path            mocha > growl

  More info       https://npmjs.com/advisories/146

```

これを見ながらやばそうな（＝"Critical"とか"High"な）やつから順に対処を考えることにするとよいでしょう。

「npm audit fix」すると、npm auditのルールに従って、ある程度自動で利用バージョンを新しくしてくれます（下図）。semver([セマンティックバージョニング](https://semver.org/lang/ja/))の考え方に従って、プログラムが壊れてしまう可能性があるバージョンアップについては除外されます。

```console
$ npm audit fix
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.1.2 (node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.1.2: wanted {"os":"darwin","arch":"any"} (current:{"os":"win32","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.11 (node_modules\watchpack\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.11: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})

+ marked@0.8.0
added 2 packages from 5 contributors and updated 2 packages in 23.417s

35 packages are looking for funding
  run `npm fund` for details

fixed 9 of 20 vulnerabilities in 8617 scanned packages
  4 vulnerabilities required manual review and could not be updated
  3 package updates for 7 vulnerabilities involved breaking changes
  (use `npm audit fix --force` to install breaking changes; or refer to `npm audit` for steps to fix these manually)

```

さらに「node audit fix --force」すると、プログラムは壊れるかもしれないけれどもさらにライブラリのアップデートを試みます(下図)。

```console
$ npm audit fix --force
npm WARN using --force I sure hope you know what you are doing.

> fsevents@1.2.11 install C:\Users\hrkt\work\shu-ho-standalone\node_modules\watchpack\node_modules\fsevents
> node-gyp rebuild


(中略)

npm WARN css-loader@3.4.2 requires a peer of webpack@^4.0.0 || ^5.0.0 but none is installed. You must install peer dependencies yourself.

+ mocha@7.1.0
+ css-loader@3.4.2
+ bootlint@1.0.0
added 172 packages from 92 contributors, removed 138 packages, updated 27 packages and moved 1 package in 35.222s

40 packages are looking for funding
  run `npm fund` for details

fixed 7 of 11 vulnerabilities in 8617 scanned packages
  4 vulnerabilities required manual review and could not be updated
  3 package updates for 7 vulnerabilities involved breaking changes
  (installed due to `--force` option)

```

残った部分は「npm audit」を見ながら一つ一つ対応が必要になるでしょう。

## ツール類をアップデートする

### 目的別の分類

ツール類をアップデートにあたり、まず目的別に分類してみます。

とてもよくできたリポジトリ[https://github.com/kamranahmedse/developer-roadmap(以降"WDR2020"と略記)](https://github.com/kamranahmedse/developer-roadmap)の「Front-end」の部分を参考に分類を試みます。例えば、下表のようになるでしょう。

|カテゴリ|上記リポジトリ中の項目名|目的|このエントリで扱うもの|
|:---|:---|:---|:---|
|見た目|CSS Framework|CSSを利用したフレームワークで、UIツールキット群を含むようなもの|N/A|
||CSS Preprocessor|より便利な書き方をしてCSSを作り出すためのプリプロセッサ|N/A|
|主にビルドまわり|Module Loader / Bundler|複数のJSを一つにまとめてロードを早くするなど|x|
||Package Manager|アプリで使用するJSのライブラリ群を管理|x|
||Task Runner|開発時に必要な各種タスクを実行する起点となる|x|
|画面制御|SPA Framework|ReactとかAngularとかVueとかみんなが好きなやつ|N/A|
|テスト|Testing|単体・結合・E2Eテストを実行する|x|
|言語|JS/TS|アプリのロジックを書く。JSに変換できる言語など(例：TypeScript)|N/A|
|コードスタイル|Linter / Formatter|コードのスタイルをきれいに揃える|x|
|進んだWEB|PWA|モバイルのネイティブアプリのような高度な機能を持つWEBを作る|N/A|
||SSR|サーバ側でSPAフレームワークを動かして画面をレンダリングしてクライアントに返す|N/A|
||StaticSite Generator|サイトを静的に出力して、結果のhtmlをホストする|N/A|
||Desktop App|WEBの技術でデスクトップアプリを作る。[Electron](https://www.electronjs.org/)とかそういうもの|N/A|
||Mobile App|WEBの技術でモバイルアプリを作る。[Cordova](https://cordova.apache.org/)とかそういうもの|N/A|

「ツール類をアップデートする」という観点では、アプリに影響が大きそうなのは、各ツールがメジャーバージョンアップをし、古いバージョンとの互換性がなくなって作成したコードやスクリプト側に大きな変更が必要になるときが挙げられます。想定されるのは例えば下記のような例です。

- SPAのフレームワークがアップデートしたので引きずられていろいろ変えないと動かない
- バンドラのバージョンを上げたら使っていたスクリプトとかプラグインが動かなくなったのでいろいろ変えないといけない
- ほかの要因に引きずられてテスト実行系が壊れたので直さないといけない

このエントリでは以降、上の表でチェック「x」が入っているものについて扱います。（「N/A」としてあるものは、筆者があまり経験がなかったり、メジャーアップデートにあたり設計変更を含めた大きな変更が必要だったり、それぞれのツール/フレームワーク内でのノウハウの塊っぽかったりするので日和りました。。）

上の表で「x」をつけたものに関しては、「ツール類を見直して乗り換えてみる」も一部含みます。

### 各論

以降、前述の表でチェック「x」をつけたものに従い、考え方の例として、筆者の考えを述べます。判断の基準は、外部サイトを明記したもの以外は、「ソースは俺」レベルであることをお断りしておきます。

#### 共通

まず、考え方の共通となる部分について述べます。

##### アップデートする/しない

- SemVerでいう、「メジャー.マイナー.パッチ」形式のバージョンでいうところの「マイナー」「パッチ」レベルなら、SemVerが主張する通りの考えで作られたツールなら、package.jsonに記載した各ツールごとにバージョンを上げて動作確認するレベルでもそのまま動作することがある程度期待できます。まれに何かが壊れることも予想されますが、そういったことが起こっても、少ない時間で対応方法が見つかる範囲にとどまることが多いと考えられます。

- SemVerでいう、「メジャー」レベルなら、多くの場合既存の資産（スクリプトとか設定）に破壊的な変更が入ることが大いに予想されます。ツールのサイトで新バージョンでの考え方・破壊的な変更点を確認することになるでしょう。親切なツールでは、移行のためのガイドが示されたりすることもあるでしょう。

##### 乗り換えるなら

- 多くの場合、使い慣れたツールには、「学習のために多くの時間が費やされ、多少の不便があっても目の前で動いており、実現したいことに向かっての使い方がある程度わかる」という属性があるはずです。このため、「乗り換える」に、コストが見合わないことも多いはずです。このエントリは、いたずらに乗り換えを進めるものではありません。
- とはいえ、「特にこだわりもなく使い始めたが情報が少なめで不便だった」「機能的に足りないので他のツールを探したい」場合も想定されることから、本エントリではWDR2020を引用しつつ、"乗り換えるなら"案を併記します。

#### Module Loader / Bundler

##### アップデートする/しない

- このカテゴリは、ここ数年、ツールの機能追加が続いており、数年前に選択したものを新しいバージョンにすることにはメリットが多いと考えられます

##### 乗り換えるなら

- WDR2020では、[webpack](https://webpack.js.org/)押しです。そのほかの選択肢としては[Parcel](https://parceljs.org/), [Rollup](https://rollupjs.org/guide/en/)があげられています。
- webpackを現在使っているなら、webpackそのままで進めばよいと筆者は思います。機能もドキュメントもコミュニティも充実しているし。
- 上記以外の以外を使っているなら、webpackの利用の検討をお勧めします（情報量、コミュニティの活発さの観点で）

#### Package Manager

##### アップデートする/しない

- このカテゴリは、[npm](https://www.npmjs.com/) vs [Yarn](https://classic.yarnpkg.com/ja/)の戦いにより、それぞれがよくなっており、バージョンを上げると機能アップと、場合によっては処理が早くなる効果も期待できるので、アップデートを検討する価値はあると思います。

##### 乗り換えるなら

- WDR2020では、npmとyarn押しです。
- npmかYarnを使っているなら、そのままの路線で筆者はよいと思います。Yarnという対抗馬が出てきたことにより、npm側も改善を入れてきているため、Yarn登場時ほどの乗り換えの圧は高くないはずです。

#### Task Runner

##### アップデートする/しない

- このカテゴリは、[npm scripts](https://docs.npmjs.com/misc/scripts)や[Gulp](https://gulpjs.com/)を含みます。npmなら、nodeのアップデートとともに新しいものを使っているはずです。

##### 乗り換えるなら

- WDR2020では、npm scripts押しです。
- npm-scripts、ビルドや前処理など必要なことは一通りできるし、nodeに最初から入っているし、記述内容もシンプルでエコシステムもあるし、ということで、筆者はnpm-scriptsで十分と考えます。ほかのツールを使っていても、シンプル化のために乗り換える価値があると思います。

#### Testing

##### アップデートする/しない

- テストに関しては、自身で書いたテストケースという資産があります。テストの実行が継続的に実現できている状態なら、目的は十分果たしているため、アップデートも急を要するものではないと想定されます。

##### 乗り換えるなら

- WDR2020的には、[Jest](https://jestjs.io/ja/)、[react-testing-library](https://github.com/testing-library/react-testing-library)、[Cypress](https://www.cypress.io/)、[Enzyme](https://github.com/enzymejs/enzyme)押しです（筆者からみると、React系の香りがします）。一方で、WDR2020的には推奨はしない扱いのものとして、[Mocha](https://mochajs.org/)、[Chai](https://www.chaijs.com/)、[Ava](https://github.com/avajs/ava)、[Jasmine](https://jasmine.github.io/) あたりがあげられています。
- TODO: この項目については、機会を改めてアップデートもしくは別エントリにします。（付記：WDR2020で上がっている中ではJestは使いどころが多そうであり、特定のSPAフレームワーク用にはそれを意識したツールキットが便利そうであり、E2Eをキャプチャしながら実行するのにはそれに適したツールがあり、という観点で比べるところいっぱいあって今日はおなかがいっぱい）


#### Linter / Formatter

##### アップデートする/しない

- LinterやFormatterは、ソースが綺麗に保てていることが重要であるため、言語側のアップデート対応等が必要ないのであれば急いでアップデートする必要性は低めだと思います。

##### 乗り換えるなら

- WDR2020的には、[Prettier](https://prettier.io/)、[ESLint](https://eslint.org/)が一押しです。
- ESLintは、長らく広く使われているツールなので、実用上はほぼすべてのアプリで使っているのではないでしょうかと筆者はみています。Prettierは、複数の言語/IDE・エディタで使えるフォーマッタであり、ESLintと組み合わせつつの利用もできます。IDEのフォーマッタで足りている場合は必要ないかもしれませんが、CIでの利用等含めチェックをいつも行うことを考えると、使うのもよいと思います。

# おわりに

このエントリでは、小規模なWEBフロントで、作ってしばらくたったものについて、JS系のツール周りを見直す時の考え方の例について扱います。

TODOにしたものは、遠からぬうちにまたエントリを書きたいと思います。