深入了解 Dynamic imports
深入了解動態(tài)導(dǎo)入
我們在前面的章節(jié)中提到的導(dǎo)出和導(dǎo)入語句被稱為“靜態(tài)”。語法非常簡單和嚴(yán)格。
首先,我們不能動態(tài)地生成import的任何參數(shù)。
模塊路徑必須是原語字符串,不能是函數(shù)調(diào)用。這不會工作:
import ... from getModuleName(); // Error, only from "string" is allowed
其次,不能有條件地或在運(yùn)行時導(dǎo)入:
if(...) {
import ...; // Error, not allowed!
}
{
import ...; // Error, we can't put import in any block
}
這是因?yàn)?code style="font-size: 14px;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 93, 108);">import/export的目的是為代碼結(jié)構(gòu)提供一個主干。這是一件好事,因?yàn)榇a結(jié)構(gòu)可以被分析,模塊可以被收集并通過特殊工具綁定到一個文件中,未使用的導(dǎo)出可以被刪除(“樹狀震蕩”)。這是可能的,因?yàn)檫M(jìn)口/出口的結(jié)構(gòu)簡單和固定。
但我們?nèi)绾蝿討B(tài)地、按需地導(dǎo)入模塊呢?
import() 表達(dá)式
import(module)表達(dá)式加載模塊并返回一個promise,該promise解析為一個包含其所有導(dǎo)出的module對象。可以從代碼中的任何地方調(diào)用它。
我們可以在代碼的任何地方動態(tài)地使用它,例如:
let modulePath = prompt("Which module to load?");
import(modulePath)
.then(obj => <module object>)
.catch(err => <loading error, e.g. if no such module>)
或者,如果在異步函數(shù)中,也可以使用let module = await import(modulePath)。
例如,如果我們有以下模塊say.js:
// ?? say.js
export function hi() {
alert(`Hello`);
}
export function bye() {
alert(`Bye`);
}
那么動態(tài)導(dǎo)入可以像這樣:
let {hi, bye} = await import('./say.js');
hi();
bye();
或者,如果say.js有默認(rèn)的導(dǎo)出:
// ?? say.js
export default function() {
alert("Module loaded (export default)!");
}
然后,為了訪問它,我們可以使用模塊對象的default屬性:
let obj = await import('./say.js');
let say = obj.default;
// or, in one line: let {default: say} = await import('./say.js');
say();
下面是完整的例子:
say.js
export function hi() {
alert(`Hello`);
}
export function bye() {
alert(`Bye`);
}
export default function() {
alert("Module loaded (export default)!");
}
index.html
<!doctype html>
<script>
async function load() {
let say = await import('./say.js');
say.hi(); // Hello!
say.bye(); // Bye!
say.default(); // Module loaded (export default)!
}
</script>
<button onclick="load()">Click me</button>
注意
動態(tài)導(dǎo)入可以在常規(guī)腳本中工作,它們不需要script type="module"。
盡管import()看起來像一個函數(shù)調(diào)用,但它是一種特殊的語法,只是碰巧使用了圓括號(類似于`super()``)。
因此,我們不能將import復(fù)制到一個變量,也不能使用call/apply。它不是一個函數(shù)。
