在React项目中使用dotenv是否可行?

143

我想设置一些环境变量(用于调用开发/生产环境的API端点,根据开发/生产使用不同的密钥等),我想知道是否可以使用dotenv。

我已经安装了dotenv,并且正在使用webpack。

我的webpack入口是main.js,所以我在这个文件中放置了require('dotenv').config()

然后,在我的webpack配置中,我放置了这个:

  new webpack.EnvironmentPlugin([
    'NODE_ENV',
    '__DEV_BASE_URL__'  //base url for dev api endpoints
  ])

然而,它仍然没有定义。我该如何正确地做这件事?

6个回答

470

很抱歉翻出这个老问题,但是
react-scripts 其实在幕后使用了 dotenv 库。

从 react-scripts@0.2.3 开始,你可以按以下方式处理环境变量:

  1. 在项目的根目录中创建.env文件
  2. 在该文件中设置以REACT_APP_开头的环境变量
  3. 在组件中通过process.env.REACT_APP_... 来访问它

.env

REACT_APP_BASE_URL=http://localhost:3000

App.js

const BASE_URL = process.env.REACT_APP_BASE_URL;

查看文档了解更多详细信息。


76
谢谢Dmitry。对于那些尝试但无法立即运行的人,请重新启动你的react应用程序。 - Pedro Ferrari
16
另外需要注意的是,自行安装dotenv并进行初始化似乎会破坏一些东西。 - Gustavo Morais
2
这样使用 API 密钥是否存在风险?这些变量不会在生产环境中编译并公开吗? - Ariel Frischer
1
@ArielFrischer 这里有一个详细的好答案:https://dev59.com/o1YN5IYBdhLWcg3w07Fx - Dmitry Demidovsky
2
注意:你 必须 创建以 REACT_APP_ 开头的自定义环境变量。(https://create-react-app.dev/docs/adding-custom-environment-variables/) - aderchox
显示剩余12条评论

66

简而言之,不能。浏览器无法访问本地或服务器环境变量,因此dotenv没有可以查找的内容。相反,您可以在React应用程序中指定普通变量,通常在设置模块中。

Webpack可以从构建机器中获取环境变量,并将它们嵌入到您的设置文件中。但是它的作用是在构建时实际替换字符串,而不是运行时。因此,每次构建您的应用程序时,这些值都会被硬编码到其中。这些值可以通过process.env对象进行访问。

var nodeEnv = process.env.NODE_ENV;

此外,您可以使用webpack的DefinePlugin,它允许您根据构建目标(dev、prod等)显式地指定不同的值。请注意,您必须将传递给它的所有值进行JSON.stringify

new webpack.DefinePlugin({
    'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development')
}),

这很适合用于任何公共信息,但绝不能用于私钥、密码或API密钥等敏感信息。因为内嵌的任何值都是公开可访问的,如果包含敏感信息,则可能被恶意使用。对于这些内容,您需要编写一些服务器端代码并构建一个简单的API,该API可以使用密钥进行身份验证,然后将相关详细信息传递给客户端应用程序。您的服务器端API充当中介,保护您的机密信息,同时获取所需的数据。


2
谢谢。对于像 API 密钥这样的东西,我该怎么办?例如,Google 地图 API 密钥。我的意思是,那个应该没问题,因为只有一个域名被列入白名单。但无论如何,我还是很好奇。谢谢! - user1354934
1
我在我的回答中添加了如何做到这一点的解释。简短的答案是编写一个服务器端应用程序,让客户端应用程序可以与其通信,并在其中执行所有私有/机密操作。 - Soviut
1
谢谢。抱歉如果这听起来很愚蠢,但是你的意思是像我现在所做的那样吗——我的后端(express应用程序)有一个/api-auth端点,它发送一个JWT,然后将其存储在LS中。如果它是有效的(否则刷新它),我使用它,以便客户端不需要担心获取有效令牌来访问任何api响应/数据。 - user1354934
1
有点像。您对用户进行身份验证,但也可以使用您的API代理其他API。因此,所有API请求,即使是对Google API的请求,也可以通过您的服务器进行代理。客户端只关心您的API以及它是否已通过身份验证。 - Soviut
2
这个答案应该被更受欢迎的答案所取代,作为正确的答案。 - Randomness Slayer

19

实际上,你可以在你的 React 应用中使用 webpack 来使用 dotenv。此外,有几种方法可以实现。但是,请记住这仍然是一个构建时配置。

  1. 与上面的答案类似。在你的 webpack 配置中导入dotenv并使用 DefinePlugin 将变量传递给你的 React 应用程序。关于如何根据当前配置注入.env文件的更完整指南可以在这篇博客中找到

  2. 使用dotenv-webpack插件。我个人觉得它非常方便。假设你有环境:devstagingprod。你为每个环境创建一个 .env 文件(.env.dev.env.staging等)。在你的 webpack 配置中,你需要选择一个正确的环境文件:

const Dotenv = require('dotenv-webpack');

module.exports = (env, argv) => {
    const envPath = env.ENVIRONMENT ? `.env.${env.ENVIRONMENT}` : '.env';

    const config = {
        ...
        plugins: [
            new Dotenv({
                path: envPath
            })
        ]
    };

    return config;
};

当您为特定的环境构建应用程序时,只需将环境名称传递给webpack:

webpack --config webpack.config.js --env.ENVIRONMENT=dev

19
  1. 创建.env文件
    API_URL=http://localhost:8000
    
  2. 安装dotenv npm包
    $ npm install --save-dev dotenv
    
  3. 配置webpack以添加环境变量
    const webpack = require('webpack');
    const dotenv = require('dotenv');
    
    module.exports = () => {
      // 调用dotenv并返回一个解析后的对象
      const env = dotenv.config().parsed;
    
      // 将其减少为一个漂亮的对象,与之前相同
      const envKeys = Object.keys(env).reduce((prev, next) => {
        prev[`process.env.${next}`] = JSON.stringify(env[next]);
        return prev;
      }, {});
    
      return {
        plugins: [
        new webpack.DefinePlugin(envKeys)
      ]
    };
    

1
那么我该如何在我的服务中使用它们呢? - Vladyn
@Vladyn 你可以像平常一样使用它们:process.env.MY_ENV_VARIABLE - Raul Rene

2
为了在React项目中设置.env文件,请按照以下步骤进行操作:
  1. 在您的React项目根目录下创建一个名为.env的新文件。
  2. 按照VARIABLE_NAME=VALUE的格式将环境变量添加到.env文件中。例如:

    REACT_APP_API_URL=https://api.example.com
    REACT_APP_API_KEY=YOUR_API_KEY
    

    注意:建议使用REACT_APP_作为环境变量的前缀,以确保它们被React的构建过程识别。

  3. 保存.env文件。
  4. 重新启动开发服务器或构建过程以加载环境变量。
在你的React组件中,你可以像这样访问环境变量:
const apiUrl = process.env.REACT_APP_API_URL;
const apiKey = process.env.REACT_APP_API_KEY;

确保不要将.env文件提交到像Git这样的版本控制系统中,因为它可能包含敏感信息,如API密钥和其他凭据。
如果您正在使用Create React App,它会自动从.env文件中获取变量。但是,如果您正在使用自定义设置,则可能需要相应地配置构建工具以支持.env文件。

-12

我刚在源文件夹中创建了一个config.json:

{
    "api_url" : "http://localhost:8080/"
}

将其导入我需要它的文件中。
const config = require('./config.json');

并使用了config.api_url


1
但这并没有回答Dotenv是否可以在React项目中使用的问题。 - Ray
这与dotenv无关,伙计。 - szymeo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接