【问题标题】:Gatsby, Environment variables not accessible in browserGatsby,浏览器中无法访问的环境变量
【发布时间】:2020-02-17 16:20:46
【问题描述】:

我想使用环境变量。我创建了.env.development 文件并放置了一些变量。然后我包含dotenv 插件来读取gatsby-config.js 中的变量:

require('dotenv').config({
    path: `.env.${process.env.NODE_ENV}`
});

.env.development的内容:

GATSBY_APP=MYAPP

它在 gatbsy-node.js 中工作,但在浏览器 (REACT) 中它是空的。我显示 console.log(process.env) 并返回空对象。

即使我安装和配置gatsby-plugin-env-variables

【问题讨论】:

    标签: reactjs browser process environment-variables gatsby


    【解决方案1】:

    看起来你正在结合两种方法,这可能是你遇到麻烦的地方。

    1. Gatsby 开箱即用,支持在特定于环境的 .env.[environment] 文件(例如 .env.development)中定义环境变量,前提是这些文件位于项目的根目录中(例如 your-project/.env.development)。 Documentation for this feature。您确实不需要需要安装或配置 dotenv 才能使其工作。

    2. 另一种方法是使用dotenv,这将允许您使用通用的.env 文件。然后需要导入并配置该工具,一般在gatsby-config.js的最上面一行完成,如下所示:

       require("dotenv").config()
      

    请注意,您在这种情况下指定环境名称(例如development),并且您不会将.env 文件提交到您的存储库。

    您可能遇到的另一个问题是您的部分代码使用 Node 在服务器端运行,而部分代码在客户端(在浏览器中)运行。由于process.env 仅在 Node 中可用,Gatsby 做了一些额外的工作以使其在浏览器中可用。不过,我们不希望所有将这些经常包含秘密的变量提供给浏览器,因此 Gatsby 只复制那些名称以 GATSBY_ 开头的变量。最后,作为这些变量被复制的方式的副作用,您必须明确引用它们才能使您的构建工作:

    // this is okay everywhere
    const GATSBY_APP = process.env.GATSBY_APP
    
    // this won't work in code that runs client-side, but will work
    // in `gatsby-node.js` and other files that only run in Node
    const { GATSBY_APP } = process.env
    

    【讨论】:

    • 我无法编辑答案,因为它只是一个字符,但 env var 前缀需要一个下划线 - 它是 GATSBY_ 而不仅仅是 GATSBY
    • Coreyward,这不是做同一件事的两种不同方法,而是做不同的事情。根据文档,Gatsby 的默认支持允许将 env 变量放入浏览器,而 dotenv 方法允许将 env 变量放入节点 js 文件中。如果他需要访问这两个地方的变量,他这样做是正确的。我只使用默认方式进行了测试,还测试了在命令行中传入 env 变量(两者都在变量名的开头使用 GATSBY_),但没有任何东西进入浏览器。 @Youssef Lahssini,你有想过这个吗?
    • @DaledeSilva 我可以向您保证,如果您正在配置 dotenv 并且不会犯与 OP 相同的错误,那么任何一个都可以很好地将 GATSBY_ 前缀的环境变量导入浏览器。我在几十个网站上使用它。
    • @Coreyward ,你是对的,两者都适用于浏览器:) 不过,我认为默认和 dotenv 方法都存在,因为获取环境变量的方式没有任何问题进入 gatsby-*.js 文件(而不是浏览器)是使用 dotenv,即使默认方法仍然存在 - 因此,如果您在构建时需要环境变量,则必须同时拥有两者。但是,OP 遇到的这个问题仅与他的 console.log 有关。我有同样的问题并提交了一个描述它的答案。
    • 注意:我还没有实际测试过,看看是否一些vars通过默认方法和一些通过dotenv方法解析的vars在一起完成时都共存,但是我已经导入了多个env文件dotenv 调用并没有任何问题 - 所以我想这很好。
    【解决方案2】:

    如果您想将自己的环境变量列入白名单,无论是作为前缀(此处显示)还是列出它们,您可以在 gatsby-node.js 文件中添加类似这样的内容:

    exports.onCreateWebpackConfig = ({ actions, getConfig }) => {
        const config = getConfig();
    
        // Allow process.env.MY_WHITELIST_PREFIX_* environment variables
        const definePlugin = config.plugins.find(p => p.definitions);
        for (const [k, v] of Object.entries(process.env)) {
            if (k.startsWith("MY_WHITELIST_PREFIX_")) {
                definePlugin.definitions[`process.env.${k}`] = JSON.stringify(v);
            }
        }
    
        actions.replaceWebpackConfig(config);
    };
    

    【讨论】:

      【解决方案3】:

      我遇到了同样的问题,只是发现我做错了什么。看起来你在做同样的事情。

      文档和@coreyward 给出的解释都是正确的,但是,请注意,虽然 corey 暗示它们是两种不同的方法,问题可能是它们存在冲突,但它们不是,它们做不同的事情 - 所以你的那个代码很好。

      问题出在,您正在控制台记录 process.env。事实证明,即使变量可能存在,这也将始终输出一个空对象。

      您必须直接console.log(process.env.GATSBY_APP) 才能看到任何值。 (Reference)

      这本质上是 Corey 在他的“最终作为副作用”部分中指出的内容的扩展,但是,他编写它的方式暗示这是一个解构问题 - 但不限于此。

      在我的情况下,我犯了上述错误并且没有正确地使用 GATSBY_ 公开变量,然后在测试时我开始像你一样在搜索原因时记录整个 env 对象。这意味着即使我添加了正确的 GATSBY_ 前缀,我仍然看不到任何东西。

      简而言之,可能只是您的 console.log 行有问题 - 直接访问变量,而不是整个 env 对象。

      【讨论】:

        【解决方案4】:

        Gatsby 网站是关于使用 environment variables 的一个有据可查的部分。要点是环境变量仅在内部 nodejs 服务器正在服务器呈现您的站点时在构建期间可用。为了在浏览器中获取这些环境变量,您需要使用特殊的gatsby-*.js 文件以编程方式嵌入它们。 The example 他们提供的似乎接近您想要实现的目标。

        【讨论】:

          猜你喜欢
          • 2020-08-16
          • 2019-05-13
          • 2018-10-15
          • 2014-02-11
          • 2018-03-17
          • 2021-05-05
          • 1970-01-01
          • 1970-01-01
          • 2023-01-08
          相关资源
          最近更新 更多