我有一个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方法要建立几个目录的原因。
关于我在做什么错的任何想法吗?
答案 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配置。