yarn から npm に出戻ろうとしている話

こんにちは, 今年の freee の新卒エンジニアで会計freee の開発をしているけむりだま (@_kemuridama) です. この記事は freee Developers Advent Calendar 2018 の 11 日目の記事になります 🎄

今回は freee の中で最も大きなプロダクトである会計freee で使っている JavaScript パッケージマネージャを yarn から npm に出戻ろうとしている話をしていこうと思います.

なぜやるのか 🤔

yarn から npm に戻ろうとしている理由は, 下記のブログで説明されている通り, npm がアップデートしていくのに従って yarn と性能が変わらなくなってきたためです.

engineering.mixmax.com

まず, yarn は並列インストールができるため npm よりパッケージインストールが高速でした. しかし, npm 5 から改良が進められ npm 6 では yarn とほぼ同等の速度でパッケージのインストールが可能になりました.

次に npm 5 から package-lock.json というロックファイルが生成されるようになりました. これは yarn における yarn.lock というロックファイルに代替されるものです. 古い npm も shrinkwrap によってロックファイルが生成できましたが, 環境によってインストールの構成が変わってしまうといった不具合を抱えていたため, チーム開発を行う上で問題になることがしばしばありました.

出戻るための道のり 🚶

yarn に出戻る上でまず会計freee のフロントエンドで課題になっていったことを解決しました.

まず, Babel 7 の正式版の導入です. 会計freee では半年弱 Babel 7 の Alpha 版を使っていました. 8 月の終わりに正式版が出ていたので Alpha 版から正式版へアップデートしました.

次に Node.js のアップデートです. 会計freee のフロントエンド開発ではビルドが遅いことが問題になっています. その問題を解決すべく, 去年の Advent Calendar でも webpack のビルド時間を短くするための取り組みを紹介していました.

developers.freee.co.jp

Node.js v8.9.10 ~ v9.11.1 ではパフォーマンスが低下するという問題を抱えていました. そのため webpack のビルド速度低下の可能性が公式ドキュメントにも記されていました. 会計freee では v8.11.2 を使っていて, パフォーマンス低下の影響を受けていそうだったので, 現在の LTS である Node.js v10 にアップデートしました. 定量的な評価はまだできていませんが, 少しでもビルド時間が短縮できていればと思っています.

さよなら yarn 👋

yarn から npm に戻す CLI ツールとして deyarn があります.

github.com

このツールを使っても良かったのですが, 中で実際にやっている作業も単純でインストールをするのも面倒だったので, 手動で deyarn しました. 手順は以下の通りです.

  1. yarn.lock ファイルを消す
  2. node_modules を消す
  3. npm install をしてパッケージをインストールするのと同時に package-lock.json を生成する

一応これでパッケージマネージャ自体は yarn から npm に戻すことができました 👏

npm に戻したあと結構ハマった 😰

会計freee のフロントエンドは jest を使ってユニットテストを行っています. deyarn を行った後テストを動かしてみると以下のようなエラーが発生しました.

Requires Babel "^7.0.0-0", but was loaded with "6.26.3".

GitHub や Stack Overflow を眺めていると jest のバージョンを最新にすると良いと書いてあったので, 執筆時点での最新である v23.6.0 にアップデートしました. このとき, 公式ドキュメント に書いてある通りに依存パッケージのインストールを行い, regenerator-runtime が現在の最新である v0.13.1 がインストールされました.

jest のアップデートを行ったことにより上記のエラーは解消されました. しかし今度はブラウザでの実行時とユニットテスト時に regenerator-runtime が参照できずにエラーになったり, テストが通らなくなる問題に直面しました.

regenerator-runtime v0.13.0 では破壊的な変更が加わっており, global に regenerator-runtime が展開されなくなります. その結果 @babel/polyfill が実行時に v0.13.1 の regenerator-runtime を使ってしまって, 本来 global に存在しているはずの regenerator-runtime を参照できなくなっていました. なので regenerator-runtime を uninstall し, 本来 @babel/polyfill が使うべき regenerator-runtime がインストールされるように @babel/polyfill を再インストールすることでこの問題を解決しました.

おわりに

執筆時点ではまだ完全には npm に出戻ることはできてなさそうですが, もう少しでやり遂げることでできそうです. 他にもいろいろと細かな問題が発生しましたが, 特に今回紹介した regenerator-runtime の問題は原因を特定するまでに時間がかかり, チームの人の手助けなく自分一人では解決できなかったかなと思っています.

会計freee は画面のほとんどを JavaScript で描画しているためコードの規模もかなり巨大化してきています. そのためビルドツールやパッケージ 1 つのアップデートでも何が問題になるか分からないので, 試行錯誤しながらやっていくことにとてもやりがいを感じられます. 新卒エンジニアでもこういったことにどんどんチャレンジしていける環境はとてもいいなと入社して感じました.

大規模 JavaScript の開発やビルド周りのチューニングをやっていきたい人を募集しています 👍

jobs.freee.co.jp

最後に宣伝ですが, 私も企画 & 運営に参加している freee 初の技術イベントが今週の金曜にあるので, 興味のある方は是非参加していただけると嬉しいです 🎉

freee-tech-night.connpass.com

次の 12 日目は弊社 CEO の DS です, お楽しみに!!! (去年の Advent Calendar 見返すと, 去年も DS の前日は新卒が担当していましたね 😄)