![](/img/trans.png)
[英]React-snapshot pre-renders index.html on all routes with create-react-app and serve
[英]How to properly serve the create-react-app index from the server?
我正在使用 create-react-app 开发一个应用程序,一切都很顺利,除了我最初想从后端提供index.html
的事实,并且在这样做时遇到了麻烦。
我想这样做的原因是,我可以将一些特定于用户的 Javascript 注入index.html
页面,并在用户最初点击页面时运行各种其他查询( 类似于此人)
因此,我不是连接到localhost:3000
来查看应用程序,而是连接到localhost:8080
并让服务器提供此index.html
文件。 (所有其他资产(js、css、图像)仍将位于localhost:3000
)
这样做的一个问题似乎是脚本标签默认不包含在index.html
文件中,而是由 create-react-app 生成。 也就是说,这是我的index.html
文件:
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
</head>
<body>
<div id="root"></div>
</body>
</html>
如果我运行npm start
,然后检查源代码,它将是这个(由于我认为是 CRA 运行时注入):
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rel="shortcut icon" href="/favicon.ico">
</head>
<body>
<div id="root"></div>
</body>
<script src="/static/js/bundle.js"></script><script src="/static/js/0.chunk.js"></script><script src="/static/js/main.chunk.js"></script>
</html>
结果,在服务器上,我目前正在尝试这样的事情:
#[get("/")]
fn handle_index() {
let scripts = r#"<script src="https://localhost:3000/static/js/bundle.js"></script>
<script src="https://localhost:3000/static/js/0.chunk.js"></script>
<script src="https://localhost:3000/static/js/main.chunk.js"></script>"#;
let index_html = include_str!("../frontend/public/index.html");
let document = format!(r#"<script type="application/javascript">
window.APP_GLOBALS = { user_id: 5, color: "red" };
</script> {}{}"#, data, index_html, scripts);
return document;
}
因为我不确定注入这些脚本标签的任何其他方式。 看起来 create-react-app 只对我的localhost:3000
页面执行,而不是对localhost:8080
页面执行。
这似乎有点奏效。 也就是页面加载了,但是有两个问题。
许多资产 URL 现在是错误的。 他们改为指向localhost:8080
而不是localhost:3000
,并且%PUBLIC_URL%
URL 同样不起作用(我想这是另一个不再发生的过程)
websocket autoreload 开发服务器不再工作。 当我导航到localhost:3000
而不是localhost:8080
时,它起作用。 当我编辑文件并保存时,页面会变成白色,控制台中没有错误。
我认为所有这些问题都是由于相同的原因: create-react-app
通常以某种方式预处理index.html
文件(转换%PUBLIC_URL%
,添加那些脚本标签,处理重新加载),但它不再这样做当文件从服务器返回时。
我想知道的是如何恢复此功能。 基本上,让这些脚本标签和%PUBLIC_URL%
进程发生而我的后端服务器不必尝试这样做。
当您运行npm start
,您是在告诉 CRA 使用 webpack 进行开发构建。 Webpack 会执行您看到的所有处理,例如注入脚本和替换%PUBLIC_URL%
。 您不希望后端为public
文件夹中的index.html
提供服务,因为 webpack 尚未处理该文件。 相反,您需要后端来提供 webpack 的构建输出。
npm start
配置是一个开发构建,它适用于开发但不适用于生产。 (此外,它不会将其输出保存到文件系统,因此如果您愿意,您甚至无法从后端提供它。请参阅CRA 问题 #1070 )。 如果你运行npm run build
,你会在build
文件夹中得到一个生产构建,你应该从后端提供它(然后你可以进行任何你需要的注入)。
这样做的缺点是构建需要更长的时间,当您更改前端文件时它不会自动重新构建,而且我不确定它给出的错误是否与npm start
一样有用。 因此,您可能希望在开发前端时使用npm start
并在测试后端时使用npm run build
。 还有一些像patch-package这样的项目可以让你将npm start
的构建输出保留在文件系统中,这样你就可以为它提供服务,但我没有尝试过其中的任何一个。
顺便说一句 - 从后端将脚本注入 html 时要小心。 考虑在后端设置 cookie 并在前端读取这些 cookie 之类的事情。 这更安全,更容易调试等。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.