npmについて 個人的解釈メモ

# npmを個人的に解説していく

まだまだエンジニア初心者だが、知識をアウトプットして定着させていく。
記事を書く上で質問がいくつかでるので、誰か回答求む。

1. [npmにまつわるファイル・フォルダ](#npmにまつわるファイル・フォルダ)
  1. [package.json](#package.json)
  1. [package-lock.json](#package-lock.json)
  1. [node-modules](#node-modules)
1. [package.jsonの中身について](#package.jsonの中身について)
  1. [name](#name)
  1. [version](#version)
  1. [private](#private)
  1. [homepage](#homepage)
  1. [dependencies](#dependencies)
  1. [scripts](#scripts)
1. [npm \<command> について](#npm \<command> について)
  1. [npm audit](#npm-audit)
  1. [npm ci](#npm-ci)
  1. [npm dedupe](#npm-dedupe)
  1. [npm init](#npm-init)
  1. [npm install](#npm-install)

疑問
----

- [[疑問]packAとpackBでpackCを用いているが、それぞれが使っているpackCのバージョンが違う場合、どちらがインストールされるの？](#[疑問]packAとpackBでpackCを用いているが、それぞれが使っているpackCのバージョンが違う場合、どちらがインストールされるの？)
- [[疑問]audit fix では修正されない場合ってどういうとき？？？](#[疑問]audit fix では修正されない場合ってどういうとき？？？)
- [[疑問]audit fix でアプデされるのはローカルのみ？？？](#[疑問]audit fix でアプデされるのはローカルのみ？？？)
- [[疑問]audit fix -f でもアプデされないパッケージは？？？](#[疑問]audit fix -f でもアプデされないパッケージは？？？)

## npmにまつわるファイル・フォルダ

pythonとかはAnaconda等用いて仮想環境を作ってライブラリをインストールする(pip コマンド)。
フォルダを変えても同一仮想環境なら再びインストールとかしなくてもライブラリを使用できる。

npmはプロジェクトごと(=rootディレクトリごと)にパッケージをインストールする。

### package.json

プログラマがnpm install によってインストールしたパッケージの一覧(=dependencies)がメイン。
他にもアプリを動作するうえでの必要な項目がいろいろ書かれている。詳細は下記参照

### package-lock.json

package.json のdependenciesにあるパッケージが用いているパッケージを総まとめにしたもの
例えば
パッケージが2つ、packAとpackBが使用しているパッケージが以下の様だったとする。

- packA
  - packC
  - packD
- packB
  - packC
  - packE

すると、package-lockでは、

- packA
- packB
- packC
- packD
- packE

が記述される(って解釈してます)。

##### [疑問]packAとpackBでpackCを用いているが、それぞれが使っているpackCのバージョンが違う場合、どちらがインストールされるの？

### node-modules

早い話がインストールしたパッケージのソースコードたち。

## package.jsonの中身について

公式サイト
> https://docs.npmjs.com/cli/v8/configuring-npm/package-json

### name

自分のパッケージを公開する際の名前？
公開する気が無くても、パッケージの区別のために名前をつけよう

> If you plan to publish your package, the most important things in your package.json are the name and version fields as they will be required. 


### version

nameと同じポジション

そのパッケージのバージョンを表す

> If you plan to publish your package, the most important things in your package.json are the name and version fields as they will be required. 

### private

trueにするとこのパッケージは公開されない

> If you set "private": true in your package.json, then npm will refuse to publish it.

### homepage

このパッケージのHPのURL

> The url to the project homepage.

### dependencies

このパッケージで利用しているパッケージたち
バージョンの指定等で書き方が様々ある様子
直接記入するのではなく`npm install`等を用いるべきだろう

### scripts

早い話がショートカット
下の例で`npm run start`をすると`bar ./test`が実行される

```
  "scripts": {
    "start" : "bar ./test"
  }
```

## npm \<command> について

よく見かけるものを抜粋

### npm audit

```
npm audit           Run a security audit

                    Usage:
                    npm audit [fix]

                    Options:
                    [--audit-level <info|low|moderate|high|critical|none>] [--dry-run] [-f|--force]
                    [--json] [--package-lock-only]
                    [--omit <dev|optional|peer> [--omit <dev|optional|peer> ...]]
                    [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
                    [-ws|--workspaces]

                    Run "npm help audit" for more info
```

audit : 監査

インストールされているパッケージに脆弱性があるかをチェックする。
ここでいう脆弱性とは

**パッケージのセキュリティ面に穴があり、ユーザーに攻撃される恐れがあるよ**

ってイメージだと思う。
古いバージョンでは脆弱性が見つかったので、新しいやつに更新してね、ていうパッケージをこのコマンドで知らせてくれる。
試しに実行した結果：

```
react-dev-utils  0.4.0 - 12.0.0-next.60　-> [このパッケージのこのバージョンは]
Severity: high -> [脆弱性 high ]
Improper Neutralization of Special Elements used in an OS Command. - https://github.com/advisories/GHSA-5q6m-3h65-w53x
Depends on vulnerable versions of browserslist -> [脆弱性をもつこれらのパッケージのバージョンを使用している( = 依存している)]
Depends on vulnerable versions of globby
Depends on vulnerable versions of immer
Depends on vulnerable versions of inquirer
fix available via `npm audit fix --force` -> [このコマンドで修正してね]
Will install react-scripts@5.0.0, which is a breaking change -> [すると react-scripts@5.0.0　をインストールするけど、めっちゃ変更点あるよ]
node_modules/react-dev-utils
  react-scripts  >=0.8.0
  Depends on vulnerable versions of @svgr/webpack
  Depends on vulnerable versions of @typescript-eslint/eslint-plugin
  Depends on vulnerable versions of eslint
  Depends on vulnerable versions of eslint-config-react-app
  Depends on vulnerable versions of eslint-loader
  Depends on vulnerable versions of jest-watch-typeahead
  Depends on vulnerable versions of optimize-css-assets-webpack-plugin
  Depends on vulnerable versions of react-dev-utils
  Depends on vulnerable versions of resolve-url-loader
  Depends on vulnerable versions of webpack-dev-server
  node_modules/react-scripts
```

#### npm audit fix

auditはチェックするだけだが、audit fix で実際にパッケージが更新される。
audit fix では修正されない場合、オプションに -force をつけて無理くりアプデするらしい。
また、パッケージが更新されてプログラムが動く保証はないので、ブランチを分けるなど、慎重にすること。

##### [疑問]audit fix では修正されない場合ってどういうとき？？？

##### [疑問]audit fix でアプデされるのはローカルのみ？？？

##### [疑問]audit fix -f でもアプデされないパッケージは？？？

> 脆弱性の警告を受けたnpmパッケージの依存関係を力技で直す
> https://qiita.com/hibikikudo/items/0af352acac85fce28ec2
> npmパッケージの脆弱性を自動チェックして対応する方法 – 2つの簡単な工夫を紹介
> https://thilog.com/npm-security-check/

### npm ci

```
    ci              npm ci

                    Install a project with a clean slate

                    Usage:
                    npm ci

                    Options:
                    [--no-audit] [--ignore-scripts] [--script-shell <script-shell>]

                    aliases: clean-install, ic, install-clean, isntall-clean

                    Run "npm help ci" for more info
```

clear install

npm install と似ているが、

- package-lock.json or npm-shrinkwrap.json が必須
- それらが package.json の記述と矛盾する場合、エラー
- 依存追加には使えない。（npm install xxx でやる）
- node_modules はいったん全消しされる
- npm installはpackage-lock.json を更新することがしばしばあるが、npm ci はpackage-lock.jsonに基づいてインストールするため、そういったことは起きない

>https://ginpen.com/2019/12/04/npm-install-vs-ci/
>>npm install は package-lock.json を更新することがしばしばあります。
>>理由は package.json に記述する semver が幅のあるバージョンを許すためで、また package-lock.json は（”lock” という名前に反して）node_modules の実際を反映するものだからです。

### npm dedupe

```
    dedupe          npm dedupe

                    Reduce duplication in the package tree

                    Usage:
                    npm dedupe

                    Options:
                    [--global-style] [--legacy-bundling] [--strict-peer-deps] [--no-package-lock]
                    [--omit <dev|optional|peer> [--omit <dev|optional|peer> ...]] [--ignore-scripts]
                    [--no-audit] [--no-bin-links] [--no-fund] [--dry-run]
                    [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
                    [-ws|--workspaces]

                    alias: ddp

                    Run "npm help dedupe" for more info
```

deduplication : 重複排除

パッケージの重複を無くす
シンプルにやるだけお得なんじゃね？

> npm dedupeでモジュールの重複を解消する
> https://qiita.com/totto357/items/585b6bb225021f723c5e

### npm init

```
    init            npm init

                    Create a package.json file

                    Usage:
                    npm init [--force|-f|--yes|-y|--scope]
                    npm init <@scope> (same as `npx <@scope>/create`)
                    npm init [<@scope>/]<name> (same as `npx [<@scope>/]create-<name>`)

                    Options:
                    [-y|--yes] [-f|--force]
                    [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
                    [-ws|--workspaces]

                    aliases: create, innit

                    Run "npm help init" for more info
```

initialize : 初期化
package.json が作成される。

> npm init しないとどうなる？
> https://qiita.com/sugurutakahashi12345/items/1049a33b86225f6345fe

### npm install

```
    install         npm install

                    Install a package

                    Usage:
                    npm install [<@scope>/]<pkg>
                    npm install [<@scope>/]<pkg>@<tag>
                    npm install [<@scope>/]<pkg>@<version>
                    npm install [<@scope>/]<pkg>@<version range>
                    npm install <alias>@npm:<name>
                    npm install <folder>
                    npm install <tarball file>
                    npm install <tarball url>
                    npm install <git:// url>
                    npm install <github username>/<github project>

                    Options:
                    [-S|--save|--no-save|--save-prod|--save-dev|--save-optional|--save-peer]
                    [-E|--save-exact] [-g|--global] [--global-style] [--legacy-bundling]
                    [--strict-peer-deps] [--no-package-lock]
                    [--omit <dev|optional|peer> [--omit <dev|optional|peer> ...]] [--ignore-scripts]
                    [--no-audit] [--no-bin-links] [--no-fund] [--dry-run]
                    [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
                    [-ws|--workspaces]

                    aliases: i, in, ins, inst, insta, instal, isnt, isnta, isntal, add

                    Run "npm help install" for more info
```

一番の大玉。
普通、installをすると、

1. package.json のdependenciesに追記
1. インストールするパッケージが用いているpackageをpackage-lock.json に記載
1. node_modulesにパッケージをインストール

的な流れをする。
ここで、インストールの仕方にはいくつかり、

#### ローカルかグローバルか [-global]

ローカルは現在のプロジェクトでのみ使い、グローバルはプロジェクト間を超えて使えるようになる。
詳しくは下記

> きちんとわかる、npm install  第1回
> https://www.codegrid.net/articles/2020-npm-install-1/

#### dependenciesに記載するか [--save]

[--save]によって install する際にdependenciesにも記載する
が、今のバージョンではデフォルトで記載されるらしい

> npm よく使うコマンドまとめ
> https://qiita.com/standard-software/items/2ac49a409688733c90e7#%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB

#### 開発のときのみ使うパッケージか [--save-dev]

[--save-dev]によって、package.json の devDependencies欄 にパッケージ名が記録される。
リリースする際には不要なパッケージなどを記載する。

### npm prefix

```
    prefix          npm prefix

                    Display prefix

                    Usage:
                    npm prefix [-g]

                    Options:
                    [-g|--global]

                    Run "npm help prefix" for more info
```

prefix : 接頭語

npm を実行する際のディレクトリを示す
結局のところ、`npm prefix`は現在のディレクトリと等価

`npm prefix -g` で、グローバルパッケージの所在わかる

`npm prefix`と直接は関係ないが、prefixの使い方は下記参照

> npm run command --prefix directory でサブディレクトリのコマンドを実行する。
> https://blog.rhyztech.net/npm_prefix/

### npm run-script

```
    run-script      npm run-script

                    Run arbitrary package scripts

                    Usage:
                    npm run-script <command> [-- <args>]

                    Options:
                    [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
                    [-ws|--workspaces] [--if-present] [--ignore-scripts]
                    [--script-shell <script-shell>]

                    aliases: run, rum, urn

                    Run "npm help run-script" for more info
```

npm run の使われ方の方が多い。
`config.json`の`scripts`に書かれているコマンドを実行する

`npm run <command>` のcommmandに、config.jsonに書かれているコマンドを記述する

### npm uninstall

```
    uninstall       npm uninstall

                    Remove a package

                    Usage:
                    npm uninstall [<@scope>/]<pkg>...

                    Options:
                    [-S|--save|--no-save|--save-prod|--save-dev|--save-optional|--save-peer]
                    [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
                    [-ws|--workspaces]

                    aliases: un, unlink, remove, rm, r

                    Run "npm help uninstall" for more info
```

デフォルトでは、node_modulesからパッケージを消すだけ。
`package.json`等にはリストに残っているので、再度`npm install`をするとインストールされる。

`--save`はDependenciesからの削除
`--save-dev`はdevDependenciesからの削除
`--g`はグローバルパッケージの削除

> npmのuninstallコマンドを忘れがちなのでメモ
> https://qiita.com/mamosan/items/6f1cf71ccd82216fe25b