是否可以在客户端的前端使用 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 中所述,您可以创建可注入前端代码的服务器端变量。
这是您需要做的:
- 创建一个 JS 脚本,比如
myConfig.js
,并将其放在服务器上的 public 位置,以便前端可以加载它。
- 在此文件中定义配置数据,例如:
const myConfig1 = "foo bar"
const myConfig2 = "anythng else"
- 在前端应用程序
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>
- 现在您可以使用全局
window
对象作为 window['myConfig1']
和 window['myConfig2']
. 在您的 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 值或存储在浏览器的本地存储中
我正在使用 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 中所述,您可以创建可注入前端代码的服务器端变量。
这是您需要做的:
- 创建一个 JS 脚本,比如
myConfig.js
,并将其放在服务器上的 public 位置,以便前端可以加载它。 - 在此文件中定义配置数据,例如:
const myConfig1 = "foo bar"
const myConfig2 = "anythng else"
- 在前端应用程序
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>
- 现在您可以使用全局
window
对象作为window['myConfig1']
和window['myConfig2']
. 在您的 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 值或存储在浏览器的本地存储中