@loadable/server 将整个统计数据 JSON 传递给 eval('require')(modulePath)

@loadable/server pass the whole stats JSON to eval('require')(modulePath)

我正在尝试使用 @loadable/components 为 React 应用程序设置 SSR。我使用 babel 和 webpack 插件基于文档进行设置。当我尝试 运行 node server.js 它 运行 没问题但是当我打开浏览器并抛出以下错误(到节点控制台):

TypeError [ERR_INVALID_ARG_TYPE]: The "id" argument must be of type string. Received an instance of Object
    at validateString (internal/validators.js:118:11)
    at Module.require (internal/modules/cjs/loader.js:1033:3)
    at require (internal/modules/cjs/helpers.js:72:18)
    at smartRequire (/Users/max/Documents/repos/app/node_modules/@loadable/server/lib/util.js:44:25)
    at new ChunkExtractor (/Users/max/Documents/repos/app/node_modules/@loadable/server/lib/ChunkExtractor.js:181:50)
    at renderer (webpack://app/./node_modules/@MYSCOPE/elm/dist/elm.esm.js?:3619:19)
    at eval (webpack://app/./src/server.tsx?:64:90)
    at processTicksAndRejections (internal/process/task_queues.js:97:5) {
  code: 'ERR_INVALID_ARG_TYPE'
}

如您所见,回溯中有@MYSCOPE,其中包含我的一些内部包(如果重要的话)。

@loadable/server/lib/util.js 是以下函数:

当我尝试 console.log(modulePath) 在线 42 我看到整个统计 JSON 输出似乎是错误的,我应该得到一个单一的模块路径(据我了解)。

有什么帮助吗?

如果需要,我可以分享我的配置文件的某些特定部分。因为我在控制台输出中看到我自己的包似乎它的构建有问题(它在客户端使用 cjs 构建完美运行),但是将完整的统计对象作为模块路径非常混乱。

更新:演示https://www.dropbox.com/s/9r947cgg4qvqbu4/loadable-test.zip?dl=0

运行

yarn
yarn dev:server
# go to localhost:3000 and see the error in console

重建:

yarn
yarn dev:build-client
yarn dev:build-server
yarn dev:server # go to localhost:3000

传递给 ChunkExtractorstatsFile 选项需要 loadable-stats.json 文件的路径,而不是它的实际 JSON 内容。通过执行 require('../loadable-stats.json'),webpack 实际上在构建期间解析了 JSON 并将其分配给 loadableJson 变量。

您可以按如下方式更改 loadableJson

import path from 'path';

const loadableJson = path.resolve(__dirname, '../bundle_client/loadable-stats.json');

这将解决您在问题中遇到的问题。但是,如果你只这样做,你会发现你有另一个问题。默认情况下可加载假定您的入口块名称是 main。在您的演示中情况并非如此,因为您已将入口块名称设置为 app

entry: {
    app: ['@babel/polyfill', './src/index.tsx']
},

要解决这个问题,只需将数组传递给 ChunkExtractor 构造函数,就可以告诉 loadable 您的 entrypoints 名称:

    const extractor = new ChunkExtractor({
        statsFile: loadableJson,
        entrypoints: ["app"], // name of your entry chunk
    });

就是这样,现在一切都应该正常工作了!

如果有帮助,我在 GitHub 上设置了演示,这样您就可以轻松地看到我所做的更改 here