Vite で複数モードのビルドを JavaScript から実行する
Vite の JavaScript API を使用して複数モードで連続ビルドする方法のメモです。
やりたいこと
マルチテナントアプリでリポジトリは単一なのですが、フロントリソースがテナント毎に分けてホスティングする必要があり、かつ各テナント毎の設定を .env
ファイルで定義している場合、テナント毎にビルドとデプロイを実施する必要があります。
このようなアプリを AWS CodePipeline で単一パイプラインでビルド & デプロイする場合、buildspec.yml
にシェルスクリプトでビルド内容を記載していくことになりますがシェルスクリプトで書くのがつらかったので JavaScript で書いて npm run build
で実行できるようにできないかと考えました。
アプリは Vite ベースで開発していたので、JavaScript API | Vite を調べていたら build
API があったので出来そうだなと思い、試してみました。
環境
- OS
- Microsoft Windows 11 22H2
- Node.js:
- 16.14.0
- vite
- 4.3.9
準備
新規 Vite プロジェクト作成
-
シンプルにするため、はじめに | Vite に沿って Vanilla な Vite プロジェクトを新規で作成します。
-
依存関係のインストール
環境変数の設定
Vite の環境変数については こちらの記事 で詳しく説明していますのでよかったらご覧ください。
-
.env
ファイルを複数使用するのでプロジェクトルートではなく、個別フォルダに配置したいため、.env
ファイルの配置場所をvite.config.js
に定義します。 -
./env/.env.mode1
ファイルを作成し、以下の通り環境変数を定義します。 -
./env/.env.mode2
ファイルを作成し、以下の通り環境変数を定義します。
アプリケーションにテスト用環境依存コードを追加
main.js
に以下の通り環境変数 VITE_MODE
を出力する箇所を追加します。
以上で準備は完了です。
ビルドスクリプトの作成
JavaScript API | Vite に沿ってビルドスクリプトを build.js
として書いていきます。
build
メソッドの引数ですが、上記公式ドキュメント上は InlineConfig
という型で定義されています。InlineConfig
自体は同ページに定義されていますが、
InlineConfig インタフェイスは、追加のプロパティで UserConfig を拡張します ― JavaScript API | Vite
とあるものの、肝心の UserConfig
の定義がわかりません。ただ実際のソース ./node_modules/vite/dist/node/cli.js
を見たところ、Vite の設定 | Vite と同一のように見えたので、こちらに沿ってオプションを簡単に設定しています。
mode
: ビルドモードの指定です。ここで指定したモードに一致する.env
ファイルが適用されます。build.outDir
: ビルドされたファイルの出力先です。モード毎にそれぞれ出力されるようにしています。
実行
以下のように実行します。
また、package.json
の scripts
に以下のように定義して、npm run build
で実行することも可能です。
実行するとプロジェクトルートに mode1
と mode2
のディレクトリが出来ていて、それぞれビルド後のコードが出力されています。
以下のように outDir
オプションに ./mode1
あるいは ./mode2
を渡して preview
を実行し、ブラウザでアクセスしてみます。
./mode1
の場合は、mode1
とページ上に表示されており、
./mode2
の場合は、mode2
とページ上に表示され、モード毎にビルドされていることがわかります。
なお、vite preview
は outDir
オプションでホストするディレクトリを指定できますが、npm run
経由でオプションを渡す場合は --
で区切る必要があります。
Any positional arguments are passed to the specified script. Use – to pass –prefixed flags and options which would otherwise be parsed by npm. ― npm-run-script | npm Docs
あとがき
Vite の JavaScript API を使用して、使用する環境変数を変えながらビルドできました。あまりユースケースは多くないかもしれませんが、便利でした。本番利用時はビルドエラー発生時にどのビルドでエラーが発生したか等のトレース可能なロギング等必要だと思いますが、ミニマムな実装の紹介でした。