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

时间:2017-12-23 17:47:24

标签: ecmascript-6 dynamic-import

最近偶然发现了dynamic import proposal以及此Youtube video。想到将它用于React中的组件按需导入是个好主意。

import将字符串文字作为运行时变量传递时,遇到无法“解析”路径的问题。

例如:

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

尝试了_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)
    })}
    
  2. Variabes 不起作用:在webpack build期间出现错误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)
    })}
    
  3. 字符串文字 作品:只传递纯字符串文字。点击后,我可以在开发工具网络选项卡中看到正在下载的块

    代码

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

      

    import()接受任意字符串(使用运行时确定的模板   这里显示的字符串),而不仅仅是静态字符串文字。

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

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

    我会给你留下CodeSandbox个链接。

1 个答案:

答案 0 :(得分:11)

规范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/开头,它可以自动捆绑每个组件,然后加载你需要的组件。这里的缺点是,因为它不知道你正在加载哪个组件,所以它必须加载所有组件,并且不能保证它们都被实际使用。这是动态进口的权衡。