web-dev-qa-db-ja.com

ランタイム変数を使用したES6での動的インポート

最近、 動的インポート提案 およびこれ Youtubeビデオ に遭遇しました。 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のビルド中に55:12-23Critical 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)
    })}
    

仕様によると、

import()は、静的な文字列リテラルだけでなく、任意の文字列(ここではランタイムで決定されたテンプレート文字列を含む)を受け入れます。

だから私は文字列リテラルがその役割を果たすことを望んでいましたが、そうではないようです。

フロー課題トラッカー で同様の問題に遭遇しました。しかし、提案されたソリューションは、文字列リテラルの使用を再び提唱しました。

CodeSandbox リンクを残しておきます。

8
semuzaboi

仕様のimport()のルールは、Webpack自体がimport()を処理できるようにするためのルールと同じではありません。 Webpackがインポートを処理するには、少なくともimport()が何を参照しているのかを大まかに推測できる必要があります。

これが、import("../components/Counter")の例が機能する理由です。これは、Webpackが何をロードする必要があるかを100%確信できるためです。

yourユースケースの場合、たとえば、

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

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

そして、パスが../components/で始まることをWebpackが認識したので、everyコンポーネントを自動的にバンドルして、必要なコンポーネントをロードできます。ここでの欠点は、ロードしているコンポーネントがわからないため、すべてをロードする必要があり、すべてが実際に使用されているという保証がないことです。これが動的インポートのトレードオフです。

17
loganfsmyth