可加载组件SSR-服务器状态文件中的块名称与客户端状态文件不同

问题描述 投票:0回答:1

我正在尝试为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

任何帮助将不胜感激。谢谢!

reactjs webpack ssr code-splitting loadable-component
1个回答
0
投票

之所以这样,是因为我忘记了在客户端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(),
 ]
} };

现在可以完美运行。

© www.soinside.com 2019 - 2024. All rights reserved.