ES6中的动态导入与运行时变量

sem*_*boi 5 dynamic-import ecmascript-6

最近偶然发现了动态导入提案Youtube视频.想到将它用于React中的组件按需导入是一个好主意.

遇到一个问题,当我import将字符串文字作为运行时变量传递时,我无法"解析"路径.

例如:

<div>
<button onClick={this._fetchComp.bind(this, "../component/Counter")}>
Get Asyn Comp
</button>
</div>
Run Code Online (Sandbox Code Playgroud)

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

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

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

    _fetchComp(res) {
    import(`${res}`).then(() => {
        console.log("Loaded")
    },(err)=>{
        console.log("Error",err)
    })}
    
    Run Code Online (Sandbox Code Playgroud)
  2. Variabes 不起作用:在webpack构建过程中出现错误55:12-23 Critical dependency: the request of a dependency is an expression

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

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

根据规范,

import()接受任意字符串(此处显示运行时确定的模板字符串),而不仅仅是静态字符串文字.

所以我希望字符串文字能做到这一点,但事实并非如此.

我在流量问题跟踪器上遇到了类似的问题.但是提出的解决方案主张再次使用字符串文字.

我将为您提供CodeSandbox 链接.

log*_*yth 13

对于规则import()的规范是不一样的规则的WebPack自己能够处理import().对于Webpack来处理导入,它需要能够至少大致猜测一个import()引用的内容.

这就是你工作的例子import("../components/Counter"),因为Webpack可以100%确信需要加载什么.

对于您的用例,您可以这样做

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

this._fetchComp.bind(this, "Counter")
Run Code Online (Sandbox Code Playgroud)

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

  • @Ciantic然后考虑执行 ```import(`../components/${res}.js`)``` 这样 Webpack 就知道你只会加载 JS 文件。 (4认同)