はじめに
株式会社リンクアンドモチベーションの新卒2年目エンジニアです。
私が携わっているプロダクトのビルドツールをVue CLIからViteに変更することになりました。
当時は、ビルドの内部で何が行われているかを体系的に説明できる状態ではなく、
ビルドツールについても表層的な理解に留まっていました。
そんな状態でViteへの移行を担当することになり、ビルドについての理解が深まったのでその学びをまとめます。
※この記事では移行の方法については触れません。
Vue CLIとViteの違い
Viteに移行するぞ!
と気合いを入れたものの、Vue CLIについて体系的に理解する機会はこれまで多くなく、何がどう変化するのかを理解しきれていませんでした。
ということで、まずはVueCLIとViteについて改めて理解します。
VueCLI
まず、VueCLIは厳密にはビルドツールではありません(先ほどビルドツールと書いてしまいましたが)。
ビルドエンジンそのものではなく、ビルドツール(webpack)を中心としたVue 向けのツールチェーンです。
ビルド以外には、プロジェクトの雛形作成や開発サーバーの提供、ESLintなどの周辺ツール統合の役割も担っています。
Vue CLI では、実際のビルド処理はwebpackが担っています。
Vite
ViteはES Moduleを前提に設計された「開発サーバー」と「本番ビルド機能」を併せ持つツールです。
開発時はバンドルを行わず、必要なモジュールだけを変換・配信します。
本番ビルドでは、内部的にバンドラーとしてRollupを使用しています。
なぜViteはビルドツールと言われるのか
ここで、1つ疑問に思った点がありました。
VueCLIはビルドツールを含んだ包括的なツールであることは理解しましたが、VueCLIもViteも内部で別のビルドツールを使っているのに、Viteだけビルドツールと呼ばれるのはなぜなのか。(公式でもビルドツールとして定義されています)
webpack、Rollup、VueCLI、Viteの違いは何なのか?
上記を理解するにあたって、そもそもビルドの仕組みを深く理解していないと感じたので、ビルドの仕組みを整理します。
ビルドの流れ
一般的な「本番向けビルド」では、以下のような工程で処理が進みます。
- 依存関係の解析
- プリプロセス
- トランスパイル(変換)
- バンドル(ファイル統合)
- 最適化(Optimization)
- 出力
上記処理と並行して、静的解析が実施されることもあります。
静的解析ではLintや型チェックなどにより構文の誤りを検出します。
1. 依存関係の解析
「どのファイルがどのファイルに依存しているか」を完全に洗い出す工程。
エントリーポイントを起点にし、import/requireを再帰的にすべてたどる。
この工程により、内部的には依存関係グラフが作られる。
main.ts
├─ App.vue
│ ├─ Header.vue
│ └─ useUser.ts
└─ router.ts
2. プリプロセス
次工程が理解できる形式に、コードを言語や記法レベルで変換する工程。
バンドラやトランスパイラはSCSSやVue SFCのような独自記法をそのまま理解できないので、CSSやJSに変換する。
例)
SCSS→CSS
Vue SFC(template)→ render 関数
3. トランスパイル(変換)
実行環境(ブラウザ)が理解できる形式にコードを変換する工程。
例)変換前→変換後
TypeScript→JavaScript
最新JavaScript→古いJavaScript
const user: User = { name: 'Taro' }
↓ //トランスパイル
const user = { name: 'Taro' }
4. バンドル(ファイル統合)
多数のモジュールを、実行効率良い単位にまとめる工程。
※多数のモジュールをそのまま配信すると、初期読み込みや実行効率に影響が出るため
5. 最適化(Optimization)
「速く・軽く・小さく」するための最終調整の工程。
主な最適化には、Minify(空白・改行の削除や変数名の圧縮)や、デッドコードの削除、CSSやアセットの圧縮が挙げられる。
6. 出力
最適化まで終えた「最終成果物」を、実行・配布可能な形でファイルシステムに書き出す工程。
この際に、ファイル名やchunk構成が確定する。
dist/
├─ index.html
├─ assets/
│ ├─ index.8f3a1c.js
│ ├─ vendor.2a91de.js
│ ├─ index.91ab.css
│ └─ logo.a8d923.svg
なぜViteはビルドツールと言われるのか(再び)
ここで、先ほど整理した ビルドの6ステップをもとに、
Vue CLI と Vite が どの立場でビルドに関わっているかを整理します。
Vue CLI の立ち位置
Vue CLI自体はビルドエンジンではないので1~6を自ら実行しませんが、webpackの設定生成・プラグイン適用・実行制御を一元的に担っています。
Vue CLI がやっているのは、
• Webpack 設定の生成
• Vue 用の loader / plugin の組み込み
• vue-cli-service build という実行入口の提供
です。
つまりVue CLIは、
「ビルドそのもの」ではなく
「ビルドツール(Webpack)を Vue向けに操作するためのCLI」
という立ち位置のツールです。
Vite の立ち位置
Viteも、すべてのビルド処理を自前で実装しているわけではありません。
• 本番ビルド時の依存関係の解析・バンドル → Rollup
• 最適化 → Rollup / esbuild
• トランスパイル → esbuild / plugin
といったように、実際の処理は別のエンジンに委譲しています。
しかし Vite は、
• どの工程を有効にするか
• どのツールを使うか
• どの順序で処理するか
• 出力構成をどうするか
といった設計・オーケストレーションを担い、実処理は各ツールに委譲します。
まとめると
Vue CLI は Webpackを前提としたビルド工程の設計・実行を担うVue向けのツールチェーンであり、
Viteは、開発サーバーから本番ビルドまでを一貫して提供するビルドツールとして設計されていると理解しました。
最後に
「Vue CLIからViteへの移行」ということで、両者を同じ立ち位置のものとして認識していましたが、よく調べてみると設計思想や仕組みが全く異なっているということを知りました。
今後も、目標とする挙動や作業を達成するだけでなく、その仕組みまで理解する習慣をつけていきたいです。