JS 动态导入 ECMAScript 模块的方法是什么
ES 模块系统有 2 个角色:
- 导入-import { func } from ‘./myModule.js’
- 导出-export const func = () => {}。
导入模块使用import
语法导入依赖项:
// The importing module import { concat } from './concatModule.js'; concat('a', 'b'); // => 'ab'
导入的模块本身是用export
语法导出的模块:
// The imported module exports components export const concat = (paramA, paramB) => paramA + paramB;
使用 ES 模块的方式是静态的:这意味着模块之间的依赖关系在编译时是已知的。
虽然静态导入在大多数情况下都有效,但有时也会遇到动态加载模块的情况。
如果import
用作函数,则可以动态导入模块— import(pathToModule)
。动态导入是 ES2020 开始的 JavaScript 语言功能。
1. 模块的动态导入
当import
关键字用作函数而不是静态导入语法时:
const module = await import(path);
它返回一个 Promise
并启动一个异步任务来加载模块。如果模块成功加载,则 Promise
解析为模块内容,否则, Promise
拒绝。
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 命名导出的导入
让我们考虑以下名为 namedConcat.js 的模块:
// namedConcat.js export const concat = (paramA, paramB) => paramA + paramB;
namedConcat
执行concat
函数的命名导出。
如果您想动态导入 namedConcat.js 并访问命名的 export concat
,那么只需通过命名的导出名称解构解析的模块对象:
async function loadMyModule() { const { concat } = await import('./namedConcat.js'); concat('b', 'c'); // => 'bc' } loadMyModule();
2.2 导入默认导出
如果导入的模块作为默认导出,您可以通过default
从模块对象读取属性来访问默认导入。
假设 defaultConcat.js 导出功能作为default
导出:
// defaultConcat.js export default (paramA, paramB) => paramA + paramB;
defaultConcat.js 动态导入时,特别是访问default
导出时,您只需要读取default
属性即可。
但有一个细微差别。default
是 JavaScript 中的关键字,因此它不能用作变量名,因此您只需使用带别名的解构:
async function loadMyModule() { const { default: defaultImport } = await import('./defaultConcat.js'); defaultImport('b', 'c'); // => 'bc' } loadMyModule();
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);
对于只有几十行代码的小模块(如 namedConcat.js 或 defaultConcat.js 来自前面的示例),动态导入不值得麻烦。
4. 结语
Node.js(版本 13.2 及更高版本)和大多数现代浏览器都支持动态导入。
码云笔记 » JS 动态导入 ECMAScript 模块的方法是什么