在404

时间:2018-08-04 22:53:07

标签: javascript node.js reactjs webpack static

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

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

目录结构如下:

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'

经过大量的Google搜索后,我在下面添加了条件:

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方法要建立几个目录的原因。

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

2 个答案:

答案 0 :(得分:0)

仅查看path.join的结果,并亲自查看这是否是正确的路径。将其放在您服务器的代码中:console.log(path.join(__dirname, 'dist/public/index.html'))

答案 1 :(得分:0)

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