ViteでHTMLコードを開発と本番で分けて.envで置換する方法

HTML内のコードを置換して生成

Viteを使用しているとHTML内のコードを置換して生成したいことがあります。

そんなときはViteのプラグインAPIのtransformIndexHtmlを使用すれば簡単にできます。

やり方の説明のため、まずViteの開発環境を以下のコマンドで作成してください。

npm init vite@latest

「Need to install the following packages」などが表示されたら全部Enterを押してデフォルトで作成してください。

npm init vite@latest
Need to install the following packages:
  create-vite@3.2.1
Ok to proceed? (y)
✔ Project name: … vite-project-test
✔ Select a framework: › Vanilla
✔ Select a variant: › JavaScript

作成したらindex.htmlを以下に書き換えます。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Vite App</title>
</head>
<body>
<h1>Vite App</h1>
</body>
</html>

試しにVite AppをVite Testに置換してみましょう。

HTML内のコードを置換して生成するにはプロジェクトルート内にvite.config.jsが必要なので作成して、中身を以下のようにしてください。

import {defineConfig} from 'vite'

export default defineConfig(() => {
  return {
    plugins: [htmlPlugin()],
  }
})

function htmlPlugin() {
  return {
    name: 'html-transform',
    transformIndexHtml: {
      enforce: 'pre',
      transform: (html) => {
        return html
          .replace(/Vite App/g, 'Vite Test')
      },
    },
  }
}

このように書くことで「npm run dev」または「npm run build」を実行するとHTMLが置換されて生成されます。

<h1>Vite Test</h1>

開発 or 本番 で置換内容を変更する

npm run dev (開発) と npm run build (本番) で置換される文字を変えたい場合はdefineConfigの引数でmodeを指定します。

modeはnpm run dev (開発) はdevelopment、npm run build (本番) はproductionを返します。

import {defineConfig} from 'vite'

export default defineConfig(({mode}) => {
  return {
    plugins: [htmlPlugin(mode)],
  }
})

function htmlPlugin(mode) {
  return {
    name: 'html-transform',
    transformIndexHtml: {
      enforce: 'pre',
      transform: (html) => {
        return html
          .replace(/Vite App/g, 'Vite ' + mode)
      },
    },
  }
}
<!-- 置換前 -->
<h1>Vite App</h1>

<!-- npm run dev 実行後 -->
<h1>Vite development</h1>

<!-- npm run build 実行後 -->
<h1>Vite production</h1>

環境変数で変更する方法

HTML内に%VITE_MODE%のように挿入して開発と本番で出し分けることもできます。

やり方はまずHTML内に%VITE_MODE%のような独自の変数を作成して入れます。

<h1>%VITE_MODE%</h1>

次に.env.developmentと.env.productionファイルを作成して、それぞれに「VITE_MODE='開発環境'」、「VITE_MODE='本番環境'」を入れます。

この2つのファイル名は間違いやすいので、以下をコピペして作成してください。

touch .env.development .env.production

次にvite.config.jsでloadEnvを読み込み、環境変数を元に置換できるようにします。

import {defineConfig, loadEnv} from 'vite'

export default defineConfig(({mode}) => {
  return {
    plugins: [htmlPlugin(loadEnv(mode, '.'))],
  }
})

function htmlPlugin(env) {
  return {
    name: 'html-transform',
    transformIndexHtml: {
      enforce: 'pre',
      transform: (html) => {
        return html
          .replace(/%(.*?)%/g, (match, p) => env[p] ?? match)
      },
    },
  }
}

この状態にしたら再び実行してHTMLを生成してみてください。

「%VITE_MODE%」が、npm run devだと「開発環境」、npm run buildだと「本番環境」になっていることが確認できます。

例として「%VITE_MODE%」にしましたが、置換して変えているだけなので%で囲まず「{{VITE_MODE}}」のように設定可能です。

開発と本番で変数の内容が同じ場合は、.env.developmentや.env.productionではなく.envファイルを作成して、「VITE_FOO='bar'」のように書けば置換できます。