Vite ReactでUncaught ReferenceError: process is not definedというエラーが発生し、import.meta.envでもVITE_で始まる環境変数が読み込まれない場合の回避策


# 本記事の概要

Viteで.envが読まれないの、どうしよう～

# 解決

### ソースコード（修正後）

```TypeScript:vite.config.ts
import { defineConfig, loadEnv } from 'vite'
import react from '@vitejs/plugin-react-swc'
import { resolve } from "node:path";

export default defineConfig(({ mode }) => {
  const env = loadEnv(mode, __dirname, '')
  return {
    // vite の設定
		base: "./",
		root: "src",
		plugins: [
			react()
		],
		build: {
			// distフォルダに出力
			outDir: resolve(__dirname, "dist"),
			// 存在しないときはフォルダを作成する
			emptyOutDir: true,
			copyPublicDir: true,
			rollupOptions: {
				// entry pointがあるindex.htmlのパス
				input: {
					"": resolve(__dirname, "src/index.html"),
				},
				// bundle.jsを差し替えする
				output: {
					entryFileNames: "assets/bundle.js",
				},
			},
		},
    define: {
      'process.env': env,
    },
  }
})
```

```App.tsx
const env = process.env;

console.log(env);
```

```.env.development
ENV_HAS_READ_DEVELOP=true
VITE_ENV_HAS_READ=true
```

下記「[ソースコード（修正前）](####ソースコード（修正前）)」の該当ファイルを上記のものに差し替えた状態で`npm run dev`を行った結果；

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653543/400a20a2-10c2-3a16-eeb4-8ed0e6d212c4.png)

→　環境変数`ENV_HAS_READ_DEVELOP`ならびに`VITE_ENV_HAS_READ`が読み込まれていることが確認できた。

# 症状

#### ソースコード（修正前）

```json:package.json
{
  "name": "myapp",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite"
  },
  "dependencies": {
    "react": "^18.3.1",
    "react-dom": "^18.3.1"
  },
  "devDependencies": {
    "@types/react": "^18.3.10",
    "@types/react-dom": "^18.3.0",
    "@vitejs/plugin-react-swc": "^3.5.0",
    "eslint": "^9.11.1",
    "typescript": "^5.5.3",
    "typescript-eslint": "^8.7.0",
    "vite": "^5.4.8"
  }
}
```

```TypeScript:vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc'
import { resolve } from "node:path";

export default defineConfig({
		base: "./",
		root: "src",
		plugins: [
			react()
		],
		build: {
			outDir: resolve(__dirname, "dist"),
			emptyOutDir: true,
			copyPublicDir: true,
			rollupOptions: {
				input: {
					"": resolve(__dirname, "src/index.html"),
				},
				output: {
					entryFileNames: "assets/bundle.js",
				},
			},
		},
    }
)
```

```html:src/index.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8" />
    <title></title>
    <script type="module" src="/main.tsx"></script>
  </head>
<body>
  <div id="root"></div>
</body>
</html>
```

```React:main.tsx
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import App from './App.tsx'

createRoot(document.getElementById('root')!).render(
  <StrictMode>
      <App />
  </StrictMode>,
)
```

```React:App.tsx
console.log(import.meta.env);
const env = process.env;
console.log(env);

function App() {
  return (<></>);
}

export default App
```

```.env
ENV_HAS_READ=true
VITE_ENV_HAS_READ=true
```

```.env.development
ENV_HAS_READ_DEVELOP=true
VITE_ENV_HAS_READ=true
```

```.env.production
ENV_HAS_READ_PRODUCTION=true
VITE_ENV_HAS_READ=true
```

#### 結果

```
npm run dev
```

でブラウザで開き、コンソールを見ると

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653543/c6615ffe-94c1-a354-300f-819b8ef5e968.png)

```
{BASE_URL: '/', DEV: true, MODE: 'development', PROD: false, SSR: false}BASE_URL: "/"DEV: trueMODE: "development"PROD: falseSSR: false[[Prototype]]: Object
App.tsx:4 Uncaught ReferenceError: process is not defined
    at App.tsx:4:13
```

Viteの`import.meta.env`が存在し、MODE=developmentになっているが、環境変数が読み込まれていない。

Viteでは仕様上、`VITE_`のフレフィックスをもつ環境変数を`import.meta.env.VITE_****`で利用できるハズだが
`import.meta.env`以下に存在していない。

# 失敗

Viteにおいて環境変数の対応は本来Viteが行ってくれているが、
これを無視してdotenvを無理やり使うことを試みる。

#### ソースコード

```
npm install dotenv
```

からの

```TypeScript:env.ts

import * as dotenv from 'dotenv';

if (import.meta.env.PROD) {
  dotenv.config({ path: '.env' });
  dotenv.config({ path: '.env.production' });
}
if (import.meta.env.DEV) {
  dotenv.config({ path: '.env' });
  dotenv.config({ path: '.env.develop' });
}
if (process.env.ENV === 'local') {
  dotenv.config({ path: '.env' });
  dotenv.config({ path: '.env.local' });
}
const env = process.env;

export default env;
```

```TypeScript:App.tsx
import env from "./env";

console.log(import.meta.env);
console.log(env);

function App() {
  return (<></>);
}

export default App
```

#### 結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653543/a8a4b625-124d-3f2e-b7f6-aaeff2a7da99.png)

#### そこからの試み

よく分からないが、`process`はNode.jsで動くものであって、ブラウザ上で動くものではないと勝手に考察した。
まずは`process`を強引に作ってみる

[こちらの記事](https://github.com/vitejs/vite/issues/1973)を参考に；
```TypeScript:vite.config.ts
export default defineConfig({
        ....
        
		define: {
			'process.env': {}
		}
    }
)

```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653543/e4e0fce6-a706-6185-99ae-680ceba3f0aa.png)

`vite.config.ts`のdefineオプションに入れたものはグローバル変数になる（？）という知見が得られた。

空のオブジェクトを入れたのでエラーが出るのは当然。
多分、`process`に本来格納されるべきオブジェクトをそのまま入れないとダメなのだろう。そこまでするのは面倒なので、[Viteの環境変数ヘルパー](https://ja.vite.dev/config/)から得られた値をここへ入れてみる。

　→　[「解決」セクション](#解決)へ続く

　　（※結局`npm install dotenv`は不要でした）

# もう一つの解決法

`vite-plugin-env-compatible`を使用

　→　参考：[Uncaught ReferenceError: process is not definedが表示される](https://qiita.com/gantarooou_js/items/6fc638fc27feb1246bea)

#### ソースコード

```
npm install vite-plugin-env-compatible
```

からの

```TypeScript:vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc'
import env from "vite-plugin-env-compatible";
import { resolve } from "node:path";

export default defineConfig({
		base: "./",
		root: "src",
		plugins: [
			react(),
			env({ prefix: "VITE", mountedPath: "process.env" })
		],
		build: {
			outDir: resolve(__dirname, "dist"),
			emptyOutDir: true,
			copyPublicDir: true,
			rollupOptions: {
				input: {
					"": resolve(__dirname, "src/index.html"),
				},
				output: {
					entryFileNames: "assets/bundle.js",
				},
			},
		},
  }
)
```

#### 結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653543/b8f30c59-bef9-1087-27be-010f29032f8b.png)

`VITE_ENV_HAS_READ`が読み込まれたので、`.env`ファイルが評価されている。

が、`vite-plugin-env-compatible`で`mode`に応じて読み込む`.env`ファイルを変える方法がいまいち分からなかったため、今回は採用しなかった。