简体   繁体   English

“从服务器注入数据”到 React 应用程序的 index.html

[英]"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"));

...

Overview:概述:

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.此后端应用程序还提供反应生产文件。

  • Load original index.html加载原始索引.html
  • For each substitution I want to do:对于我想做的每个替换:
    • modified = modified.replace(substitutionKey, substitute);
  • Write new mutated_index.html to disk.将新的mutated_index.html写入磁盘。
  • Serve mutated_index.html in app.get("/", ...) and app.get("/index.html", ...)mutated_index.html app.get("/", ...)app.get("/index.html", ...)中提供 mutated_index.html
    • Below this, serve the other files: app.use(express.static("/build"));在此之下,提供其他文件: app.use(express.static("/build"));

Long term solution长期解决方案

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM