[英]"Inject data from server" into a React app's index.html
I'm trying to "inject data from the server into the page", as per create-react-app docs instead of hardcoding environment variables at build time:我正在尝试根据 create-react-app 文档“将数据从服务器注入页面”,而不是在构建时硬编码环境变量:
To read them at runtime , you would need to load HTML into memory on the server and replace placeholders in runtime, as described here .要在运行时读取它们,您需要在服务器上将 HTML 加载到 memory 并在运行时替换占位符,如此处所述。
<!doctype html>
<html lang="en">
<head>
<script>
window.SERVER_DATA = __SERVER_DATA__;
</script>
Then, on the server, you can replace
__SERVER_DATA__
with a JSON of real data right before sending the response.然后,在服务器上,您可以在发送响应之前将__SERVER_DATA__
替换为 JSON 的真实数据。
I've got an index.html
file which I'd like to inject URLs from environment variables into, using a backend application which serves the static/built file.我有一个index.html
文件,我想使用为静态/构建文件提供服务的后端应用程序将环境变量中的 URL 注入其中。
For example, in index.html
:例如,在index.html
中:
<script type="text/javascript">
// Runs before react application.
window.SERVICE_A_URL = "<%=SERVICE_A_URL%>";
window.SERVICE_B_URL = "<%=SERVICE_B_URL%>";
console.log(window.SERVICE_A_URL, window.SERVICE_B_URL);
</script>
My backend application (eg express) should inject SERVICE_A_URL=https://service_a.example.com
into <%=SERVICE_A_URL%>
.我的后端应用程序(例如 express)应该将SERVICE_A_URL=https://service_a.example.com
注入<%=SERVICE_A_URL%>
。
However, I cannot do this because when my React app builds, it finds this template "<%=SERVICE_A_URL%>"
and decides not to generate the index.html
file.但是,我不能这样做,因为当我的 React 应用程序构建时,它找到这个模板"<%=SERVICE_A_URL%>"
并决定不生成index.html
文件。 So I can't use ejs.所以我不能使用ejs。 I need to use something like __SERVER_DATA__
, not <%=SERVER_DATA%>
.我需要使用类似__SERVER_DATA__
的东西,而不是<%=SERVER_DATA%>
。 But what tool can I use to replace this at runtime?但是我可以使用什么工具在运行时替换它呢? For example, in an express server.例如,在快速服务器中。
Extra details:额外细节:
Why?: The other/better approach is to make a.network request to an API server to get the URLs dynamically.为什么?:另一种/更好的方法是向 API 服务器发出 .network 请求以动态获取 URL。 However, the application I'm working with would need a lot of refactoring to support this.但是,我正在使用的应用程序需要进行大量重构才能支持这一点。 I'll probably end up searching for ENV_VAR in the index.html and modifying it.我可能最终会在index.html中搜索 ENV_VAR 并对其进行修改。
NodeJS app节点应用程序
import express, {Request, Response} from 'express';
import ejs from 'ejs';
const app = express();
app.engine('html', ejs.renderFile);
const renderIndexHtmlWithServiceUrls = (req: Request, res: Response) => {
res.render('index.html', {
SERVICE_A_URL: process.env.SERVICE_A_URL,
SERVICE_B_URL: process.env.SERVICE_B_URL,
cache: true
})
}
app.get('/', renderIndexHtmlWithServiceUrls)
app.get('/index.html', renderIndexHtmlWithServiceUrls)
// Serve built react app
app.use(express.static("/build"));
...
I just ended up creating a mutated_index.html
file when the backend (expressJS) application launches.当后端 (expressJS) 应用程序启动时,我刚刚创建了一个mutated_index.html
文件。 Then I serve that to all clients when they request /
or /index.html
.然后,当所有客户请求/
或/index.html
时,我将其提供给他们。 This backend application also serves the react production files.此后端应用程序还提供反应生产文件。
modified = modified.replace(substitutionKey, substitute);
mutated_index.html
to disk.将新的mutated_index.html
写入磁盘。mutated_index.html
in app.get("/", ...)
and app.get("/index.html", ...)
在mutated_index.html
app.get("/", ...)
和app.get("/index.html", ...)
中提供 mutated_index.html
app.use(express.static("/build"));
在此之下,提供其他文件: app.use(express.static("/build"));
If you have this problem, I would suggest you refactor your application to avoid global variables if you need this functionality.如果你有这个问题,我建议你重构你的应用程序以避免全局变量,如果你需要这个功能。 Then you can make.network requests and instantiate services/clients when you get the data you need.然后,当您获得所需的数据时,您可以发出网络请求并实例化服务/客户端。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.