[npm & Bower] Yarn 入門: npm との違いを探る
Yarn は、Facebook, Exponent, Google, Tilde によって開発されたパッケージマネージャ。
npm のより良いCLIクライアントという位置づけで、置き換える技術ではありません。
[markdown]
> * [Yarn: A new package manager for JavaScript | Engineering Blog | Facebook Code | Facebook](https://code.facebook.com/posts/1840075619545360)
[Ruby on Rails 5.1 も Yarn をサポート](https://railsguides.jp/5_1_release_notes.html#yarn%E3%81%AE%E3%82%B5%E3%83%9D%E3%83%BC%E3%83%88)しましたので、いまこそ入門のタイミングでしょうか。
npm から乗り換える視点で、調査してみました。
## Yarn の特徴
npm と比較して、主に以下のような特徴があります。
> * [Yarn](https://yarnpkg.com/en/)
1. インストールにキャッシュを利用するので **ウルトラ速い**
2. checksums を見るので **メガ安全**
3. yarn.lock でパッケージを管理するので **スーパー確実**
## Installation
`brew install` できます。
> * [Installation | Yarn](https://yarnpkg.com/en/docs/install)
“`prettyprinted
% brew update
% brew install yarn
% yarn –version
0.24.6
“`
npm については、以下のバージョンと比較します。
“`prettyprinted
% npm -v
4.2.0
“`
> * [CLI Introduction | Yarn](https://yarnpkg.com/en/docs/cli/)
### npm -> Yarn 乗り換え時の注意
yarn でインストールされるパッケージは、npm と同じく `node_modules/` 以下に配置されます。
しかしながらファイル配置は `diff -rq` などで確認すると異なります。
`yarn` と `npm` を混ぜて利用しない方が良さそうです。
以下は、`yarn` で作成された `node_modules/` がある状態で、`npm list` を実行した結果です。
エラーが発生しています。
“`prettyprinted
% npm list –depth 0
yarn_project@1.0.0 /Users/****/projects/sandbox-yarn/yarn_project
├── node-pre-gyp@0.6.34 extraneous
├── react@15.5.4
└── webpack@2.6.0
npm ERR! extraneous: node-pre-gyp@0.6.34 /Users/****/projects/sandbox-yarn/yarn_project/node_modules/node-pre-gyp
“`
**npm -> Yarn への乗り換え時には node_modules/ を削除して作り直す** と安全でしょう。
## Usage: パッケージの管理
プロジェクト単位でパッケージを管理する方法を確認します。
### package.json の生成
npm と同じく package.json を利用します。
> * [yarn init | Yarn](https://yarnpkg.com/en/docs/cli/init)
|npm |Yarn |
|:———|:———-|
|`npm init`|`yarn init`|
“`prettyprinted
% yarn init
yarn init v0.24.6
question name (yarn_project):
question version (1.0.0):
question description:
question entry point (index.js):
question repository url:
question author:
question license (MIT):
success Saved package.json
✨ Done in 5.34s.
“`
> * [package.json | Yarn](https://yarnpkg.com/en/docs/package-json)
“`json:package.json
{
“name”: “yarn_project”,
“version”: “1.0.0”,
“main”: “index.js”,
“license”: “MIT”
}
“`
package.json が存在する場合は、以下でまとめてインストールできます。
|npm |Yarn |
|:————|:————-|
|`npm install`|`yarn install`|
### パッケージの追加
プロジェクトに必要なパッケージを追加します。
あわせてインストールも行います。
> * [yarn add | Yarn](https://yarnpkg.com/en/docs/cli/add)
|npm |Yarn |
|:———|:———-|
|`npm install –save [package]`|`yarn add [package]`|
“`prettyprinted
% yarn add react
yarn add v0.24.6
info No lockfile found.
[1/4] 🔍 Resolving packages…
[2/4] 🚚 Fetching packages…
[3/4] 🔗 Linking dependencies…
[4/4] 📃 Building fresh packages…
success Saved lockfile.
success Saved 17 new dependencies.
├─ asap@2.0.5
:
└─ whatwg-fetch@2.0.3
✨ Done in 4.64s.
“`
package.json や yarn.lock が無い場合は、自動で生成されます。
“`json:package.json
{
“dependencies”: {
“react”: “^15.5.4”
}
}
“`
プロジェクトの開発に必要なパッケージは、オプションを付けて実行します。
|npm |Yarn |
|:———|:———-|
|`npm install –save-dev [package]`|`yarn add [package] [–dev/-D]`|
“`prettyprinted
% yarn add –dev webpack
“`
### パッケージの削除
パッケージの削除は、同じコマンドで削除できます。
> * [yarn remove | Yarn](https://yarnpkg.com/en/docs/cli/remove)
|npm |Yarn |
|:———|:———-|
|`npm uninstall –save [package]`|`yarn remove [package]`|
|`npm uninstall –save-dev [package]`|`yarn remove [package]`|
“`prettyprinted
% yarn remove react
yarn remove v0.24.6
[1/2] Removing module react…
[2/2] Regenerating lockfile and installing missing dependencies…
success Uninstalled packages.
✨ Done in 3.44s.
“`
### パッケージのアップグレード
**アップグレードコマンドが用意されています。**
> * [yarn outdated | Yarn](https://yarnpkg.com/en/docs/cli/outdated)
> * [yarn upgrade | Yarn](https://yarnpkg.com/en/docs/cli/upgrade)
|npm |Yarn |
|:———|:———-|
|`npm outdated [package]`|`yarn outdated [package]`|
|[package.json を書き換えて](https://www.d-wood.com/blog/2015/12/15_7728.html#update) `npm update ` ※1|`yarn upgrade [package]`|
※1 普段は [npm-check-updates](https://www.d-wood.com/blog/2014/09/01_6692.html) を利用しています。他に方法があるかも知れません。
“`prettyprinted
% yarn outdated
% yarn upgrade
“`
### パッケージの掃除
install, update などでたまったパッケージを掃除します。
> * [yarn clean | Yarn](https://yarnpkg.com/en/docs/cli/clean)
|npm |Yarn |
|:———|:———-|
|`npm prune`|`yarn clean`|
“`prettyprinted
% yarn clean
yarn clean v0.24.6
[1/2] Creating “.yarnclean”…
[2/2] Cleaning modules…
info Removed 1552 files
info Saved 4.93 MB.
✨ Done in 3.15s.
“`
## Usage: scripts の実行
package.json に設定した scripts を実行できます。
> * [yarn run | Yarn](https://yarnpkg.com/lang/en/docs/cli/run/)
|npm |Yarn |
|:—————–|:——————|
|`npm run [script]`|`yarn run [script]`|
[DriftwoodJP/sandbox-es6](https://github.com/DriftwoodJP/sandbox-es6) をサンプルに実行してみます。
“`prettyprinted
% yarn install
yarn install v0.24.6
info No lockfile found.
[1/4] 🔍 Resolving packages…
warning serve > fs-promise@1.0.0: Use mz or fs-extra^3.0 with Promise Support
[2/4] 🚚 Fetching packages…
warning There appears to be trouble with your network connection. Retrying…
[3/4] 🔗 Linking dependencies…
[4/4] 📃 Building fresh packages…
success Saved lockfile.
✨ Done in 73.37s.
“`
`lint` タスクを実行してみます。
“`prettyprinted
% npm run lint
> sandbox-es6@0.2.10 lint /Users/****/projects/sandbox-yarn/sandbox-es6
> eslint src/ test/
% yarn run lint
yarn run v0.24.6
$ eslint src/ test/
✨ Done in 1.15s.
“`
問題なさそうです。
### bin
package.json で管理しているパッケージのコマンドをカレントプロジェクト内で実行したい場合にも、yarn 経由で同じように利用できます。
> * [yarn bin | Yarn](https://yarnpkg.com/en/docs/cli/bin)
|npm |Yarn |
|:——–|:———|
|`npm bin`|`yarn bin`|
“`prettyprinted
% $(npm bin)/webpack -v
2.6.0
% $(yarn bin)/webpack -v
2.6.0
“`
追記:2018/11/06
ローカルプロジェクトのコマンドは `npx` 及び `yarn run` で実行できます。
|npm |Yarn |
|:——–|:———|
|`npx [command]`|`yarn run [command]`|
“`prettyprinted
% yarn run webpack -v
yarn run v1.10.1
$ /Users/***/foo/node_modules/.bin/webpack -v
4.17.2
✨ Done in 0.47s.
% npx webpack -v
4.17.2
“`
## Usage: global インストール
`yarn global` コマンドを利用することで、グローバルで利用するパッケージの管理が可能です。
### global install path
brew install した yarn の場合、以下のようなパスになりました。
“`prettyprinted
% yarn global bin
/usr/local/Cellar/node/7.10.0/bin
“`
パスの変更には `~/.npmrc` の設定を活かせます。
> * [Node を Homebrew でインストールした場合でも npm をうまく利用したい(global install 編) | deadwood](https://www.d-wood.com/blog/2015/12/14_7721.html#Homebrew_node_modules)
“`prettyprinted:~/.npmrc
prefix=/Users/****/local/lib/node_modules
“`
shell にパスを通します。
“`prettyprinted:~/.zshrc
# for npm
if [ -d $HOME/local/lib/node_modules/bin ]; then
export PATH=$PATH:$HOME/local/lib/node_modules/bin
fi
“`
変更後のパスはこうなりました。
“`prettyprinted
% yarn global bin
/Users/****/local/lib/node_modules/bin
“`
npm から yarn に乗り換える場合には、ディレクトリを一度削除する必要があります。
“`prettyprinted
% sudo rm -rf ~/local/lib/node_modules/
“`
### パッケージの追加・削除・アップグレード
`yarn global` コマンドを実行します。
> * [yarn global | Yarn](https://yarnpkg.com/en/docs/cli/global)
|npm |Yarn |
|:———|:———-|
|`npm install –global [package]`|`yarn global add [package]`|
|`npm uninstall –global [package]`|`yarn global remove [package]`|
|`npm list –global`|`yarn global ls`|
|`npm update –global`|`yarn global upgrade`|
“`prettyprinted
% yarn global add electron eslint
yarn global v0.24.6
[1/4] 🔍 Resolving packages…
warning electron > electron-download > nugget > progress-stream > through2 > xtend > object-keys@0.4.0:
[2/4] 🚚 Fetching packages…
[3/4] 🔗 Linking dependencies…
[4/4] 📃 Building fresh packages…
success Installed “electron@1.6.8” with binaries:
– electron
success Installed “eslint@3.19.0” with binaries:
– eslint
✨ Done in 40.65s.
% yarn global ls
yarn global v0.24.6
warning No license field
info “electron@1.6.8” has binaries:
– electron
info “eslint@3.19.0” has binaries:
– eslint
✨ Done in 1.66s.
% ls ~/local/lib/node_modules/bin
electron@ eslint@
“`
## まとめ
– Yarn は npm の wrapper
– node_modules/ 以下を作り直して利用する
node_modules/ を作り直せば変わらず使える、というか便利になるという印象。
簡単に確認した限りでは、不具合もなさそう。
今後のプロジェクトでは、積極的に採用していくつもりです。
## 追記: npm v5.0
書いた数日後に npm@5 がリリースされたので補足。
> * [The npm Blog — v5.0.0](http://blog.npmjs.org/post/161081169345/v500)
> * [npm v5 がリリースされた – from scratch](http://yosuke-furukawa.hatenablog.com/entry/2017/05/30/090602)
## 補遺
npm の情報。
> * [Node を Homebrew でインストールした場合でも npm をうまく利用したい(global install 編) | deadwood](https://www.d-wood.com/blog/2015/12/14_7721.html)
> * [Node を Homebrew でインストールした場合でも npm をうまく利用したい(local install 編) | deadwood](https://www.d-wood.com/blog/2015/12/15_7728.html)
> * [npm: run-script でタスクランナーから解放される | deadwood](https://www.d-wood.com/blog/2015/12/10_7716.html)
`yarn licenses`, `yarn why`, `yarn generate-lock-entry`
> * [Migrating from npm | Yarn](https://yarnpkg.com/en/docs/migrating-from-npm#toc-cli-commands-comparison)
> * [Yarnとnpmの違い:JavaScriptパッケージマネジャーを比較する – WPJ](https://www.webprofessional.jp/yarn-vs-npm/)
[/markdown]