vite-plugin-env-generate-config
简介
该插件用于在vite构建时将.env
,.env.[mode]
中(仅VITE_开头的)环境变量提取到打包后的config.js中, 以支持在运行时修改配置变量。
安装
npm install vite-plugin-env-generate-config --save-dev
使用
在vite.config.ts中引入插件并配置:
import { defineConfig } from 'vite'
import envGenerateConfig from 'vite-plugin-env-generate-config'
export default defineConfig({
plugins: [
envGenerateConfig()
]
})
示例效果
- 源文件.env
VITE_SYS_TITLE="XXX系统"
VITE_SERVER_BASEURL="http://192.168.1.1:8200/"
- 源文件.env.production
VITE_SERVER_BASEURL="http://192.0.0.0:8200/"
- 打包文件中config.js
VITE_SYS_TITLE="XXX系统"
VITE_SERVER_BASEURL="http://192.0.0.0:8200/"
这样在打包后也可以修改服务器地址等信息,方便在不同服务器部署的需求。也支持在不同打包环境下合并相应环境的配置,如build --mode test时则会合并.env和.env.test的配置。
源码思路
- 根据build环境读取配置文件
export function loadViteConfig(mode: string): Record<string, string> {
const baseEnvPath = path.resolve(process.cwd(), '.env')
const modeEnvPath = path.resolve(process.cwd(), `.env.${mode}`)
const baseEnvConfig = dotenv.parse(fs.readFileSync(baseEnvPath))
const modeEnvConfig = dotenv.parse(fs.readFileSync(modeEnvPath))
return Object.fromEntries(
Object.entries({ ...baseEnvConfig, ...modeEnvConfig }).filter(([key]) => key.startsWith('VITE_')),
)
}
- 插件主函数
export default function GenerateConfigPlugin(options?: VitePluginEnvGenerateConfigOptions): Plugin {
let mode: string
const { outputName } = assignOptions(options)
return {
name,
apply: 'build',
configResolved(config) {
// 记录本次构建的mode
mode = config.mode
},
// 将配置合并写入config.js
writeBundle(options) {
const viteEnvConfig = loadViteConfig(mode)
const configJsContent = `window.vite_env_config = ${JSON.stringify(viteEnvConfig, null, 2)};`
const outputPath = path.resolve(options.dir as string, `${outputName}.js`)
fs.mkdirSync(path.dirname(outputPath), { recursive: true })
fs.writeFileSync(outputPath, configJsContent)
},
// 在最终的index.html中写入加载config.js语句
transformIndexHtml(html) {
if (!html.includes(`<script src="/${outputName}.js"></script>`)) {
return html.replace('</head>', ` <script src="/${outputName}.js"></script>\n</head>`)
}
return html
},
// 将代码中的import.meta.env语句替换为config.js中的变量
transform(code, id) {
if (/.(js|ts|jsx|tsx|vue|svelte)$/.test(id)) {
const viteEnvConfig = loadViteConfig(mode)
for (const [key, value] of Object.entries(viteEnvConfig)) {
code = code.replace(new RegExp(`import\.meta\.env\.${key}`, 'g'), `window.vite_env_config.${key}`)
}
}
return code
},
}
}