无法在客户端 Javascript 中设置“process.env"的值

2022-01-16 00:00:00 environment-variables javascript

我有一个系统(它恰好是 Gatsby,但我认为这与这个问题无关)它使用 webpack DefinePlugin 将一些 EnvironmentVariables 附加到全局变量:process.env

I have a system (it happens to be Gatsby, but I don't believe that's relevant to this question) which is using webpack DefinePlugin to attach some EnvironmentVariables to the global variable: process.env

我可以很好地阅读这个.

I can read this just fine.

不幸的是,由于应用程序启动过程的怪异,我需要选择在站点加载后对这些 EnvironmentVariables 进行一些简短的覆盖.(在这个问题的背景下,没有兴趣讨论这是否是最佳选择.我知道还有其他选择;我想知道 this 是否可行)

Unfortunatley, due to weirdnesses in the app startup proces, I need have chosen to do some brief overwritting of those EnvironmentVariables after the site loads. (Not interested in discussing whether that's the best option, in the context of this question. I know there are other options; I want to know whether this is possible)

但它不起作用:(<小时>如果我尝试明确地这样做:

But it doesn't work :(


If I try to do it explicitly:

process.env.myVar = 'foo';

然后我得到 ReferenceError: invalid assignment left-hand side.

如果我通过索引器执行此操作(这似乎是 dotenv 所做的),那么它不会出错,但也不起作用:

If I do it by indexer (which appears to be what dotenv does) then it doesn't error, but also doesn't work:

console.log(process.env.myVar);
process.env['myVar'] = 'foo';
console.log(process.env.myVar);

将记录 undefined 两次.<小时>我做错了什么,我该如何解决?

will log undefined twice.


What am I doing wrong, and how do I fix this?

推荐答案

这个尝试的解决方案背后的前提是有缺陷的.

The premise behind this attempted solution was flawed.

我的印象是 webpack 使 process.env.* 在浏览器中作为对象可用".

I was under the impression that webpack "made process.env.* available as an object in the browser".

不会!

它实际上所做的是将您的代码转换成文字,无论您在哪里引用 process.env.那么看起来像 fetch(process.env.MY_URL_VAR);实际上并没有引用变量,它实际上在编译时被转译为 fetch("http://theActualValue.com").

What it actually does is to transpile you code down into literals wherever you reference process.env. So what looks like fetch(process.env.MY_URL_VAR); isn't in fact referencing a variable, it's actually being transpiled down into fetch("http://theActualValue.com") at compile time.

这意味着在概念上不可能修改process.env 对象"上的值,因为在转译的 javascript 中实际上并没有实际的对象.

That means that it's conceptually impossible to modify the values on the "process.env object", because there is not in fact an actual object, in the transpiled javascript.

这解释了为什么直接赋值会产生 ref 错误(您尝试执行 "someString" = "someOtherString";)但索引器没有.(我假设 process.env 被编译成一些不同的文字,这在技术上支持索引设置器)

This explains why the direct assignment gives a ref error (you tried to execute "someString" = "someOtherString";) but the indexer doesn't. (I assume that process.env gets compiled into some different literal, which technically supports an indexed setter)

唯一可用的解决方案是修改 webpack 构建过程(不是一个选项,尽管我很快会提出 PR 以使其成为可能:)),使用不同的过程将 Env.Vars 放入前端(子- 出于各种其他原因而优化)或使用 Gatsby 提供的各种环境控制来解决问题,以使其完全正常工作(出于其他原因令人反感).

The only solutions available would be to modify the webpack build process (not an option, though I will shortly raise a PR to make it possible :) ), use a different process for getting the Env.Vars into the frontEnd (sub-optimal for various other reasons) or to hack around with various bits of environment control that Gatsby provides to make it all kinda-sorta work (distasteful for yet other reasons).

相关文章