【问题标题】:How can I "sendFile" and serve multiple static builds using express.js?如何使用 express.js “发送文件”并提供多个静态构建?
【发布时间】:2022-01-23 06:28:48
【问题描述】:

我想要实现的目标

我希望有一个快速后端服务于多个 react 静态构建,而这些构建是 react 应用主站点的子域。 react-router-dom 仍然可以在各个 react 应用程序构建中的页面组件之间导航。

现状

我使用npx create-react-app ./ 创建了三个应用程序。我有一个使用react-router-dom 的“主页”站点,然后是两个名为“test-1”和“test-2”的“组合站点”。

在“主页”中,我使用简单的<a href="../portfolio-site/test-1">/* */</a>(注意这是一个相对路径)导航到“投资组合网站”。

两个“投资组合网站”都包含一个基本名称,即<BrowserRouter basename="portfolio-sites/test1">

文件结构是这样的(注意:所有构建都是默认的 react 构建,我没有个性化):

./public/home/build/index.html
./public/portfolio-sites/test1/build/index.html
./public/portfolio-sites/test2/build/index.html
./index.js (express.js code)

问题

我可以查看“主页”站点,但是当我单击任何一个投资组合站点的链接时,什么都没有返回。浏览器控制台说:

Uncaught SyntaxError: Unexpected token '<'

 Manifest: Line: 1, column: 1, Syntax error.

依赖关系

  • 节点版本:v16.13.2(最新版本)
  • “快递”:“^4.17.2”(最新),
  • “nodemon”:“^2.0.15”(最新),
  • “serve-static”:“^1.14.2”(最新)

React 应用程序使用的是最新的 npx。 ("反应": "^17.0.2")

我的 EXPRESS.JS 文件 (INDEX.JS)

require("dotenv").config();

const express = require("express");
const app = express();
const path = require("path");
const serveStatic = require("serve-static");

const PORT = process.env.PORT || 3001;

// SERVE STATIC BUILDS
app.use("/", serveStatic(path.join(__dirname, "public/home/build")));
app.use(
    "/portfolio-sites/test-1",
    serveStatic(path.join(__dirname, "public/portfolio-sites/test1/build"))
);
app.use(
    "/portfolio-sites/test-2",
    serveStatic(path.join(__dirname, "public/portfolio-sites/test2/build"))
);

// SERVE ROOT ROUTE
app.get("/", (req, res) => {
    res.sendFile(path.join(__dirname, "public/home/build/index.html"));
});

// SERVE PORTFOLIO SITES' ROUTES
app.get("/portfolio-sites/test-1", (req, res) => {
    res.sendFile(
        path.join(__dirname, "public/portfolio-sites/test1/build/index.html")
    );
    // res.send("test 1");
});

app.get("/portfolio-sites/test-2", (req, res) => {
    res.sendFile(
        path.join(__dirname, "public/portfolio-sites/test2/build/index.html")
    );
    // res.send("test 2");
});

// SERVE REACT-ROUTER-DOM HOME ROUTES
app.get("/*", (req, res) => {
    res.sendFile(path.join(__dirname, "public/home/build/index.html"));
});

// LISTEN ON PORT
app.listen(PORT, () => console.log(`Listening on port ${PORT}.`));

我尝试了什么以及问题可能是什么

我尝试将 "homepage": "./" 添加到主目录的 package.json 中。也许在投资组合站点的 package.json 中添加一个“主页”字段可以解决这个问题?

我尝试使用express.static,但它不起作用,所以我尝试使用serveStatic(如上所示)。

如果我替换:

res.sendFile(
    path.join(__dirname, "public/portfolio-sites/test1/build/index.html")
);

res.send("test 1");

并注释掉

app.use(
    "/portfolio-sites/test-1",
    serveStatic(path.join(__dirname, "public/portfolio-sites/test1/build"))
);

“test 1”已正确呈现,所以问题一定出在:

  • 我如何为投资组合网站的静态文件提供服务,或者,
  • 我如何在app.get 中使用“sendFile”,或者,
  • 在我的“主”目录的&lt;a href=""&gt; 中使用的相对路径内。

我对 express.js 感到很迷茫和陌生。非常感谢任何帮助,我不会忘记给任何帮助他们的人。

【问题讨论】:

  • 我错过了您描述问题所在的部分。意外的 404 响应(对哪个请求)?还是服务器控制台中的错误?另外,“express.static 不起作用”是什么意思?
  • 我很抱歉。我添加了一个名为“问题”的部分,其中包含控制台日志和所发生情况的描述。干杯
  • 请比“什么都没有回来”更具体。这听起来好像浏览器根本没有响应,另一方面,浏览器发现了语法错误,所以肯定有响应。响应的状态、标头或负载有什么可疑之处吗?
  • 您的错误可能在投资组合文件中。此代码适用于我(您可以删除服务静态)
  • 终端不显示任何错误但浏览器不显示页面。浏览器控制台会显示我提到的错误,并且路由器会根据我单击的投资组合站点链接正确转到 localhost:3001/portfolio-sites/test-1localhost:3001/portfolio-sites/test-2

标签: node.js reactjs express create-react-app


【解决方案1】:
  • Uncaught SyntaxError: Unexpected token '<'
    

您可以使用 express 设置多个公共路径。您收到此错误是因为您传递的路径不正确。

 path.join(__dirname, "public/home/build")

这不是加入目录的正确方法。 macos和linux使用“/”,windows使用\这就是我们使用path.join的原因。应该是

 path.join(__dirname, "public","home","build")
  •  Manifest: Line: 1, column: 1, Syntax error.
    

这个错误意味着,在 html 文件中,有一个指向 manifest 的链接。像这样:

链接 rel="manifest" href="/manifest.json">

确保manifest.json 存在于正确的路径中。

  • 同时检查 html 文件中的所有其他 linksrc 以确保它们指向正确的路径。

  • serve-static 的用法可能不正确。而是尝试使用 express.static。首先设置正确的路径:

    const publicPath1 = path.join(__dirname, "public","home","build");
    const publicPath2 = path.join(__dirname, "public","home","build2");
    const publicPath3 = path.join(__dirname, "public","home","build3");
    

然后注册那些应用

app.use(express.static(publicPath1));
app.use(express.static(publicPath2));
app.use(express.static(publicPath3));

只需与应用程序一起使用

app.get("/", (req, res) => {
  res.sendFile(path.join(publicPath1, "index.html"));
});


 

【讨论】:

  • 我已经更正了 path.join 并且没有任何改变。 npm run build 中指向 manifest.json 文件的链接似乎是正确的。
  • 文件名是否正确?
  • 我看不到文件名有任何问题。我确实在我的问题中添加了一个显示文件结构的部分。它们似乎都匹配。
  • @srWebDev 使用 express.static 代替 npm 包。也许包的用法不同。我用指令更新了答案
猜你喜欢
  • 2018-09-21
  • 1970-01-01
  • 1970-01-01
  • 2014-11-24
  • 2020-08-03
  • 2016-11-13
  • 2014-01-12
  • 2013-06-10
  • 1970-01-01
相关资源
最近更新 更多