[Vueの開発体験を爆上げする] Viteを調査


  [自ブログ](https://blog.hedrall.work/posts/vite-20210305)からの引用です。
  
  ![TopPage](https://blog.hedrall.work/images/vite/logo.jpeg)

## 前提

Vueは3系です

## viteとは

フロントエンドのDXを爆上げするツール群です。
当初はVueのエコシステムでしたが、現在はreactなど多くのライブラリをサポートしています。

レポ: [vitejs/vite](https://github.com/vitejs/vite)
doc: [Features | Vite](https://vitejs.dev/guide/features.html#npm-dependency-resolving-and-pre-bundling)

## まずは試す

```bash
npm init @vitejs/app
```

対話式にテンプレートを選べるので、vue-tsで試します。

他にも色々あるようです。

```bash
vanilla
vue
vue-ts
react
react-ts
preact
preact-ts
lit-element
lit-element-ts
```

### package.jsonの内容

```json
{
  "scripts": {
    "dev": "vite", // DEVサーバ起動
    "build": "vite build", // ビルド
    "serve": "vite preview" // プロダクションビルドでサーブ
  }
}
```

### 検証起動
`npm run dev` で1秒程で起動します。コンソールに表示される実処理時間は200~300msほどです。
後述しますが、node_modulesにキャッシュが生成されるため、2回目以降の起動はさらに高速になります。<br/>
HMRもsaveと同時に即時反映される印象です。

### 本番ビルド

`time npm run build`で、タイムを計測した結果した結果です。

実行時間: **約3秒** (realで0m2.870s, 0m2.591s, 0m2.630s, 0m2.620s, 0m2.973s)<br/>

やはり、検証本番共にビルドはかなり高速である事が確認できました。

## vue-cli-serviceを使用する従来の方法と比較

```bash
npm i -D @vue/cli-service
npm i -D @vue/cli-plugin-typescript
```

```diff
// package.json
  "scripts": {
    // ...
+   "cli-serve": "vue-cli-service serve",
+   "cli-build": "vue-cli-service build"
  },
```

### 検証起動

`npm run cli-serve` は **手動計測で5秒程** の時間で終了しました。Viteは1秒未満だったので、やはりViteの方が高速です。

### 本番ビルド

`rm -rf node_modules/.cache && time npm run cli-build` は **8.5秒** ほどで終了しました。<br/>
(realで0m8.434s, 0m8.494s, 0m8.438s, 0m8.568s, 0m9.126s)

Viteが3秒ほどだったので、やはりViteの方が高速です。

## デザインライブラリを入れてみる

SPA系ってデザインライブラリ入れるとググッと重くなりますよね。

今回は試しに `material-plas`(material-uiのvue3系のやつ)を入れてみました。

|  |検証  |本番  |
|---|---|---|
|Vite  | 相変わらず1秒ほどで起動 | 10s  |
|vue-cli  | 6.5秒くらい | 16.5s |

計測結果詳細
- 本番 vita: 0m10.125s, 0m9.996s, 0m10.308s, 0m9.680s, 0m10.259s
- 本番 vue-cli: 0m16.784s, 0m16.778s, 0m16.906s, 0m16.388s, 0m17.322s

本番ビルドに関しては差が大きくないですが、検証ビルドはやっぱりViteが早いですね。<br/>
開発体験の爆上げと言う点で非常に有用なツールだと思います。

## 気になる仕様

Viteの仕様できになる部分をまとめてみます。

### ツール
ほとんどの既存エコシステムが仕様できる雰囲気です。TSやJSXの変換には `esbuild` が採用されています。

- TS
- Vue
- JSX, TSX
- CSS
  - CSS import
  - CSS modules ( .module.cssの拡張子が処理される )
  - CSS Pre-processors ( .scss, .sass, .less, .styl and .stylus )
- image, file
- json
- glob import
- Web assembly
- Web Workers
- その他バンドルの最適化

### キャッシュ(dependency pre-bundling)

**ファイルキャッシュ**<br/>
検証モードの場合、ビルド時に依存するnpmライブラリを`esbuild` で個別に変換し、ESMとして`node_modules/.vite`に保存しており、
ブラウザからは `import` を使用してオンデマンドでアクセスします。
これらより2回目以降の検証サーバの起動を高速化しています。キャッシュがある場合は体感で1/2~1/3ほどにビルド時間が短縮されました。
キャッシュはライブラリのバージョンが変更が検知された場合に自動的にクリアされます。
(例えば、`package-lock.json`, `yarn.lock`などが更新された場合)<br/>
もしくは `--force` フラグで強制的にクリアできます。

```bash
npm run dev # 2回目以降
> 282ms
npm run dev -- --force # .vitaのキャッシュをクリア
> 749ms
```

**ブラウザキャッシュ**<br/>
ファイルキャッシュをimportする際に、`max-age` を最大に設定し、無限時間ブラウザにキャッシュさせます。
キャッシュの削除は `google chrome` のdisable cacheなどで行います。

![キャッシュから読まれる様子](/images/vite/browser-cache.png)

## 本番ビルド
ES2015以降に変換するため、デフォルトでは古いブラウザには対応していません。
- Chrome >=61
- Firefox >=60
- Safari >=11
- Edge >=16

ただし`@vitejs/plugin-legacy`プラグインでレガシーブラウザにも対応できます。

ビルドには `rollup` を使用しており、vita.config.jsから設定をカスタマイズできます。

## マルチページ

検証モードではそのままファイル階層通りでアクセス可能。

```bash
src/nest/indes.htmlを作成
http://localhost:3000/src/nest/ <= これでアクセスできる
http://localhost:3000/src/nest  <= これだとダメみたい
```

本番ビルドのためにrollupの設定を拡張する

```bash
build: {
    rollupOptions: {
      input: {
        main: path.resolve( __dirname, 'index.html' ),
        nest: path.resolve( __dirname, 'src/nest/index.html' ),
      }
    }
  }
```

(しかしながらJAMStackでも基本SPAかSSGだと思うので、マルチページのVueプロジェクトってどういう時使うんだろう？)

## 環境変数

dotenvが設定されているので、.env.local, .env.development, .env.productionを作成するだけ

## SSR

実験的機能なので、割愛。手動で設定しなければならない点が多く、管理に時間を割きそうな印象です。

## まとめと所感

特に検証系のビルドが高速で10倍弱くらいのスピード的なメリットがあるため、DX爆上げが実現できます。
最近esbuildに関しても調査をしたのですが、esbuildは機能とかスコープを絞って爆速変換+バンドルツールとして完成しつつある印象ですが、
Viteはビルドツール(rollup)まで統合されているので、ツールと言うよりはviewライブラリを差し込めるフレームワークという印象がします。
その点、Viteがもう少し成熟してこないと本番系に使用したり、検証系だけビルド方法をVitaに載せ替えてDX爆上げするなどの使い方は難しと思われます。

しかしながら、フロントエンド開発におけるビルド+バンドルサイズの課題は根本的な課題なので、これを解決するViteには今後の発展を期待しています！