首页 > 解决方案 > 直接导航到单页节点应用程序中的 URL 导致 404

问题描述

我有一个连接到 ReactJS 前端的 NodeJS 后端(不使用 create-react-app)。

我将 React 前端和 Node 后端与 webpack 捆绑在一起。webpack 配置的输出在我的应用程序文件夹的根目录中创建了一个“dist”目录。在“dist”目录中,我有捆绑的 server.js 文件和一个包含 index.html 和捆绑的 .js/.css 文件的“公共”目录。

目录结构如下所示:

dist
- server.js
- public
-- index.html
-- client.{hash}.js
-- client.{hash}.css

(上面的散列替换为 Webpack 生成的散列)。

我通过运行启动服务器NODE_ENV='production' node ./dist/server.js。这将在我的终端中记录一个开放端口(例如:60245),当我导航到 localhost:{PORT} 我的应用程序运行并加载使用 React Router v4 构建的默认路由,例如:localhost:{PORT}/pages/dashboard if the user is authenticated.

问题是,如果我直接访问 URL(例如:localhost:{PORT}/pages/dashboard),我会收到 404 响应并查看Error: ENOENT: no such file or directory, stat '/dist/public/index.html'在我的终端中看到。

经过相当多的谷歌搜索后,我在下面添加了条件:

app.use(express.static('dist/public'));
app.use('/api', routes);

if (process.env.NODE_ENV === 'production') {
  app.get('*', (req, res) => {
    res.sendFile(path.join(__dirname, 'dist/public/index.html'));
  });
} else {
  app.get('*', (req, res) => {
    res.sendFile(path.join(__dirname, '../../dist/public/index.html'));
  });
}

在开发模式下运行应用程序时,我可以直接访问 URL 而不会出现问题。这仅在生产中运行应用程序时发生。

整个应用程序的文件结构如下所示:

config
-- webpack
--- webpack.dev.config.js
--- webpack.prod.config.js
-- tests
dist
- server.js
- public
-- index.html
-- client.{hash}.js
-- client.{hash}.css
node_modules
src
- client
-- {all client stuff}
- server 
-- {all server stuff}
{config files}

在开发中,我只捆绑了 react 前端而不是服务器,我使用 Webpack 开发服务器来提供 React 前端,我正在代理使用 nodemon 服务的后端服务器,我正在构建一个 in内存“dist”文件夹位于同一位置,这就是非生产 sendFile 方法上升几个目录的原因。

关于我做错了什么的任何想法?

标签: javascriptnode.jsreactjswebpackstatic

解决方案


我弄清楚了实际问题是什么,这与 webpack 而不是 node_env 等有关。有关更多信息,请参见此处:https ://github.com/webpack/webpack/issues/1599 。

对于后代,解决方法是添加

node: {
  __dirname: false
}

到我的 wepack.prod 配置,因为 webpack 似乎在编译时更改了 __dirname 的根目录。

然后我将静态 index.html 文件的路径更新为

app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname, 'public/index.html'));
});

突然间所有路径都起作用了!

TL;DR 添加

node: {
  __dirname: false
}

如果您也在编译服务器代码,则添加到 webpack 配置。


推荐阅读