0

我使用 create-react-app (react ^17.0.2, react-scripts 4.0.3) 来构建一个简单的应用程序,该应用程序使用基于路由的延迟加载来执行代码拆分。当我构建这个应用程序时,我看到每个延迟加载的组件都创建了单独的块,这一切都很好,因为我的所有组件都是使用默认值导出的。我的输出是:

build/static/js/2.xxxxxxxx.chunk.js
build/static/js/runtime-main.xxxxxxxx.js
build/static/js/main.xxxxxxxx.chunk.js
build/static/js/3.xxxxxxxx.chunk.js
build/static/js/5.xxxxxxxx.chunk.js
build/static/js/4.xxxxxxxx.chunk.js

然后我更新了我的 package.json 文件以包含以下条目:

{
  ...
  "main": "dist/App"
  "publishConfig": { "registry": "http://my-private-repo" }
  ...
  "scripts" : {
    ...
    "prepublishOnly": "rm -rf dist && mkdir dist && npx babel src -d dist --copy-files"
  },
  ...
  "devDependencies": {
    "@babel/cli: "^7.16.0",
    "@babel/core: "^7.16.5"
  },
  ...
  "files": [
    "dist/*"
  ]
}

使用此配置和 babel.config.js 文件,然后我将我的应用程序发布到我的私人仓库,有效地使用 Babel CLI 转换 src 目录中的所有内容,在发布该文件夹的内容之前将其复制到 dist 文件夹。babel.config.js 只包含:

module.exports = {
  presets:[
    "@babel/preset-env",
    "@babel/preset-react"
  ]
}

接下来,我创建了另一个 create-react-app,并在它的根目录中创建了一个 .yarnrc 文件,其中包含我的私人仓库的注册表项。例如:

registry "http://my-private-repo"

然后我执行了一个纱线添加命令:

yarn add 'my-other-application'

这将第一个应用程序添加为对这个应用程序的依赖项。这成功地将代码复制到 node_modules

然后,在第二个应用程序的 index.js 中,我使用以下命令导入我的第一个应用程序:

import App from 'my-other-application'

然后我使用标准渲染:

<ReactDOM.render(
  <ReactStrictMode>
    <App />
  </ReactStrictMode>
);

运行第二个应用程序,一切都呈现出来,我可以很好地浏览路线。但是我注意到第一个应用程序的延迟加载行为似乎没有发生。我通过构建应用程序确认了这一点,并且可以看到生成的块数少于我的第一个应用程序:

build/static/js/2.xxxxxxxx.chunk.js
build/static/js/runtime-main.xxxxxxxx.js
build/static/js/main.xxxxxxxx.chunk.js

对我来说,这表明对我位于 node_modules 中的模块的动态导入的代码拆分没有以我期望的方式得到尊重。我期待看到与我的第一个应用程序类似的分块模式。通过阅读有关该主题的信息,我目前可以得出的唯一结论是,我的第一个应用程序中的代码最终会出现在供应商块中,并且不会发生进一步的拆分。有人能对此有所了解吗?使用 create-react-app 提供的默认 webpack 配置可以实现我所期望的吗?

免责声明:这些技术对我来说是相当新的,所以如果我从根本上误解了某些东西,或者我正在尝试做一些完全非传统的事情,我深表歉意。

4

1 回答 1

0

在经典意义上的橡皮鸭调试中,发布后不久。我意识到我可以测试我的关于由于从 node_modules 加载模块而导致代码拆分不起作用的理论。只需将我的转译代码直接发布到我的 /src 文件夹并从那里加载组件即可。我这样做了,代码拆分仍然没有发生,这免除了 create-react-app webpack 配置的参与。

相反,它在转译阶段提出了一个问题,并且通过更集中的谷歌搜索,我在这个线程中找到了答案:https ://github.com/babel/babel/issues/10273#issuecomment-517838332

问题出在我的 babel.config.js 中,它需要更新以包含对于预设环境的模块值 false。例如:

module.exports = {
  presets:[
    ["@babel/present-env, { modules: false }],
    "@babel/preset-react"
  ]
}

在我这样做之后,一切都开始按我的预期工作。关键指标是生成的转译组件保留了所有的导入语句。而不是将它们转换为 Promise,这是在配置更改之前发生的事情,也是阻止 webpack 执行代码拆分的原因。

于 2021-12-23T15:37:32.663 回答