Dynamic import() 有哪些特点
Dynamic import() 已被 Chrome 63 和 Safari Technology Preview 24 支持。
Dynamic import()
采用 类函数 的方法来塑造 import
,相比 static import
解锁了新功能。这篇文章对比了两者并概览新功能。
Static import(概括)
九月份,Chrome 61 发布并支持在 modules 中使用 ES2015 import
声明。
仔细看下面这个模块,位于 ./utils.mjs
:
// Default export
export default () => {
console.log('Hi from the default export!');
};
// Named export `doStuff`
export const doStuff = () => {
console.log('Doing stuff…');
};
下面是使用 静态 import
引入 ./utils.mjs
模块:
注意: 上面这个例子使用 .mjs 来标识这是一个模块文件而不是普通脚本。在网页端,文件扩展名并不是问题,只要服务端设置了正确的 MIME 类型(比如给 javascript 文件设置 Content-Type:text/javascript)在 HTTP header。.mjs 在其他一些平台上特别有用,如 Node.js 这类没有 MIME 类型或其他 Hooks 如 type=”module” 来确定模块或普通脚本。我们在这里使用相同的扩展名来保持跨平台的一致性,并清楚地区分模块和普通脚本。
这个导入模块的语法形式是 静态 声明:它只接受字符串作为模块标识符,并通过运行前的 “linking” 过程将模块绑定到本地作用域。静态 import
语法只能用于文件顶部。静态import
支持一些重要的用例,如:static analysis
, bundling tools
, 和 tree-shaking
。
在一些案例中,下面这些特性会非常有用:
- 请求时导入模块(或有条件地)
- 运行时计算模块标识符
- 在普通脚本中导入模块(而不是在模块中导入)
但是这些用 静态 import
都无法做到。
Dynamic import() 🔥
Dynamic import()
采用 类函数 的方法来塑造满足这些用例的 import
。import(moduleSpecifier)
为请求模块的模块名称空间返回一个 promise。它是在获取,实例化和评估模块的所有依赖关系之后创建的,模块本身也是。
下面是如何使用 动态 import,并使用 ./utils.mjs
模块:
注意: 尽管 import() 看起来像一个函数调用,但它只是恰好被规定为使用括号的一种 语法 (类似于 super())。这意味着 import 不会继承 Function.prototype ,所以不能使用 call 和 apply。像 const importAlias = import 这样的代码也不能运行 —— import 甚至不是一个 object 对象!但是这在实践中并不重要。
下面是一个例子,展示了如何在一个小型单页应用的导航上使用 动态 import()
启用懒加载模块:
<meta charset="utf-8">
<title>My librarytitle>
<nav>
<a href="books.html" data-entry-module="books">Booksa>
<a href="movies.html" data-entry-module="movies">Moviesa>
<a href="video-games.html" data-entry-module="video-games">Video Gamesa>
nav>
<main>This is a placeholder for the content that will be loaded on-demand.main>
<script>
const main = document.querySelector('main');
const links = document.querySelectorAll('nav > a');
for (const link of links) {
link.addEventListener('click', async (event) => {
event.preventDefault();
try {
const module = await import(`/${link.dataset.entryModule}.mjs`);
// The module exports a function named `loadPageInto`.
module.loadPageInto(main);
} catch (error) {
main.textContent = error.message;
}
});
}
script>
当正确使用 动态 import()
开启懒加载功能时将会非常强大。为了演示目的,Addy 修改了一个 Hacker News PWA 示例,在首次加载时静态地导入所有依赖,包括评论。升级版 使用 动态 import()
延迟加载评论,避免加载,解析和编译成本,直到用户确实需要它们。
建议
静态 import
和动态 import()
都很有用。它们都有各自的特点和使用场景。使用静态 import
来初始绘制依赖关系,尤其是首屏内容。另一种情况,考虑到按需加载则使用动态 import()
。
译者注: static import 是没有括号的,dynamic import() 是带括号的。不注意的可能会混淆。用法的区别:
- static import:
import $ from 'jquery'
有声明提升,一般只放在头部位置- dynamic import():
const $ = import('jquery')
可以放在任何位置