[英]How to properly serve the create-react-app index from the server?
I'm developing an application with create-react-app and all is going well, except for the fact that I would like to initially serve the index.html
from the backend, and am running into trouble doing so.我正在使用 create-react-app 开发一个应用程序,一切都很顺利,除了我最初想从后端提供
index.html
的事实,并且在这样做时遇到了麻烦。
The reason that I want to do this is so that I can inject some user-specific Javascript into the index.html
page and also run various other queries when the user initially hits the page ( similar to this person )我想这样做的原因是,我可以将一些特定于用户的 Javascript 注入
index.html
页面,并在用户最初点击页面时运行各种其他查询( 类似于此人)
So, instead of connecting to localhost:3000
to view the app, I would instead connect to localhost:8080
and have the server serve this index.html
file.因此,我不是连接到
localhost:3000
来查看应用程序,而是连接到localhost:8080
并让服务器提供此index.html
文件。 (all other assets (js, css, images) would still be on localhost:3000
) (所有其他资产(js、css、图像)仍将位于
localhost:3000
)
One issue with doing this seems to be that the script tags are not included in the index.html
file by default, and are instead generated by create-react-app.这样做的一个问题似乎是脚本标签默认不包含在
index.html
文件中,而是由 create-react-app 生成。 That is, say this is my index.html
file:也就是说,这是我的
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>
If I run npm start
, and then inspect the source, it will instead be this (due to CRA runtime injections I presume):如果我运行
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>
As a result, on the server, I'm currently trying something like this:结果,在服务器上,我目前正在尝试这样的事情:
#[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;
}
Because I'm not sure of any other way to inject those script tags.因为我不确定注入这些脚本标签的任何其他方式。 It looks like create-react-app only does it for my
localhost:3000
page, and not the localhost:8080
page.看起来 create-react-app 只对我的
localhost:3000
页面执行,而不是对localhost:8080
页面执行。
This seems to somewhat work.这似乎有点奏效。 That is, the page loads, but there are two issues.
也就是页面加载了,但是有两个问题。
Many of the asset URLs are now wrong.许多资产 URL 现在是错误的。 They are instead pointing to
localhost:8080
instead of localhost:3000
, and %PUBLIC_URL%
URL likewise doesn't work (I suppose this is another process that is no longer occurring)他们改为指向
localhost:8080
而不是localhost:3000
,并且%PUBLIC_URL%
URL 同样不起作用(我想这是另一个不再发生的过程)
The websocket autoreload dev server no longer works. websocket autoreload 开发服务器不再工作。 It works when I navigate to
localhost:3000
, but not localhost:8080
.当我导航到
localhost:3000
而不是localhost:8080
时,它起作用。 When I edit a file and save, the page just turns white with no errors in the console.当我编辑文件并保存时,页面会变成白色,控制台中没有错误。
I think all of these issues are due to the same cause: create-react-app
normally preprocesses the index.html
file in some way (converting %PUBLIC_URL%
, adding those script tags, handling reload), but it is no longer doing this when the file is instead returned from the server.我认为所有这些问题都是由于相同的原因:
create-react-app
通常以某种方式预处理index.html
文件(转换%PUBLIC_URL%
,添加那些脚本标签,处理重新加载),但它不再这样做当文件从服务器返回时。
What I'm wondering is how I can restore this functionality.我想知道的是如何恢复此功能。 Basically, have these script tags and
%PUBLIC_URL%
processes occur without my backend server having to attempt to do so.基本上,让这些脚本标签和
%PUBLIC_URL%
进程发生而我的后端服务器不必尝试这样做。
When you run npm start
, you are telling CRA to make a development build using webpack.当您运行
npm start
,您是在告诉 CRA 使用 webpack 进行开发构建。 Webpack does all of the processing you see like injecting scripts and replacing %PUBLIC_URL%
. Webpack 会执行您看到的所有处理,例如注入脚本和替换
%PUBLIC_URL%
。 You don't want your backend to serve the index.html
in the public
folder because that file hasn't been processed by webpack.您不希望后端为
public
文件夹中的index.html
提供服务,因为 webpack 尚未处理该文件。 Instead you need the backend to serve webpack's build output.相反,您需要后端来提供 webpack 的构建输出。
The npm start
configuration is a development build, which is good for development but not production. npm start
配置是一个开发构建,它适用于开发但不适用于生产。 (Also it doesn't save its output to the file system, so you couldn't even serve it from your backend if you wanted to. See CRA issue #1070 ). (此外,它不会将其输出保存到文件系统,因此如果您愿意,您甚至无法从后端提供它。请参阅CRA 问题 #1070 )。 If you run
npm run build
, you get a production build in the build
folder, which you should serve from your backend (and then you can make whatever injections you need).如果你运行
npm run build
,你会在build
文件夹中得到一个生产构建,你应该从后端提供它(然后你可以进行任何你需要的注入)。
The downside of this is that it takes longer to build, it doesn't rebuild automatically when you change your frontend files, and I'm not sure if the errors it gives are as useful as npm start
.这样做的缺点是构建需要更长的时间,当您更改前端文件时它不会自动重新构建,而且我不确定它给出的错误是否与
npm start
一样有用。 Thus you might want to use npm start
when developing the frontend and npm run build
when testing your backend.因此,您可能希望在开发前端时使用
npm start
并在测试后端时使用npm run build
。 There are also certain projects like patch-package that would allow you to make npm start
's build output stay in the file system so you can serve it, but I haven't tried any of them.还有一些像patch-package这样的项目可以让你将
npm start
的构建输出保留在文件系统中,这样你就可以为它提供服务,但我没有尝试过其中的任何一个。
BTW - be careful with injecting scripts into the html from your backend.顺便说一句 - 从后端将脚本注入 html 时要小心。 Consider something like setting cookies in your backend and reading those cookies in your frontend instead.
考虑在后端设置 cookie 并在前端读取这些 cookie 之类的事情。 This is safer, easier to debug, etc.
这更安全,更容易调试等。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.