使用运行时变量在 ES6 中动态导入

Dynamic imports in ES6 with runtime variables

最近偶然发现了 dynamic import proposal and also this Youtube video。认为将其用于 React 中组件的按需导入是个好主意。

运行 当 import 作为运行时变量传递字符串文字时,我无法“解析”路径。

例如:

<div>
  <button onClick={this._fetchComp.bind(this, "../component/Counter")}>Get Async Comp</button>
</div>

尝试了 _fetchComp 的多个选项,但传递参数似乎不起作用。尝试过的不同选项的细分。

  1. 模板字符串 不起作用:点击时出现以下错误

Error: Cannot find module '../components/Counter'. at webpackAsyncContext (^.*$:53)

代码

    _fetchComp(res) {
    import(`${res}`).then(() => {
        console.log("Loaded")
    },(err)=>{
        console.log("Error",err)
    })}
  1. Variabes 不起作用:在 webpack 构建期间出现错误 55:12-23

Critical dependency: the request of a dependency is an expression

**Code**

    _fetchComp(res) {
    import(res).then(() => {
        console.log("Loaded")
    },(err)=>{
        console.log("Error",err)
    })}
  1. String literal Works:只传递纯字符串文字。单击我可以在开发工具网络选项卡中看到正在下载的块

    代码

    _fetchComp(res) {
    import("../components/Counter").then(() => {
        console.log("Loaded")
    },(err)=>{
        console.log("Error",err)
    })}
    

根据规范,

import() accepts arbitrary strings (with runtime-determined template strings shown here), not just static string literals.

所以我希望字符串文字能起到作用,但事实并非如此。

我在 flow issue tracker 上遇到了类似的问题。但是提议的解决方案提倡再次使用字符串文字。

我会给大家留下一个 CodeSandbox link。

规范的 import() 规则与 Webpack 本身能够处理 import() 的规则不同。对于要处理导入的 Webpack,它至少需要能够粗略地猜测 import() 意味着引用什么。

这就是您的 import("../components/Counter") 示例有效的原因,因为 Webpack 可以 100% 确定需要加载的内容。

对于你的用例,你可以例如做

_fetchComp(res) {
  import(`../components/${res}`).then(() => {
    console.log("Loaded")
  }, (err)=>{
    console.log("Error", err)
  })
}

this._fetchComp.bind(this, "Counter")

现在 Webpack 知道路径以 ../components/ 开头,它可以自动捆绑 每个 组件,然后加载您需要的组件。这里的缺点是因为它不知道您正在加载哪个组件,所以它必须加载所有组件并且不能保证它们都被实际使用。这就是动态导入的权衡。