前端笔记 - 模块(module)
Posted tanyioO
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了前端笔记 - 模块(module)相关的知识,希望对你有一定的参考价值。
模块只通过 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
命令是异步加载,有一个独立的模块依赖的解析阶段。
以上是关于前端笔记 - 模块(module)的主要内容,如果未能解决你的问题,请参考以下文章
前端模块化小总结—commonJs,AMD,CMD, ES6 的Module
前端工程化4:如何去做js模块化开发?ES Modules/CommonJS有什么区别?