如何在Vite+React开发模式下将环境变量注入JSON文件?
解决Vite开发模式下替换public目录JSON文件中的环境变量问题
问题背景
用Vite搭建的React项目,执行yarn build时能通过vite-plugin-static-copy将public目录下JSON文件中的<REACT_APP_BASE_URL>替换为.env里的变量,但执行yarn start(开发模式)时无法实现替换。
原因分析
vite-plugin-static-copy插件默认仅在生产构建阶段(vite build)执行文件复制和转换操作,开发模式下Vite会直接托管public目录的原始文件,不会经过插件的转换流程。
解决方案
方案1:修改vite-plugin-static-copy配置,让其在开发模式生效
调整插件配置,强制它在开发模式下也运行文件转换,并监听文件变化自动更新:
const copyPlugin = (env: any) => { const reactBaseURLtransform: TransformOption = (contents, path) => { return contents.replace(/<REACT_APP_BASE_URL>/g, env.VITE_REACT_APP_BASE_URL); }; return viteStaticCopy({ flatten: true, // 启用开发模式下的文件复制转换 enableDevCopy: true, // 监听JSON文件变化,自动重新处理 watch: { disableAutoRun: false, include: 'public/*.json', }, targets: [ { src: 'public/*.json', dest: '', transform: reactBaseURLtransform, } ], }); };
注意:开发模式下插件会把转换后的JSON输出到项目根目录,建议将根目录下的JSON文件加入.gitignore避免提交到版本库,Vite开发服务器会优先读取根目录的处理后文件。
方案2:通过Vite开发服务器中间件实时替换
如果不想生成额外文件,可以直接在请求阶段拦截JSON并实时替换变量,无需修改原文件:
export default defineConfig(({ command, mode }) => { const env = loadEnv(mode, process.cwd(), ''); const plugins: any[] = [react(), viteTsconfigPaths()]; // 仅在开发模式添加自定义中间件 if (command === 'serve') { plugins.push({ name: 'dev-json-env-replace', configureServer(server) { server.middlewares.use(async (req, res, next) => { // 只处理public下的JSON文件请求 if (req.url?.endsWith('.json') && !req.url.includes('/node_modules/')) { const fs = await import('fs'); const path = await import('path'); const filePath = path.resolve(process.cwd(), 'public', req.url.slice(1)); if (fs.existsSync(filePath)) { let content = fs.readFileSync(filePath, 'utf-8'); // 替换环境变量占位符 content = content.replace(/<REACT_APP_BASE_URL>/g, env.VITE_REACT_APP_BASE_URL); res.setHeader('Content-Type', 'application/json'); res.end(content); return; } } next(); }); } }); } else { // 生产模式保留原copy插件逻辑 plugins.push(copyPlugin(env)); } return { plugins: [...plugins], build: { outDir: "build", rollupOptions: { output: { manualChunks(id) { if (id.includes('node_modules')) { return id.toString().split('node_modules/')[1].split('/')[0].toString(); } }, }, }, chunkSizeWarningLimit: 5000, }, server: { open: false, port: 3000, }, }; });
这种方式无需生成额外文件,请求时实时处理内容,更贴合开发模式的动态需求。
验证方法
- 启动开发服务器:
yarn start - 访问目标JSON文件(如
http://localhost:3000/config.json) - 查看响应内容,确认
<REACT_APP_BASE_URL>已替换为.env.development中的值
内容的提问来源于stack exchange,提问作者Avanish Srivastava
相关产品推荐
相关产品推荐

