Edited at

Yarnやっていきはじめ

More than 1 year has passed since last update.


Yarnとは

YarnFastReliableSecure なパッケージマネジメントシステムです。

Facebook製でnpm互換があり、npmよりも高速だと話題です。

rails/webpackerなどもYarnを採用しており、これから色々な環境で使われていくのではないでしょうか。

そんなYarnを導入してみたので、その手順を書きます。


実際に速いのか

速かったです。下記が実際に現在のプロジェクトでベンチマークをとってみた結果です。

※ キャッシュと/node_modulesは削除しています。

コマンド
計測時間(5回平均)

$ time npm install
44.92s

$ time yarn install
22.10s

$ time yarn install --prefer-offline
16.81s

@pine613さんがGitHub Star上位100を対象にベンチマークを出している資料があります。依存数が多くなればなるほど、速くなり、Yarnの方が遅いパターンは存在しないとのことです。この発表を聞いて、導入してみようと思いました。

yarn VS. npm@2 VS. npm@3 // Speaker Deck


Yarnの導入

公式のInstallationに従ってインストールを進めます。Macの場合は、下記、2コマンドで済みます。


console

$ brew update

$ brew install yarn

.zshrcにPATHを追加。


.zshrc

export PATH="$PATH:`yarn global bin`"


上記でyarnコマンドが実行できるように🎉


console

$ yarn --version

0.19.1

$ yarn
[1/4] 🔍 Resolving packages...
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...
[4/4] 📃 Building fresh packages...
✨ Done in 18.95s.


よく使うnpmコマンドとyarnコマンドの置き換えはこちら

npm
yarn

$ npm init
$ yarn init

$ npm install -S PACKAGE
$ yarn add PACKAGE

$ npm install -D PACKAGE
$ yarn add -D PACKAGE

$ npm uninstall PACKAGE
$ yarn remove PACKAGE

$ npm install
$ yarn

ちなみに$ npm pruneコマンドの代替はなく、


console

$ yarn prune


yarn prune v0.19.1
error The prune command isn't necessary. `yarn install` will prune extraneous packages.
info Visit https://yarnpkg.com/en/docs/cli/prune for documentation about this command.

とのこと。賢いですね🙆


Yarnの運用

上述の通り、npmコマンドの箇所はyarnで置き換え可能なので、プロジェクトでnpmを使っていた箇所を置き換えていきましょう。この辺はプロジェクトで利用している技術次第なので、一例として、参考にしてください。Rails + Reactで開発していて、インフラ構築にAnsible、デプロイにCapistranoを利用しています。


package.json

- "build": "npm run clean && npm run webpack",

+ "build": "yarn run clean && yarn run webpack",


Procfile

- webpack: npm run dev

+ webpack: yarn run dev
rails: bundle exec rails server -p 3000

READMEに記述がある場合は変更しておきましょう。

続いて、デプロイ周り。


playbook.yml

- - yum: name=npm

+ - get_url: url=https://dl.yarnpkg.com/rpm/yarn.repo dest=/etc/yum.repos.d/yarn.repo
+ become: yes
+ - yum: name=yarn


Capfile

- require "capistrano/npm"

+ require "capistrano/yarn"


Gemfile

  # capistrano

gem 'capistrano'
gem 'capistrano-bundler'
- gem 'capistrano-npm'
gem 'capistrano-rails'
gem 'capistrano-rbenv'
+ gem 'capistrano-yarn'
gem 'capistrano3-puma'


config/deploy.rb

- # npm

- set :npm_flags, "--production --silent --no-progress"
- set :npm_roles, :web
- set :npm_env_variables, fetch(:npm_env_variables, {})
+ # yarn
+ set :yarn_flags, "--prefer-offline --production --no-progress"
+ set :yarn_roles, :web
+ set :yarn_env_variables, fetch(:yarn_env_variables, {})

- namespace :npm do
+ namespace :yarn do
task :build do
- on roles fetch(:npm_roles) do
- within fetch(:npm_target_path, release_path) do
- with fetch(:npm_env_variables, {}) do
- execute :npm, "run build"
+ on roles fetch(:yarn_roles) do
+ within fetch(:yarn_target_path, release_path) do
+ with fetch(:yarn_env_variables, {}) do
+ execute :yarn, "run build"
end
end
end
end
end

- before "npm:install", "npm:prune"
- after "npm:install", "npm:build"
+ after "yarn:install", "yarn:build"


最後にCircleCI。


circle.yml

machine:

timezone:
Asia/Tokyo
environment:
YARN_VERSION: 0.19.1
ruby:
version: 2.3.1
node:
version: 6.9.1
post:
- if [[ $(yarn --version 2>/dev/null) != "${YARN_VERSION}" ]]; then curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version $YARN_VERSION; fi
dependencies:
cache_directories:
- "~/.cache/yarn"
override:
- yarn install --prefer-offline
- bundle check --path=vendor/bundle || bundle install --path=vendor/bundle --jobs=4 --retry=3
test:
override:
- yarn run test
- bundle exec rspec --color --require spec_helper spec --format progress
- bundle exec rubocop


まとめ

上述の通り、テストやデプロイにかかる時間を短縮できるメリットがあり、簡単に置き換え可能なので、Yarnを導入してみてはいかがでしょうか。


参考

Yarn

yarn VS. npm@2 VS. npm@3 // Speaker Deck

amakanでyarnを使うようにした - ✘╹◡╹✘