ES6中带有运行时变量的动态导入 [英] Dynamic imports in ES6 with runtime variables

查看:587
本文介绍了ES6中带有运行时变量的动态导入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近偶然发现了动态导入建议以及此

Recently stumbled upon the dynamic import proposal and also this Youtube video . Thought would be a great idea to use it for on demand imports of components in React.

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

Running into an issue where I was not able to "resolve" a path when import is passed string literals as runtime variables.

例如:

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

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

Tried with multiple options for _fetchComp, but passing parameters doesnt seem to work . A breakdown of the different options tried.

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

  1. Template Strings Does Not Work : Getting an the below error on click

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

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

代码

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

  • 可变参数 不起作用:在Webpack构建过程中出现错误,提示为55:12-23 Critical dependency: the request of a dependency is an expression

  • Variabes Doesn't work: Getting an error during webpack build as 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)
    })}
    

  • 字符串文字 Works :仅传递纯字符串文字.点击后,我可以在开发工具的网络"标签

  • String literal Works : Just passing pure string literals . On click i am able to see the chunk being downloaded in the dev tools Network tab

    代码

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

  • 根据规范

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

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

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

    So I was hoping the string literal will do the part, but that doesn't seem to be the case.

    我在流程问题跟踪器上遇到了类似的问题.但是建议的解决方案提倡再次使用字符串文字.

    I came across a similar issue on flow issue tracker. But the proposed solution advocated use of string literals again.

    我将通过 CodeSandbox 链接给大家.

    推荐答案

    该规范的import()规则与Webpack本身能够处理import()的规则不同.为了使Webpack能够处理导入,它必须至少能够大致猜出import()是要引用的内容.

    The rules for import() for the spec are not the same rules for Webpack itself to be able to process import(). For Webpack to handle an import, it needs to be able to at least guess roughly what an import() is meant to be referencing.

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

    This is why your example of import("../components/Counter") works, because Webpack can be 100% confident in what needs to be loaded.

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

    For your usecase, you could for instance do

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

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

    现在Webpack知道路径以../components/开头,它可以自动捆绑每个组件,然后加载所需的组件.不利之处在于,由于它不知道要加载哪个组件,因此必须全部加载它们,并且不能保证它们都已被实际使用.那就是动态进口的权衡.

    and now that Webpack knows that the path starts with ../components/, it can bundle up every component automatically and then load the one you need. The downside here is that because it doesn't know which component you're loading, it has to load them all and there's no guarantee they are all actually being used. That is the tradeoff of dynamic imports.

    这篇关于ES6中带有运行时变量的动态导入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆