簡體   English   中英

ES6:條件和動態導入語句

[英]ES6: Conditional & Dynamic Import Statements

有條件的

是否可以有如下條件導入語句?

if (foo === bar) {
    import Baz from './Baz';
}

我已經嘗試了上述方法,但在編譯時出現以下錯誤(來自 Babel)。

'import' and 'export' may only appear at the top level

動態的

是否可以有如下動態導入語句?

for (let foo in bar) {
    if (bar.hasOwnProperty(foo)) {
        import Baz from `./${foo}`;
    }
}

上面在編譯時從 Babel 收到相同的錯誤。

這是可能的還是我遺漏了什么?

推理

我嘗試這樣做的原因是我有很多“頁面”的導入,並且它們遵循類似的模式。 我想通過使用動態 for 循環導入這些文件來清理我的代碼庫。

如果這是不可能的,那么有沒有更好的方法來處理 ES6 中的大量導入?

我們現在有 ECMA 的動態導入提案。 這是在第 2 階段。這也可以作為babel-preset 使用

以下是根據您的情況進行條件渲染的方法。

if (foo === bar) {
    import('./Baz')
    .then((Baz) => {
       console.log(Baz.Baz);
    });
}

這基本上返回了一個承諾。 承諾的決議有望有模塊。 該提案還包含多個動態導入、默認導入、js 文件導入等內容。您可以在此處找到有關動態導入的更多信息。

您無法動態解析您的依賴項,因為imports用於靜態分析。 但是,您可能可以在這里使用一些require ,例如:

for (let foo in bar) {
    if (bar.hasOwnProperty(foo)) {
        const Baz = require(foo).Baz;
    }
}

由於這個問題被谷歌高度評價,值得指出的是,自從舊的答案發布以來,情況已經發生了變化。

MDN 在Dynamic Imports下有這個條目:

import 關鍵字可以作為函數調用來動態導入模塊。 以這種方式使用時,它會返回一個承諾。

 import('/modules/my-module.js') .then((module) => { // Do something with the module. }); // This form also supports the await keyword. let module = await import('/modules/my-module.js');

可以在Medium上找到有關該主題的有用文章。

自 2016 年以來,JavaScript 世界已經過去了很多,所以我相信是時候提供關於這個主題的最新信息了。 目前動態導入在 Node瀏覽器都是現實的(如果你不關心 IE,或者如果你關心的話,可以使用@babel/plugin-syntax-dynamic-import )。

因此,考慮一個帶有兩個命名導出和一個默認導出的示例模塊something.js

export const hi = (name) => console.log(`Hi, ${name}!`)
export const bye = (name) => console.log(`Bye, ${name}!`)
export default () => console.log('Hello World!')

我們可以使用import()語法輕松干凈地有條件地加載它:

if (somethingIsTrue) {
  import('./something.js').then((module) => {
    // Use the module the way you want, as:
    module.hi('Erick') // Named export
    module.bye('Erick') // Named export
    module.default() // Default export
  })
}

但是由於返回是一個Promiseasync / await語法糖也是可能的:

async imAsyncFunction () {
  if (somethingIsTrue) {
    const module = await import('./something.js')
    module.hi('Erick')
  }
}

現在想想對象解構賦值的可能性! 例如,我們可以輕松地將這些命名導出中的一個放在內存中以供后用:

const { bye } = await import('./something.js')
bye('Erick')

或者也許獲取這些命名導出之一並將其重命名為我們想要的任何其他內容:

const { hi: hello } = await import('./something.js')
hello('Erick')

或者甚至將默認導出的函數重命名為更有意義的名稱:

const { default: helloWorld } = await import('./something.js')
helloWorld()

最后(但並非最不重要)注意: import()可能看起來像一個函數調用,但它不是一個Function 這是一種恰好使用括號的特殊語法(類似於super()發生的情況)。 所以不可能將import分配給變量或使用Function原型的東西,比如call / apply

Require 不會解決您的問題,因為它是一個同步調用。 有幾種選擇,它們都涉及

  1. 詢問您需要的模塊
  2. 等待承諾返回模塊

在 ECMA 腳本中,支持使用 SystemJS 的延遲加載模塊。 當然,並非所有瀏覽器都支持此功能,因此同時您可以使用 JSPM 或 SystemJS shim。

https://github.com/ModuleLoader/es6-module-loader

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM