NPMとYARN

## INTRO
node projectを作成する時によく使われるパッケージ管理ツールとして代表的なものは`npm`と`yarn`があります。
皆さんは普段どんなパッケージインストールモジュールを使っていますか？
また、皆さんは個の２つのツールについてよく説明できますでしょうか?
今日は個の２つのツールについて軽く話してみようと思います。

# npm
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76353/460e7097-03ef-d1f5-6ca6-bb5946fcd225.png)

>JavaScript言語のためのパッケージ管理者で、Node.jsの基本パッケージ管理者です。 世界で最も多くの人々が使用しているパッケージ管理ツールです。 このような管理ツールを利用して、Node.jsで作られたモジュールをウェブでダウンロードし、簡単にインストール·管理してくれるプログラムで、開発者の立場ではたった数行のcommandで既存の公開モジュールをインストールして活用できます。 (Javaでmavenと似たような役割をすると見ることができます)また、インストールされたモジュールがアップデートされているかをチェックするなど、JavaScriptで行うプロジェクトをとても楽に進めることができます。 command-line clientであるnpmとオンラインデータベースであるnpm registryから成り立っており、**一般にcommand-line clientをnpmと考えますが、実際、npmにはnpmregistryまで含まれています。**

このようなnpmがなかった場合は、必要とする機能を追加するために直接作成するか、githubを通じてダウンロードして使わなければなりませんでした。 これらの不具合を解消するために現れ、Node.jsを設置するだけで（基本的にnpmはNode.js内に内蔵されています）コマンド1行に機能を追加することが可能になります。

# yarn
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76353/b03adfee-13a9-9c22-0f88-ca70e92df575.png)

それなら、こんなに便利なNPMがあるのに、yarnというのはなぜ作られたのでしょうか？

>**yarn**は、Facebokで作ったJavascript Package Managerです。`npm`と同じ機能を実行します。しかし、事実`npm`と`yarn`について勉強しなくても、ある程度、プロジェクト経験がある方々は、`yarn`がもう少し軽い感じを受けて見たと思います。その理由は`yarn`の誕生背景にあります。
`yarn`は基本的に`npm`の短所を感じたからこれを向上させるために作られたマネージャーツールで、ここで言う`npm`の短所としては、**速度(performance)**、**安定性(stability)**、**保安省(security)**などがあります。

#### 速度（Perfomance）
yarnはダウンロードしたパッケージデータをキャッシュに保存し、重複するデータはダウンロードせずにキャッシュに保存されたファイルを活用することで理論的にnpmに比べてパッケージのインストール速度が非常に速いです。 また、複数の**パッケージを設置する際、並列に処理するためperformanceとspeedが増加**します。(npmは順次)

##### Parallel installation of packages, packages並列インストール
パッケージがインストールされると一連の作業を遂行します。 NPMで複数のパッケージをインストールする際、パッケージが完全にインストールされるまで待った後、他のパッケージをインストールします。 すなわち、ジョブはパッケージ毎に順次実行され感じです。  
しかし、YARNはこのような作業を並列に設置するため、パフォーマンスと速度が増加します。  
Reactをインストールした際、NPMとYARNの速度差はこうなります。  
NPM — 3.572 seconds
YARN — 1.44 seconds

#### 安定性(Stability)、保安性(Security)
npmは、パッケージをインストールする際に自動的にコードと依存性を実行できるようにしました。 この特徴は便利な機能ですが、安定性を脅かすことができます。 特に保証されたポリシーなしに登録したパッケージが存在し得るという点でさらにリスクが高いです。
しかし、**yarnはyarn.lock**や**package.json**からインストールするだけで、**yarn.lockはすべてのデバイスに同じパッケージをインストールすることを保障するため、バージョンの違いによって生じるバグを防止**することができます。

##### Automatic Lock file generation、自動lockファイル作成
`npm`と`yarn`いずれもパッケージでプロジェクトの従属性とバージョン番号を追跡します。 jsonファイルの従属性をインストールするたびに従属性バージョンがバージョン番号の前に`^`で始まります。 すなわち、他のシステムに全てのパッケージをインストールしたりインストールする命令を手動で実行するたびに、パッケージ管理者がリリースされた最新バージョンを探します。 最新バージョンがある場合、パッケージファイルに言及されたバージョンではなく自動にインストールされます。 パッケージを自動的に変更しないためには二つの方法があります。 一つはロックファイルを生成して一度に特定バージョンだけがインストールされます。もう一つはパッケージファイルから`^`を取り除くことである。
従属性が追加されると、`yarn`はyarn.lockファイルを自動に追加します。 `npm`は、`npm shrinkwrap`コマンドでロックファイルを生成します。 違いは、`npm`が基本的にlockファイルを生成しない時、`yarn`は常にyarn.lockファイルを生成し、アップデートするという意味になります。 `npm-shrinkwrap.json`が存在する場合にのみアップデートされます。 npmv5.0は、lock.jsonファイルと命名された新しいパッケージと共に提供され、npm-lapwrapシステムを完全に廃棄しました。 これは設置過程と性能を効率的に向上させたが、まだyarnの速度水準には至っていなかったです。

##### Security
`npm`は、他のパッケージを即時に含めることができるコードを自動で実行するので、セキュリティシステムに様々な脆弱性が発生可能性が高いです。 但し、`yarn`はyarn.lockまたはpackage.jsonファイルにあるファイルだけをインストールします。 したがって、`yarn`が`npm`パッケージよりセキュリティが強化されたものと見なされます。

## npmとyarnのコマンド
#### npmと、yarnで同じコマンド
| 内容 | NPM | YARN |
|:-:|:-:|:-:|
| make project or package | npm init  | yarn init  |
| start script| npm run  | yarn run  |
| run test | npm test  | yarn test  |
| login  | npm login(& logout)  | yarn login(& logout)  |
| make sym link  | npm link  | yarn link  |
| package publish or upgrade  | npm publish  | yarn publish  |
| local storage cache clear  | npm cache clear  | yarn cache clear  |

#### npmと、yarnで異なるコマンド
| コマンド | NPM | YARN |
|:-:|:-:|:-:|
| install dependencies | npm install  | yarn  |
| install package | npm install [package]  | yarn add [package]  |
| install dev packapge  | npm install --save-dev[ package]  | yarn add --dev [package]  |
| uninstall package  | npm uninstall [package]  | yarn remove [package]  |
| uninstall dev package  | npm uninstall --save-dev [package]  | yarn remove [package]  |
| update  | npm update  | yarn upgrade  |
| update package  | npm update [package]  | yarn upgrade [pakcage]  |
| global install package  | npm install --global [package]  | yarn global add [package]  |
| global install package  | npm uninstall --global [package]  | yarn global remove [package]  |

## npm? yarn? 何を使うべきなのか？
> 結論から言うと、**「各自に便利なものを使用するのが最も良いですが、もし両方使用していない状況であれば、npmを使用することをおすすめする」**です。

上に書いた、yarnについて、説明する時に、yarnがnpmに比べて向上したことについて話しました。実は、2016,2017年この時はyarnが歌詞的にはnpmよりスピードや、安定性が優秀しました。しかし、npmもこの何年間すごく発展し続けて、デメリとを十分にキャッチアップできましたので、現在のnpm/yarnのパフォーマンや、安定性はそんなに差が多くないとしても過言では無いです（まぁ、若干yarnのほうが優勢ではあります。)  

但し、述べたようにyarnの並列的パッケージインストールによる軽さ、またバージョン違いによるバグ防止などの機能はyarnがnpmよりも良いツールであると説明するに十分だと思います。
ですが、npmも確実に長所が存在します。 それはユーザ数とアクセス性です。 いくらyarnが良いからといって、援助は勝つことができないもので、perfomance上で確実にyarnにリードされていた時も、npmは固くpackagedmanagerの中で最も多くのユーザを保有していました。 現在も同様に最も多くのユーザーを保有しており、優れたアクセス性がこのような現象を引き起こしたと思われます。 yarnの場合、brewやnpmを通じてもう一度インストールしなければならない不便さがあるからです。

## まとめ、
それぞれの長所と短所がはっきりしていて、実質的な性能の面ではyarnがわずかに上に進んでいますが、初めて使う方にnpmをお勧めする理由は、まず**npmを直接使ってみないとyarnの必要性を判断できないからです。** ほとんどのyarnを使用し始めている方は、npmでプロジェクトを進行していましたが、package間のバージョン問題によってエラーを経験することが多いようです。
筆者本人は**npmを使ってみることで、直接このようなことにぶつかってみて、yarnというものがなぜ作られたのか、あるいはnpmだけでも十分な管理が可能なのか、そういった点を深く考え、これは開発者本人にとっても良い経験になるだろうと考えています。**

以上になります。
ありがとうございます。

[参考サイト](https://javascript.plainenglish.io/npm-vs-yarn-choosing-the-right-package-manager-a5f04256a93f)