模块只通过 HTTP(s) 工作,在本地文件则不行
如果你尝试通过 file://
协定在本地关上一个网页,你会发现 import/export
指令不起作用。你能够应用本地 Web 服务器,例如 static-server,或者应用编辑器的“实时服务器”性能,例如 VSCode 的 Live Server Extension 来测试模块。
模块代码仅在第一次导入时被解析
如果同一个模块被导入到多个地位,那么它的代码仅会在第一次导入时执行,而后将导出(export)的内容给所有的导入(importer)。
模块只被执行一次。生成导出,而后被分享给所有对其的导入,所以如果某个导入模块批改了模块内容,其余导入模块也能看到这个批改。
模块的其余常识
-
import.meta
对象蕴含对于以后模块的信息 -
在一个模块中,顶级
this
是 undefined。非模块脚本的顶级this
是全局对象。
模块脚本是提早的
模块脚本 总是 被提早的,与 defer
个性对外部脚本和内联脚本(inline script)的影响雷同。
-
下载内部模块脚本
<script type="module" src="...">
不会阻塞 HTML 的解决,它们会与其余资源并行加载。 -
模块脚本会等到 HTML 文档齐全准备就绪(即便它们很小并且比 HTML 加载速度更快),而后才会运行。
-
放弃脚本的绝对程序:在文档中排在后面的脚本先执行。
副作用是,模块脚本总是会“看到”已齐全加载的 HTML 页面,包含在它们下方的 HTML 元素
=> HTML 变量晋升
async
和defer
async
和 defer
有一个共同点:加载这样的脚本都不会阻塞页面的渲染。因而,用户能够立刻浏览并理解页面内容。然而,它们之间也存在一些实质的区别:
程序 | DOMContentLoaded |
|
---|---|---|
async |
加载优先程序。脚本在文档中的程序不重要 —— 先加载实现的先执行 | 不相干。可能在文档加载实现前加载并执行结束。如果脚本很小或者来自于缓存,同时文档足够长,就会产生这种状况。 |
defer |
文档程序(它们在文档中的程序) | 在文档加载和解析实现之后(如果须要,则会期待),即在 DOMContentLoaded 之前执行。 |
留神:defer
个性仅实用于内部脚本:如果 <script>
脚本没有 src
,则会疏忽 defer
个性。
导入导出
-
在类或者函数前的
export
不会让它们变成 函数表达式。只管被导出了,但它依然是一个函数申明。
动静导入
-
动静导入在惯例脚本中工作时,它们不须要
script type="module"
-
只管
import()
看起来像一个函数调用,但它只是一种非凡语法,只是恰好应用了括号
CommonJS 与 ES6 模块的差别
-
CommonJS 模块输入的是一个值的拷贝(对象),ES6 模块输入的是值的援用(地址)。
-
CommonJS 模块是运行时加载,ES6 模块是编译时输入接口(动态编译)。
- CommonJS 模块的
require()
是同步加载模块,ES6 模块的import
命令是异步加载,有一个独立的模块依赖的解析阶段。