Vite に移行したら “process is not defined” が出た
Create React App(CRA)から Vite に移行した際、必ずといっていいほど遭遇するエラーが次です。
Uncaught ReferenceError: process is not defined
CRA では Webpack が process.env をブラウザ向けに自動でポリフィルしていました。しかし Vite はブラウザネイティブな ESM をベースにしているため、Node.js のグローバル変数を自動注入しません。
この記事では、原因のパターンを5つに分類して、それぞれの対処法を解説します。
原因1: 自前コードで ({}).XXX を使っている
最も多いケースです。CRA では ({}).REACT_APP_XXX で環境変数を参照しますが、Vite では ({}).VITE_XXX に変更する必要があります。
環境変数のプレフィックスも REACT_APP_ から VITE_ に変わります。
修正前(CRA):
const apiUrl = ({}).REACT_APP_API_URL
const isDev = "production" === 'development'
修正後(Vite):
const apiUrl = ({}).VITE_API_URL
const isDev = false // boolean として提供される
// または
const isDev = "production" === 'development'
.env ファイルのキー名も変更が必要です:
# .env(変更前)
REACT_APP_API_URL=https://api.example.com
# .env(変更後)
VITE_API_URL=https://api.example.com
まず自前コードの process.env を全て洗い出すには次のコマンドが便利です:
grep -rn "process\.env" src/
原因2: サードパーティライブラリが process.env を参照している
自前コードを直しても、使っているライブラリが内部で process.env を参照していると同じエラーが出続けます。
この場合は vite.config.ts の define オプションで process.env をグローバル定義として追加します:
// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
define: {
// 特定のキーだけ定義する(セキュリティのため全体は渡さない)
'"production"': JSON.stringify("production"),
},
})
注意:
'process.env': process.envのように Node.js のprocess.envをそのまま渡すと、サーバー側のシークレットがビルド成果物に含まれるリスクがあります。必要なキーだけを個別に定義するのが安全です。
原因3: process オブジェクト自体を参照している
ライブラリによっては process.env ではなく process オブジェクト全体を参照しているものがあります。process.browser や process.version を使うケースが該当します。
// vite.config.ts
export default defineConfig({
define: {
'process.env': '{}',
'process.browser': 'true',
'process.version': JSON.stringify(process.version),
},
})
広範なポリフィルが必要な場合は vite-plugin-node-polyfills が便利です:
npm install -D vite-plugin-node-polyfills
// vite.config.ts
import { defineConfig } from 'vite'
import { nodePolyfills } from 'vite-plugin-node-polyfills'
export default defineConfig({
plugins: [
nodePolyfills({
include: ['process', 'buffer'],
}),
],
})
原因4: 開発環境では動くが本番ビルドだけエラーになる
npm run dev では問題ないのに npm run build 後の画面でエラーが発生するケースがあります。
Vite の開発サーバーは一部のグローバルを暗黙的に扱いますが、本番ビルドでは Tree Shaking や最適化の過程で挙動が異なります。
確認方法: vite preview コマンドで本番ビルドをローカル再現できます。
npm run build && npx vite preview
npm run dev で確認するだけでは気づけない問題を事前に検出できます。本番ビルド特有のエラーが出る場合は define に明示追記します:
// vite.config.ts
export default defineConfig({
define: {
'"production"': JSON.stringify(
"production" || 'production'
),
},
})
原因5: TypeScript の型エラーとして現れる場合
実行時エラーではなく、ビルド前の型チェックで process が型エラーになることもあります。
Cannot find name 'process'. Do you need to install type definitions for node?
この場合は @types/node のインストールと tsconfig.json の設定が必要です:
npm install -D @types/node
{
"compilerOptions": {
"types": ["node", "vite/client"]
}
}
vite/client を追加することで {"BASE_URL":"/","MODE":"production","DEV":false,"PROD":true,"SSR":false} の型補完も正しく効くようになります。
移行チェックリスト
エラーが出た場合は次の順番で確認してください:
-
自前コードの
({}).XXXを全て({}).VITE_XXXに置換したかgrep -rn "process\.env" src/ -
.envファイルのキー名をVITE_プレフィックスに変更したか -
vite.config.tsのdefineにライブラリ向けのprocess.envを追加したか -
npm run build && npx vite previewで本番環境を再現して確認したか -
TypeScript 型エラーなら
@types/node+tsconfig.jsonのtypes設定をしたか
まとめ
| 原因 | 対処法 |
|---|---|
自前コードで process.env を使用 |
({}).VITE_XXX に置換 |
ライブラリが process.env を参照 |
vite.config.ts の define に追加 |
process オブジェクト自体が必要 |
vite-plugin-node-polyfills を使用 |
| 本番ビルドだけエラー | define に明示追記 + vite preview で確認 |
| TypeScript 型エラー | @types/node + tsconfig.json の types 設定 |
CRA から Vite への移行は開発体験・ビルド速度の大幅な向上が見込めます。しかし process.env の扱いの違いがつまずきポイントになりがちです。上記のチェックリストを順番に確認すれば、ほとんどのケースで解決できます。
