【问题标题】:Navigating directly to URL in Single Page Node App Results in 404直接导航到单页节点应用程序中的 URL 导致 404
【发布时间】:2018-08-04 22:53:07
【问题描述】:

我有一个连接到 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

(上面的hash替换成Webpack生成的hash)。

我通过运行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 服务的后端服务器,我正在构建到同一位置的内存“dist”文件夹,这就是为什么非生产 sendFile 方法会上升几个目录。

关于我做错了什么有什么想法吗?

【问题讨论】:

  • 没有给你答案,但是非常有据可查的问题/问题的荣誉
  • 我很感激!我迷路了,希望尽可能多的信息会有所帮助,但我最终能够找到答案!谢谢!

标签: javascript node.js reactjs webpack static


【解决方案1】:

我弄清楚了实际问题是什么,这与 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 配置。

【讨论】:

    【解决方案2】:

    只需看看 path.join 的结果,看看它是否是正确的路径。把它放在你的服务器代码中:console.log(path.join(__dirname, 'dist/public/index.html'))

    【讨论】:

    • 感谢您的回复,您的评论帮助我找到了答案!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-16
    • 2013-08-07
    • 1970-01-01
    • 2018-02-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多