ES 模块动态导入
目录
1.动态导入
2. 导入组件
2.1 动态导入 named
2.2 动态导入 default
2.3 动态导入混合内容
3. 何时使用动态导入
4. 结论
ES 模块是一种在 JavaScript 中组织内聚代码块的方法。这是一个简单的 ES 模块:
// An ES module
import { concat } from './concatModule.js';concat('a', 'b'); // => 'ab'
import { concat } from './concatModule.js'
被视为静态导入。
静态导入在大多数情况下都有效。但有时为了节省客户端带宽,您可能选择动态加载模块。
import
如果使用函数,则可以动态导入 ES 模块——import(pathToModule)
这是从 ES2020 开始提供的功能。
让我们看看 ES 模块的动态导入如何工作,以及它何时有用。
1.动态导入
当import
关键字用作函数时
const module = await import(path)
import(path)
返回一个承诺,并启动一个异步任务来加载位于 的模块path
。如果模块加载成功,则承诺解析模块内容;否则,承诺拒绝。
path
可以是任何计算结果为表示路径的字符串的表达式。有效的路径表达式包括
// Classic string literals
const module1 = await import('./myModule.js');// A variable
const path = './myOtherModule.js';
const module2 = await import(path);// Function call
const getPath = (version) => `./myModule/versions/${version}.js`;
const moduleVersion1 = await import(getPath('v1.0'));
const moduleVersion2 = await import(getPath('v2.0'));
import(path)
返回一个 Promise,语法非常好用async/await
。例如,让我们在异步函数中加载一个模块:
async function loadMyModule() {const myModule = await import('./myModule.js');// ... use myModule
}loadMyModule();
现在,知道了如何加载模块,让我们从导入的模块中提取组件(默认或命名)
2. 导入组件
2.1 动态导入 named
让我们考虑以下模块,名为namedConcat.js
:
// namedConcat.js
export const concat = (paramA, paramB) => paramA + paramB;
namedConcat
执行函数的命名导出concat
。
要动态导入namedConcat.js
并访问命名导出concat
,请通过命名导出解构已解析的模块对象:
async function loadMyModule() {const { concat } = await import('./namedConcat.js');concat('b', 'c'); // => 'bc'
}loadMyModule();
2.2 动态导入 default
要动态导入默认值default
,只需从模块对象中读取属性。
假设将该defaultConcat.js
函数作为default
导出来:
// defaultConcat.js
export default (paramA, paramB) => paramA + paramB
动态导入时defaultConcat.js
,具体访问default
导出时,只需读取default
属性。
但这里有一个细微的差别。default
是 JavaScript 中的关键字,所以它不能用作变量名。你可以使用带别名的解构:
2.3 动态导入混合内容
如果导入的模块导出default
并有多个命名导出,那么您可以使用单个解构来访问所有这些组件:
async function loadMyModule() {const { default: defaultImport,namedExport1,namedExport2} = await import('./mixedExportModule.js');// ...
}loadMyModule();
3. 何时使用动态导入
我建议在有条件导入大模块时使用动态导入:
- 您可能会不时使用该模块,具体取决于运行时条件
- 您可能希望加载大模块的不同版本,这也取决于运行时条件。
例如:
async function execBigModule(condition) {if (condition) {const { funcA } = await import('./bigModuleA.js');funcA();} else {const { funcB } = await import('./bigModuleB.js');funcB();}
}execBigModule(true);
4. 结论
动态加载模块调用import(path)
作为函数,并使用指示模块说明符(又名路径)的参数。
const module = await import(path)
返回一个承诺,该承诺解析为包含导入模块的组件的对象。
在该对象中,default
属性包含默认导出,命名导出包含在相应的属性中:
const { default: defaultComponent, namedExport1,namedExport2
} = await import(path);
Node.js(版本 13.2 及以上)和大多数现代浏览器都支持动态导入。