我正在尝试为SSR未弹出的CRA应用设置可加载组件。我正在使用Craco覆盖Webpack配置,并且似乎正在运行,因为正在生成客户端loadable-stats.json
。当我运行build命令时,这些块是根据id命名的,因为我相信react-scripts
硬连线可以在生产模式下运行。因此,对于我的服务器配置,我决定也用id命名这些块。但是不幸的是,chunkNames似乎是server stats file中模块的路径,该路径由@loadable/webpack-plugin
生成,而不是id。实际的块用'id'命名,我可以在文件夹中看到它们。
这是我在server.js
中试图读取这些块的代码。
const nodeStatsFile = path.resolve(__dirname, 'node-stats.json');
const nodeExtractor = new ChunkExtractor({ statsFile: nodeStatsFile, entrypoints: ["server"] });
const nodeEntryPointResult = nodeExtractor.requireEntrypoint("server"); // ==> {}
const webStatsFile = path.resolve(__dirname, '../web-stats.json');
const extractor = new ChunkExtractor({ statsFile: webStatsFile });
const client = generateApolloClient();
const app = (<ApolloProvider client={client}>
<HelmetProvider context={helmetContext}>
<Router location={req.url} context={staticContext}>
<CookiesProvider cookies={req.universalCookies}>
<App />
</CookiesProvider>
</Router>
</HelmetProvider>
</ApolloProvider>);
getDataFromTree(app).then(() => {
const jsx = nodeExtractor.collectChunks(app);
const content = ReactDOMServer.renderToString(jsx);
const state = client.extract();
const { helmet } = helmetContext;
const html = ReactDOMServer.renderToString(
<Html content={content} helmet={helmet} assets={assets} extractor={extractor} />,
);
res.status(staticContext.status || 200);
res.send(`<!doctype html>${html}`);
res.end();
})
由于此,当我运行nodeExtractor
(正在从服务器状态文件读取)以收集碎片,然后将webExtractor
(正在使用客户端状态文件)运行至getScriptElements
时,会得到一个空的可加载数组大块。如果仅使用webExtractor
,则会抛出chunkNameFromServerStatsFile not found
错误。
服务器的我的Webpack配置将包含Express代码的server.js
文件用作入口点,而客户端的Webpack配置将应用程序的索引文件作为入口。我得到一个空{}作为服务器requireEntrypoint
的结果。我不太确定该调用会发生什么情况,实际文档不是很清楚。
有些人也仅在服务器代码中使用了webExtractor
,并且似乎对他们有用,但是由于它仍在尝试映射服务器端块,因此我不断收到错误消息,它在服务器代码中找不到webExtractor
。
任何帮助将不胜感激。谢谢!
之所以这样,是因为我忘记了在客户端Webpack构建中将@loadable/babel-plugin
包含在我的Craco配置中。我这样做之后效果很好。我最后的craco.config.js
是:
const LoadablePlugin = require('@loadable/webpack-plugin');
module.exports = {
babel: {
plugins: ["@loadable/babel-plugin"]
},
webpack: {
mode: "development",
configure: {
output: {
filename: '[name].js',
chunkFilename: 'static/js/[name].js',
},
},
plugins: [
new LoadablePlugin(),
]
} };
现在可以完美运行。