如何在React项目的JSON文件中通过Webpack使用环境变量API_URL?
在React+Webpack项目中给JSON文件注入环境变量的解决方案
问题背景
我们用Webpack搭了个React项目,想根据不同环境在.json文件里用API_URL这类环境变量,试了.env文件但在JSON里访问process.env.API_URL时,直接报错“无法访问process”。
可行解决方案
方案1:把JSON改成JS模块(最简单)
JSON文件本身不会被Webpack的JS处理流程解析,直接转成JS模块就能直接用环境变量:
- 重命名
myJsonFile.json为myJsonFile.js,内容改成:
export default [ { appId: "xyz", name: "abc", title: "Test", description: "Test", api: `${process.env.API_URL}/myAPI` } ];
- 在React组件里直接导入这个JS模块:
import myConfig from './myJsonFile.js';
不需要改任何Webpack配置,dotenv-webpack已经给JS/TS文件注入了环境变量,直接就能用。
方案2:用CopyWebpackPlugin的transform替换变量(保留JSON格式)
要是必须保留JSON文件,就用CopyWebpackPlugin的transform功能,在复制文件时替换变量:
修改webpack.common.js里的CopyWebpackPlugin配置,先读取对应环境的.env文件,再在复制时替换JSON里的变量:
const path = require('path'); const HTMLWebpackPlugin = require('html-webpack-plugin'); const { CleanWebpackPlugin } = require('clean-webpack-plugin'); const CopyWebpackPlugin = require('copy-webpack-plugin'); const TerserPlugin = require('terser-webpack-plugin'); const dotenv = require('dotenv'); // 读取对应环境的.env文件 const envPath = process.env.NODE_ENV === 'development' ? path.resolve(__dirname, '..', './.env.development') : path.resolve(__dirname, '..', './.env.production'); const env = dotenv.config({ path: envPath }).parsed; module.exports = { entry: './src/index.tsx', plugins: [ new CleanWebpackPlugin(), new HTMLWebpackPlugin({ template: path.resolve(__dirname, '..', './src/index.html'), }), new CopyWebpackPlugin({ patterns: [{ from: 'public', transform: (content, filePath) => { // 只处理目标JSON文件 if (filePath.includes('myJsonFile.json')) { let contentStr = content.toString(); // 替换所有process.env.XXX格式的变量 contentStr = contentStr.replace(/process\.env\.([A-Z_]+)/g, (match, key) => env[key] || match); return Buffer.from(contentStr); } return content; } }] }) ], // 其他原有配置不变... };
然后修改myJsonFile.json里的变量写法,去掉尖括号:
[ { "appId": "xyz", "name": "abc", "title": "Test", "description": "Test", "api": "process.env.API_URL/myAPI" } ]
这个方案不需要额外装依赖,靠现有插件就能搞定。
方案3:用DefinePlugin+string-replace-loader处理JSON
如果要批量处理多个JSON文件的环境变量,可以用DefinePlugin配合string-replace-loader:
- 先安装依赖:
npm install string-replace-loader --save-dev
- 修改
webpack.dev.js:
const path = require('path'); const { merge } = require("webpack-merge"); const commonConfig = require("./webpack.common"); const webpack = require('webpack'); const dotenv = require('dotenv'); // 读取开发环境的.env文件 const env = dotenv.config({ path: path.resolve(__dirname, '..', './.env.development') }).parsed; // 转换成DefinePlugin需要的格式 const envVars = Object.keys(env).reduce((obj, key) => { obj[`process.env.${key}`] = JSON.stringify(env[key]); return obj; }, {}); const devConfig = { mode: "development", output: { path: path.resolve(__dirname, '../build'), filename: 'bundle.dev.js' }, plugins: [ new webpack.DefinePlugin(envVars) ], module: { rules: [ { test: /\.json$/, type: 'javascript/auto', use: [ { loader: 'string-replace-loader', options: { search: /process\.env\.([A-Z_]+)/g, replace: (match, key) => env[key] || match } } ] } ] }, devtool: 'eval-source-map', }; module.exports = merge(commonConfig, devConfig);
- 调整
myJsonFile.json里的变量写法:
[ { "appId": "xyz", "name": "abc", "title": "Test", "description": "Test", "api": "process.env.API_URL/myAPI" } ]
这个方案适合需要统一处理所有JSON文件的场景。
内容的提问来源于stack exchange,提问作者Ankit Jain
相关产品推荐
相关产品推荐

