使用 pnpmMonorepo 模式开发 ViteTypeScript 时,希望能够统一管理所有 package 的全局环境变量,统一从根目录下的 .env 文件中读取变量。

├── app
│   ├── packages
│   │   ├── web
│   │   │   ├── src
│   │   │   │   └── vite.config.ts
│   │   │   │   └── vite-env.d.ts
│   │   ├── server
│   │   │   ├── src
│   │   │   │   └── vite.config.ts
│   │   │   │   └── vite-env.d.ts
├── vite.config.ts
└── .env

env

.env: 根目录下环境变量文件,用来管理整个 Monorepo 项目的环境变量

VITE_SERVER_API_URL=http://localhost:3000

vite.config.ts

webservervite.config.ts 通过 dotenv 读取环境变量, 通过 define.env 的变量暴露给 import.meta.env

![TIP] 注意: Vite 为了防止意外的将环境变量泄露给客户端中,只有以 VITE_ 为前缀的变量才会暴漏给 Vite 处理的代码。

import { defineConfig } from 'vite';
import dotenv from 'dotenv';
 
import { sveltekit } from '@sveltejs/kit/vite';
 
dotenv.config({ path: '../../.env' });
 
export default defineConfig(async () => ({
  plugins: [sveltekit()],
  define: {
    'process.env': process.env
  },
 
  clearScreen: false,
  server: {
    port: 1420,
    strictPort: true,
    watch: {
      ignored: ['**/src-tauri/**']
    }
  }
}));

vite.config.ts 配置好之后就可以使用 import.meta.env.VITE_SERVER_API_URL 在代码中获取到环境变量了。

TypeScript 类型支持

Vite 提供了默认的 import.meta.env 类型定义: vite/client.d.ts,但是如果是我们自己在 env 中自定义的环境变量,使用 env 访问是TS类型会找不到,可以在 src 目录下新建 vite-env.d.ts 文件,然后扩充 ImportMeta:

/// <reference types="vite/client" />
 
interface ImportMetaEnv {
  readonly VITE_APP_TITLE: string
  // more env variables...
}
 
interface ImportMeta {
  readonly env: ImportMetaEnv
}

这样使用 TypeScript 访问时就能得到类型支持
CleanShot 2024-07-11 at 17.18.52@2x.png

扩充类型失效情况

如果ImportMetaEnv增强不起作用,请确保 中没有任何import语句vite-env.d.ts

/// <reference types="vite/client" />
import type { A } from 'a';
 
interface ImportMetaEnv {
  readonly VITE_APP_TITLE: string
  // more env variables...
}
 
interface ImportMeta {
  readonly env: ImportMetaEnv
}

这种方式会导致类型扩展失效