是否可以在反应项目中使用 dotenv?

Posted

技术标签:

【中文标题】是否可以在反应项目中使用 dotenv?【英文标题】:Is it possible to use dotenv in a react project? 【发布时间】:2017-06-30 04:05:51 【问题描述】:

我正在尝试设置一些环境变量(用于对 dev/prod 端点进行 API 调用、取决于 dev/prod 的密钥等),我想知道使用 dotenv 是否可行。

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

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

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

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

但是,它仍然是未定义的。我怎样才能正确地做到这一点?

【问题讨论】:

【参考方案1】:

简短的回答是否定的。浏览器无法访问本地或服务器环境变量,因此 dotenv 无需查找任何内容。相反,您可以在 React 应用程序中指定普通变量,通常在设置模块中。

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

var nodeEnv = process.env.NODE_ENV;

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

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

这适用于任何类型的公共详细信息,但不应切勿用于任何类型的私钥、密码或 API 机密。这是因为任何嵌入的值都是可公开访问的,如果它们包含敏感细节,则可能被恶意使用。对于这类事情,您需要编写一些服务器端代码并​​构建一个简单的 API,该 API 可以使用秘密向 3rd 方 API 进行身份验证,然后将相关详细信息传递给您的客户端应用程序。您的服务器端 API 充当中介,在保护您的机密的同时仍能获取您需要的数据。

【讨论】:

谢谢。我怎样才能为 API 密钥之类的东西做到这一点?例如,谷歌地图 API 密钥。我的意思是,我猜这个可以暴露,因为只有一个域来源被列入白名单。但无论如何只是好奇。泰! 我在回答中添加了如何执行此操作的说明。简短的回答是编写一个服务器端应用程序,您的客户端应用程序可以与之通信并在其中执行所有私有/秘密的事情。 谢谢。抱歉,如果这听起来很愚蠢,但你的意思是不是像我现在所做的那样 - 我的后端(快速应用程序)有一个 /api-auth 端点,它通过 JWT 发送,然后存储在 LS 中。如果它有效(否则刷新它),我会使用它,以便客户端需要担心获取有效令牌来访问任何 api 响应/数据。 有点。您验证您的用户,但您也可以使用您的 API 代理其他 API。因此,所有 API 请求,甚至是对 Google API 的请求,都可能是通过您的服务器的代理。客户端只关心你的 API 以及它是否通过了身份验证。 此答案应替换为更受欢迎的答案作为正确答案。【参考方案2】:

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

    与上面的答案类似。您在 webpack 配置中导入 dotenv 并使用 DefinePlugin 将变量传递给您的 React 应用程序。有关如何根据当前配置注入 .env 文件的更完整指南,请参阅 in this blog。

    使用dotenv-webpack plugin。我个人觉得真的很方便。假设您有环境:devstagingprod。您为每个环境(.env.dev.env.staging 等)创建 .env 文件。在你的 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

【讨论】:

【参考方案3】:

很抱歉提出旧问题,但react-scripts 实际上在后台使用 dotenv 库。

使用 react-scripts@0.2.3 及更高版本,您可以通过这种方式使用环境变量:

    在项目根目录下创建.env文件 在REACT_APP_那里设置环境变量 通过组件中的process.env.REACT_APP_...访问它

.env

REACT_APP_BASE_URL=http://localhost:3000

App.js

const BASE_URL = process.env.REACT_APP_BASE_URL;

更多详情请见docs。

【讨论】:

感谢 Dmitry,感谢尝试过但没有立即工作的人,请重新启动您的 react 应用程序。 另一个注意事项,自己安装dotenv并初始化它似乎搞砸了。 如果我们使用nodemon并将值存储在nodemon.js中,我们必须重新启动服务器。 Nodemon 在文件更改时自动重新加载将不起作用,并且值不会存储在 process.env 中 这对于 API 密钥是否危险,这些变量不会编译并在生产中公开吗? @ArielFrischer 这是一个很好的详细答案:***.com/questions/46838015/…【参考方案4】:
    创建 .env 文件
    API_URL=http://localhost:8000
    
    安装 dotenv npm 包
    $ npm install --save-dev dotenv
    
    配置 webpack 以添加 env 变量
    const webpack = require('webpack');
    const dotenv = require('dotenv');
    
    module.exports = () => 
      // call dotenv and it will return an Object with a parsed key 
      const env = dotenv.config().parsed;
    
      // reduce it to a nice object, the same as before
      const envKeys = Object.keys(env).reduce((prev, next) => 
        prev[`process.env.$next`] = JSON.stringify(env[next]);
        return prev;
      , );
    
      return 
        plugins: [
        new webpack.DefinePlugin(envKeys)
      ]
    ;
    
    干得好!享受 React 和 dotenv。

【讨论】:

【参考方案5】:

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


    "api_url" : "http://localhost:8080/"

然后在我需要的文件中需要它

const config = require('./config.json');

并使用了 config.api_url

【讨论】:

但这并不能回答 Dotenv 是否可以在反应项目中使用的问题

以上是关于是否可以在反应项目中使用 dotenv?的主要内容,如果未能解决你的问题,请参考以下文章

Dotenv 配置不适用于 React.js 应用

NodeJs:dotenv不适用于嵌套路径

是否可以在我的反应项目中使用相同库的不同版本

是否有可能在裸反应本机项目中使用expo视频?

NPM库:dotenv,从文件加载环境变量

如何在我的整个项目中使用 phpdotenv 库?