Express SSR应用中React.Lazy静态资源路径错误问题求助
问题描述
我有一个Express SSR应用,希望将静态文件托管在/static/*目录下,但React.Lazy组件的chunk请求路径出现错误,请求地址变为http://localhost:3000/staticreact.LazyChunk.js(缺少斜杠)。注释掉server.use('/static', express.static(...))后,React Lazy的chunk路径恢复正常,但其他静态文件会返回404错误。尝试添加额外斜杠无效,相关代码及错误截图如下:
服务端代码
import express from 'express'; import path from 'path'; import handleRequest from '@server/infrastructure/handleRequest/handleRequest'; import {routes} from '@general-infrastructure/routes/routes'; import { handleErrors } from '@server/middlewares/errorHandler/errorHandler'; const server = express(); // 注释这行后React Lazy chunk路径正常,但其他静态文件404 server.use('/static', express.static(path.join(__dirname, '/static'))); // TODO - // 5. redux for theme server.get('*', handleErrors(async function(req, res, next) { handleRequest(req.url, res, routes); })); server.listen(3000, () => { console.log('Server running on http://localhost:3000'); });
Webpack配置
module.exports = { name: 'client', entry: { client: path.resolve(__dirname, 'src/client/index.tsx'), }, mode: mode, output: { path: path.resolve(__dirname + '/dist/static'), filename: '[name].[contenthash].js', publicPath: path.resolve(__dirname, '/static'), chunkFilename: 'react.[name].chunk.js', clean: true, }, resolve: { extensions: ['.ts', '.tsx', '.js', '.jsx', '.css', '.scss'], alias: webpackAliases, }, };
路由代码
const Lazy = React.lazy(() => import(/* webpackChunkName: "LazyChunk" */ '@client/modules/pages/Lazy')); const Routes: React.FC = () => { const AppRoutes = useRoutes( [ {path: '/', element: <Feed />}, {path: '/lazy', element: <Lazy />}, {path: '/overview', element: <Overview.component />}, ], ); return ( <Suspense fallback="Loading..."> {AppRoutes} </Suspense> ); };
错误截图

解决方法
问题核心在于Webpack的publicPath配置错误,同时Express静态文件路径可能指向不符:
修正Webpack的publicPath
当前使用path.resolve(__dirname, '/static')生成的是本地磁盘绝对路径,而非浏览器端的URL前缀。将publicPath改为字符串'/static/'(必须保留末尾斜杠):output: { // ...其他配置 publicPath: '/static/', // ...其他配置 }末尾斜杠会确保Webpack生成chunk路径时自动拼接斜杠,避免出现
staticreact.LazyChunk.js这类错误路径。调整Express静态文件托管路径
Webpack输出目录是dist/static,服务端需指向打包后的目录,修正为:server.use('/static', express.static(path.join(__dirname, 'dist/static')));原代码指向的源码目录
static并非打包产物目录,这也是静态文件404的潜在原因。重新打包并重启服务
修改配置后重新执行打包命令,再重启Express服务,此时React Lazy的chunk请求路径会变为http://localhost:3000/static/react.LazyChunk.js,同时其他静态文件也能正常通过/static/*访问。
内容的提问来源于stack exchange,提问作者user469485

