是否可以在客户端的前端使用 React 服务器环境变量?

Is it possible to use a React server enviroment variables into frontend at client side?

我正在使用 PKG,为我的 Appolo GraphQL Server + React 客户端制作一个可执行的 .exe 文件,将它们全部捆绑到一个 exe 文件中。它正在运行,现在有一个要求:应用程序应该从某个地方读取一个 IP 地址并将其用作主机、端口等的常量。

我在服务器端使用 fs.readFileSync - 没关系。我可以读取任何文本文件,因为它是 nodejs 服务器端。现在的要求是将该 IP 传递给客户端文件 -> 进入静态文件夹(标记为 *),其中我有 constant.js 和要在内部连接的客户端 IP(已编译 static/js..)。服务器端文件(NodeJs+React):

├───build
│   └───static
│       ├───css
│       ├───*js*
│       └───media
├───config
├───src
│   ├───core
│   ├───graphql
│   ├───guardServer
│   └───pg
└───SSL

客户端 React 文件树:

├───.idea
├───.vs
│   └───React
│       └───v16
├───build
│   └───static
│       ├───css
│       ├───js
│       └───media
├───public
└───src
    ├───components
    │   ├───core
    │   │   ├───functions
    │   │   └───modal
    │   └───modules
    │       ├───account
    │       ├───adminPanel
    │       │   └───pages
    │       ├───archive
    │       ├───hr-department
    │       │   └───pages
    │       ├───logs
    │       ├───monitor
    │       └───reports
    ├───config
    └───images

所以我的行为是:npm run build一个客户。然后我使用文件夹 build 并替换服务器端文件:server/build 文件夹。然后我在服务器端做 - npm run build 并接收一个 exe 文件。此 exe 的服务器部分 (/server/index.js) 可以读取 settings.txt,但不能读取 /server/build/static/js...

我的问题是:是否可以通过某种方式修改 webpacker,并且可以使用命令从客户端访问(并且是动态的)服务器环境变量 process.env.myvar?

如果没有,我在这种情况下是否有什么技巧可以使用?请注意,由于文件系统快照限制,现在允许使用 PKG 的 fs.writeFileSync

服务器端代码:

let fileContent = fs.readFileSync("D:\settings.txt", "utf8");
let getIp=JSON.parse(fileContent); //fine working, got IP

使用 Apollo Client 的客户端,我需要从服务器端传递那个 IP,有什么想法吗?

Ajeet Shah 更新。我做了什么:

On my server.js - var __SERVER_DATA__ = "192.168.0.111";

in index.html of client - <script>
      window.SERVER_DATA = __SERVER_DATA__;
    </script>

in index.js of client - console.log(window.SERVER_DATA);

更新:

我想我会在 运行 localhost:port 上使用微型 http 服务器一段时间。从那里我可以自由阅读任何设置。谢谢大家有用的答案。

我选择了更多选项的答案,并且有关于 localStorage 的建议。非常感谢大家的提醒。仍在尝试实施提供的方法。

更新。

我已经完成了。我使用了 html 变量 window.SERVER_DATA = __SERVER_DATA__,如此处所述 - https://create-react-app.dev/docs/title-and-meta-tags/#injecting-data-from-the-server-into-the-page。我稍后会决定如何处理最佳答案,如果没有人会 post 额外的答案。

docs 中所述,您可以创建可注入前端代码的服务器端变量。

这是您需要做的:

  1. 创建一个 JS 脚本,比如 myConfig.js,并将其放在服务器上的 public 位置,以便前端可以加载它。
  2. 在此文件中定义配置数据,例如:
const myConfig1 = "foo bar"
const myConfig2 = "anythng else"
  1. 在前端应用程序 index.html 文件的 <head> 部分添加以下行。它将从服务器读取 load/data 并将其设置在全局 window 对象中。
<script src="http://path/to/file/on/server/myConfig.js" type="text/javascript"></script>
<script>
  window.myConfig1 = myConfig1
  window.myConfig2 = myConfig2
</script>
  1. 现在您可以使用全局 window 对象作为 window['myConfig1']window['myConfig2'].
  2. 在您的 ReactJS 应用程序中访问这些配置变量(来自服务器)

使用此方法,当您更改配置变量时,您无需使用 重建 前端应用程序 npm run build,因为这些已定义,与前端分开,在服务器上。要更改这些配置变量,您只需更改服务器上的那些并在浏览器中刷新即可。

在后端技术中,一切都是通过环境变量解决的,当您必须将应用程序移至各个阶段(开发、暂存、生产)时,这是一个很好的做法。

在客户端技术(react、vue、angular或简单的js)中动态获取这些值是复杂的。

查看此答案以了解变量在 js 客户端中的工作方式或如何注入动态值

REACT_APP

一种策略是使用 REACT_APP 变量

https://create-react-app.dev/docs/adding-custom-environment-variables/

因此,如果您在服务器端创建此变量

export REACT_APP_remote_ip

React 库将为您创建一个变量。你可以在任何反应文件中使用 thia var

process.env.remote_ip

Webpack

与 REACT_APP 类似,webpack 提供了一个选项,可以将服务器端变量公开为全局 javascript 变量,可以在任何 .js 文件中使用

new webpack.DefinePlugin({
  API_BASE_URL: JSON.stringify(process.env.API_BASE_URL)
})

/设置

另一种选择是在您的 nodejs 服务器端创建一个端点。此端点可以访问环境值,因此您可以 return 任何您想要的东西:

res.json({
  "ip1": process.env.remote_ip_1
});

在此之后,您只需要在您的反应或javascript文件的最早期的js或入口点中调用或调用此端点/设置。

最后,/settings 的 return 可以公开为全局 javascript 值或存储在浏览器的本地存储中