0

我正在尝试为 SSR 未弹出的 CRA 应用程序设置可加载组件。我正在使用 Craco 覆盖 Webpack 配置,它似乎正在工作,因为loadable-stats.json正在生成客户端。当我运行构建命令时,这些块是根据 id 命名的,因为我相信react-scripts它是硬连线的,可以在生产模式下运行。所以对于我的服务器配置,我决定也用 id 来命名这些块。但不幸的是,chunkNames 似乎是服务器统计文件中模块的路径,它是由生成的@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 配置使用server.js包含 Express 代码的文件作为入口点,而客户端的 Webpack 配置使用应用程序的索引文件作为入口。我得到一个空的 {} 作为服务器requireEntrypoint结果。我不太确定该调用会发生什么,实际文档不是很清楚。

有些人也在webExtractor服务器代码中使用 only 并且它似乎对他们有用,但我不断收到错误,因为它仍在尝试映射服务器端块,它在webExtractor.

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

4

1 回答 1

1

所以发生这种情况是因为我忘记将 包含在@loadable/babel-plugin我的 Craco 配置中,用于客户端 Webpack 构建。我这样做后工作正常。我的最终结果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(),
 ]
} };

现在完美运行。

于 2019-12-09T09:24:10.063 回答