前端笔记 - 模块(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变量提升

asyncdefer

asyncdefer 有一个共同点:加载这样的脚本都不会阻塞页面的渲染。因此,用户可以立即阅读并了解页面内容。但是,它们之间也存在一些本质的区别:

顺序DOMContentLoaded
async加载优先顺序。脚本在文档中的顺序不重要 —— 先加载完成的先执行不相关。可能在文档加载完成前加载并执行完毕。如果脚本很小或者来自于缓存,同时文档足够长,就会发生这种情况。
defer文档顺序(它们在文档中的顺序)在文档加载和解析完成之后(如果需要,则会等待),即在 DOMContentLoaded 之前执行。

注意:defer 特性仅适用于外部脚本:如果 <script> 脚本没有 src,则会忽略 defer 特性。

导入导出

  • 在类或者函数前的 export 不会让它们变成 函数表达式。尽管被导出了,但它仍然是一个函数声明。

动态导入

  • 动态导入在常规脚本中工作时,它们不需要 script type="module"

  • 尽管 import() 看起来像一个函数调用,但它只是一种特殊语法,只是恰好使用了括号

CommonJS与ES6模块的差异

  • CommonJS 模块输出的是一个值的拷贝(对象),ES6 模块输出的是值的引用(地址)。

  • CommonJS 模块是运行时加载,ES6 模块是编译时输出接口(静态编译)。

  • CommonJS 模块的require()是同步加载模块,ES6 模块的import命令是异步加载,有一个独立的模块依赖的解析阶段。

以上是关于前端笔记 - 模块(module)的主要内容,如果未能解决你的问题,请参考以下文章

webpack学习 笔记

前端模块化杂记

前端模块化小总结—commonJs,AMD,CMD, ES6 的Module

前端工程化4:如何去做js模块化开发?ES Modules/CommonJS有什么区别?

python笔记73-动态导入模块import_module 和 重载reload

前端模块化