Javascript 動態(tài)導(dǎo)入

2023-02-17 10:53 更新

我們在前面章節(jié)中介紹的導(dǎo)出和導(dǎo)入語句稱為“靜態(tài)”導(dǎo)入。語法非常簡單且嚴(yán)格。

首先,我們不能動態(tài)生成 import 的任何參數(shù)。

模塊路徑必須是原始類型字符串,不能是函數(shù)調(diào)用,下面這樣的 import 行不通:

import ... from getModuleName(); // Error, only from "string" is allowed

其次,我們無法根據(jù)條件或者在運行時導(dǎo)入:

if(...) {
  import ...; // Error, not allowed!
}

{
  import ...; // Error, we can't put import in any block
}

這是因為 import/export 旨在提供代碼結(jié)構(gòu)的主干。這是非常好的事兒,因為這樣便于分析代碼結(jié)構(gòu),可以收集模塊,可以使用特殊工具將收集的模塊打包到一個文件中,可以刪除未使用的導(dǎo)出(“tree-shaken”)。這些只有在 import/export 結(jié)構(gòu)簡單且固定的情況下才能夠?qū)崿F(xiàn)。

但是,我們?nèi)绾尾拍軇討B(tài)地按需導(dǎo)入模塊呢?

import() 表達式

?import(module)? 表達式加載模塊并返回一個 promise,該 promise resolve 為一個包含其所有導(dǎo)出的模塊對象。我們可以在代碼中的任意位置調(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ù)。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號