npm package をアップデートしたい時の便利なコマンド

# npm package をアップデートしたい時のコマンド
npm packageをアップデートしたい時によく使用するコマンドについてまとめます。

今回packageを見ていくのは [vue-hackernews-2.0](https://github.com/vuejs/vue-hackernews-2.0) をです。

```
$ git clonse https://github.com/vuejs/vue-hackernews-2.0.git
$ cd vue-hackernews-2.0
```

## npm outdated
outdatedコマンドは、レジストリをチェックして、インストールされている（または特定の）パッケージが現在古くなっているかどうかを確認する。
デフォルトでは、ルートプロジェクトの直接の依存関係と構成されたワークスペースの直接の依存関係のみが表示する。
--allすべての古いメタ依存関係も検索するために使用する。

https://docs.npmjs.com/cli/v7/commands/npm-outdated

### 実行

```
$ npm outdated
Package                     Current   Wanted  Latest  Location
autoprefixer                  7.2.6    7.2.6  10.2.6  vue-hackernews-2.0
babel-loader                  7.1.5    7.1.5   8.2.2  vue-hackernews-2.0
chokidar                      1.7.0    1.7.0   3.5.2  vue-hackernews-2.0
cross-env                     5.2.1    5.2.1   7.0.3  vue-hackernews-2.0
css-loader                  0.28.11  0.28.11   5.2.6  vue-hackernews-2.0
file-loader                  1.1.11   1.1.11   6.2.0  vue-hackernews-2.0
firebase                      4.6.2    4.6.2   8.6.8  vue-hackernews-2.0
lru-cache                     4.1.5    4.1.5   6.0.0  vue-hackernews-2.0
rimraf                        2.7.1    2.7.1   3.0.2  vue-hackernews-2.0
route-cache                   0.4.3    0.4.3   0.4.5  vue-hackernews-2.0
stylus-loader                 3.0.2    3.0.2   6.1.0  vue-hackernews-2.0
sw-precache-webpack-plugin   0.11.5   0.11.5   1.0.0  vue-hackernews-2.0
url-loader                    0.6.2    0.6.2   4.1.1  vue-hackernews-2.0
vue                          2.6.12   2.6.14  2.6.14  vue-hackernews-2.0
vue-server-renderer          2.6.12   2.6.14  2.6.14  vue-hackernews-2.0
vue-template-compiler        2.6.12   2.6.14  2.6.14  vue-hackernews-2.0
webpack                      3.12.0   3.12.0  5.39.1  vue-hackernews-2.0
webpack-dev-middleware       1.12.2   1.12.2   5.0.0  vue-hackernews-2.0
webpack-merge                 4.2.2    4.2.2   5.8.0  vue-hackernews-2.0
webpack-node-externals        1.7.2    1.7.2   3.0.0  vue-hackernews-2.0p
```

current： 現在インストールされているバージョン
wanted： 存在するバージョンのうち、 package.json に記載された semver 条件を満たす最新のバージョン。
Latest： レジストリで最新としてタグ付けされているパッケージのバージョン
Location： 物理ツリーのどこにパッケージが配置されているか

※ semverとは？
Semantic Versioning の略
3.14.1
一番左側の数字をメジャーバージョン、真ん中の数字をマイナーバージョン、一番右側の数字をパッチバージョン
パッチバージョン：後方互換性のあるバグ修正やドキュメントの変更などをした場合、パッチバージョンの値をひとつ大きくする。
マイナーバージョン：後方互換性のある機能追加とドキュメントの追記をした場合、マイナーバージョンの値をひとつ大きくする。
メジャーバージョン：後方互換性のない変更がある場合、メジャーバージョンの値をひとつ大きくする。

## npm update
このコマンドはtag、semverを尊重して、リストされているすべてのパッケージを最新バージョン（構成で指定）に更新する。
また、不足しているパッケージもインストールする。
マイナーバージョンまで最新化される。

https://docs.npmjs.com/cli/v7/commands/npm-update

### 実行

```
$ npm update                           
npm WARN ajv-keywords@3.5.2 requires a peer of ajv@^6.9.1 but none is installed. You must install peer dependencies yourself.

+ vue-template-compiler@2.6.14
+ vue@2.6.14
+ vue-server-renderer@2.6.14
updated 3 packages and audited 1001 packages in 4.595s

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

found 15 vulnerabilities (4 low, 8 moderate, 3 high)
  run `npm audit fix` to fix them, or `npm audit` for details
```

+ vue-template-compiler@2.6.14
+ vue@2.6.14
+ vue-server-renderer@2.6.14
の3つのパッケージがlatest（マイナーバージョンの最新バージョン）に更新されました。


## npm audit 
auditコマンドは、プロジェクトで構成されている依存関係の説明をデフォルトのレジストリに送信し、既知の脆弱性のレポートを要求する。
脆弱性が見つかった場合は、影響と適切な修正が必要な箇所が表示される。

https://docs.npmjs.com/cli/v7/commands/npm-audit

low（低レベル）, moderate（中レベル）, high（高レベル）, critical（致命的） の 4種類に分かれます。（infoというのもあります。）
https://docs.npmjs.com/cli/v7/commands/npm-audit#audit-level 

基本的に全てに対応したいですが、BreakingChangeなどもありなかなか対応できないものもあります。しかしcriticalとhighについては絶対対応すべきです。

### 実行

```
$ npm audit
.....

found 15 vulnerabilities (4 low, 8 moderate, 3 high) in 1001 scanned packages
  run `npm audit fix` to fix 2 of them.
  12 vulnerabilities require semver-major dependency updates.
  1 vulnerability requires manual review. See the full report for details..

（訳）
スキャンした1001個のパッケージから15個の脆弱性（低4個、中8個、高3個）が見つかりました。
  npm audit fix` を実行して、そのうちの2つを修正しました。
  12個の脆弱性は準メジャーな依存関係の更新が必要です。
  1つの脆弱性は手動でのレビューが必要です。詳細は報告書の全文をご覧ください。。
```

```
┌───────────────┬──────────────────────────────────────────────────────────────┐
│ High          │ Regular Expression Denial of Service                         │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ normalize-url                                                │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ css-loader [dev]                                             │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ css-loader > cssnano > postcss-normalize-url > normalize-url │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://npmjs.com/advisories/1755                            │
└───────────────┴──────────────────────────────────────────────────────────────┘
```

More info の URIにアクセスすると脆弱性内容の詳細を見ることができます。

今回は、
https://www.npmjs.com/advisories/1755

```
Overview
The xmlhttprequest-ssl package before 1.6.1 for Node.js disables SSL certificate validation by default, because rejectUnauthorized (when the property exists but is undefined) is considered to be false within the https.request function of Node.js. In other words, no certificate is ever rejected.

Remediation
Upgrade to version 1.6.1 or later


（訳）
概要
Node.jsの1.6.1以前のxmlhttprequest-sslパッケージは、デフォルトでSSL証明書の検証を無効にしています。これは、Node.jsのhttps.request関数内でrejectUnauthorized（プロパティが存在するが未定義の場合）がfalseとみなされるためです。つまり、証明書が拒否されることはない。

対応策
バージョン1.6.1以降にアップグレードする。
```

正規表現を使ったDoS攻撃（ReDoS）を食らう危険があるらしい。。。


### 自動で修正する方法
npm audit コマンドには脆弱性のある箇所を自動修正してくれるサブコマンドfixがあります

```
$ npm audit fix
```

```
found 13 vulnerabilities (3 low, 7 moderate, 3 high) in 1001 scanned packages
  12 vulnerabilities require semver-major dependency updates.
  1 vulnerability requires manual review. See the full report for details.
```


## npm ls
lsコマンドは、インストールされているパッケージのすべてのバージョンと依存関係をツリー構造で標準出力に出力する。

https://docs.npmjs.com/cli/v7/commands/npm-ls

### 実行
今回は npm audit コマンドで脆弱性 high の normalize-url について見てみます。
`npm ls <package名>`

```
$ npm ls normalize-url       
vue-hackernews-2.0@ /Users/taimikam/workspace/vue-hackernews-2.0
└─┬ css-loader@0.28.11
  └─┬ cssnano@3.10.0
    └─┬ postcss-normalize-url@3.0.8
      └── normalize-url@1.9.1 
```


## npm dedupe
ローカルパッケージツリーを検索し、依存関係をツリーのさらに上に移動することで全体的な構造を単純化しようとする。依存関係は、複数の依存パッケージでより効果的に共有できる。

https://docs.npmjs.com/cli/v7/commands/npm-dedupe


以下のような依存関係ツリーがあるとする。

```
a
+-- b <-- depends on c@1.0.x
|   `-- c@1.0.3
`-- d <-- depends on c@~1.0.9
    `-- c@1.0.10
```

npm dedupe は以下のように変換する。

```
a
+-- b
+-- d
`-- c@1.0.10
```

# その他便利packageについて
## npm-check-updates

https://github.com/raineorshine/npm-check-updates
npm-check-updatesは、指定されたバージョンを無視して、package.jsonの依存関係を最新バージョンにアップグレードします。

## 実行

```❯
❯ ncu           
Checking /Users/hoge/workspace/vue-hackernews-2.0/package.json
[====================] 35/35 100%

 compression                      ^1.7.1  →   ^1.7.4     
 cross-env                        ^5.1.1  →   ^7.0.3     
 es6-promise                      ^4.1.1  →   ^4.2.8     
 express                         ^4.16.2  →  ^4.17.1     
 firebase                          4.6.2  →    8.6.8     
 lru-cache                        ^4.1.1  →   ^6.0.0     
 serve-favicon                    ^2.4.5  →   ^2.5.0     
 vue-router                       ^3.0.1  →   ^3.5.1     
 vuex                             ^3.0.1  →   ^3.6.2     
 autoprefixer                     ^7.1.6  →  ^10.2.6     
 babel-core                      ^6.26.0  →  ^6.26.3     
 babel-loader                     ^7.1.2  →   ^8.2.2     
 babel-preset-env                 ^1.6.1  →   ^1.7.0     
 chokidar                         ^1.7.0  →   ^3.5.2     
 css-loader                      ^0.28.7  →   ^5.2.6     
 file-loader                      ^1.1.5  →   ^6.2.0     
 friendly-errors-webpack-plugin   ^1.6.1  →   ^1.7.0     
 rimraf                           ^2.6.2  →   ^3.0.2     
 stylus                          ^0.54.5  →  ^0.54.8     
 stylus-loader                    ^3.0.1  →   ^6.1.0     
 sw-precache-webpack-plugin      ^0.11.4  →   ^1.0.0     
 url-loader                       ^0.6.2  →   ^4.1.1     
 vue-loader                      ^15.3.0  →  ^15.9.7     
 webpack                          ^3.8.1  →  ^5.39.1     
 webpack-dev-middleware          ^1.12.0  →   ^5.0.0     
 webpack-hot-middleware          ^2.20.0  →  ^2.25.0     
 webpack-merge                    ^4.2.1  →   ^5.8.0     
 webpack-node-externals           ^1.7.2  →   ^3.0.0  
```

現在のバージョン → 最新バージョン を表示してくれます。

`ncu -u` を実行すると package.jsonを強制的に最新packageを使用するように書き換えてくれます。


# 最後に
今回紹介した以外にも npm package を更新するのに便利なコマンドがあると思います。
CIなどと組み合わせて自動更新スクリプトを組むのも良いかもしれませんね。