<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-Hans-CN">
	<id>http://wiki.eijux.com/index.php?action=history&amp;feed=atom&amp;title=JS%E6%A8%A1%E5%9D%97%EF%BC%9AESM_%E4%B8%8E_CJM</id>
	<title>JS模块：ESM 与 CJM - 版本历史</title>
	<link rel="self" type="application/atom+xml" href="http://wiki.eijux.com/index.php?action=history&amp;feed=atom&amp;title=JS%E6%A8%A1%E5%9D%97%EF%BC%9AESM_%E4%B8%8E_CJM"/>
	<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=JS%E6%A8%A1%E5%9D%97%EF%BC%9AESM_%E4%B8%8E_CJM&amp;action=history"/>
	<updated>2026-05-05T14:10:03Z</updated>
	<subtitle>本wiki上该页面的版本历史</subtitle>
	<generator>MediaWiki 1.38.2</generator>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=JS%E6%A8%A1%E5%9D%97%EF%BC%9AESM_%E4%B8%8E_CJM&amp;diff=6593&amp;oldid=prev</id>
		<title>Eijux：​/* ES Module：循环引用的处理 */</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=JS%E6%A8%A1%E5%9D%97%EF%BC%9AESM_%E4%B8%8E_CJM&amp;diff=6593&amp;oldid=prev"/>
		<updated>2023-04-15T10:51:43Z</updated>

		<summary type="html">&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;ES Module：循环引用的处理&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;zh-Hans-CN&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;←上一版本&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;2023年4月15日 (六) 18:51的版本&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l302&quot;&gt;第302行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第302行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;  &amp;lt;big&amp;gt;📜&amp;lt;/big&amp;gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;：&lt;/del&gt;'''“变量提升”只能使不报错，但不能得到有效内容'''&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;  &amp;lt;big&amp;gt;📜&amp;lt;/big&amp;gt; '''“变量提升”只能使不报错，但不能得到有效内容'''&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   &lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;  —— &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;1、&lt;/del&gt;&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;只有 &amp;lt;code&amp;gt;var&amp;lt;/code&amp;gt; 变量会进行提升&amp;lt;/span&amp;gt;；&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;  —— &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;只会提升“声明”，不会提升“初始化”&lt;/ins&gt;&amp;lt;/span&amp;gt; —— 所以，上面变量为 &amp;lt;code&amp;gt;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''undefined'''&amp;lt;/span&amp;gt;&amp;lt;/code&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt; &lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt; —— 2、&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;只会提升“声明”，不会提升“非初始化”&lt;/del&gt;&amp;lt;/span&amp;gt; —— 所以，上面变量为 &amp;lt;code&amp;gt;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''undefined'''&amp;lt;/span&amp;gt;&amp;lt;/code&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== 在 node.js 中&amp;lt;ref&amp;gt;参考：[https://nodejs.cn/api-v18/packages.html Node.js文档：《module/package 包模块》]&amp;lt;/ref&amp;gt; ==&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== 在 node.js 中&amp;lt;ref&amp;gt;参考：[https://nodejs.cn/api-v18/packages.html Node.js文档：《module/package 包模块》]&amp;lt;/ref&amp;gt; ==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=JS%E6%A8%A1%E5%9D%97%EF%BC%9AESM_%E4%B8%8E_CJM&amp;diff=6588&amp;oldid=prev</id>
		<title>Eijux：​创建页面，内容为“category:JavaScript  == 关于&lt;ref&gt;参考： # [https://wangdoc.com/es6/module-loader 网道：ES6 教程：《Module 的加载实现》] # [https://zhuanlan.zhihu.com/p/113009496 《前端科普系列-CommonJS：不是前端却革命了前端》] &lt;/ref&gt; == {| class=&quot;wikitable&quot; |+ ESM 与 CJM |- !  !! ESM !! CJM |- | 应用场景 |  * 用于：浏览器、node.js  |  * 用于：node.js  |- | 加载方式 |  * 静态加载：'''编译时'''输出'''模块接…”</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=JS%E6%A8%A1%E5%9D%97%EF%BC%9AESM_%E4%B8%8E_CJM&amp;diff=6588&amp;oldid=prev"/>
		<updated>2023-04-03T17:15:32Z</updated>

		<summary type="html">&lt;p&gt;创建页面，内容为“&lt;a href=&quot;/%E5%88%86%E7%B1%BB:JavaScript&quot; title=&quot;分类:JavaScript&quot;&gt;category:JavaScript&lt;/a&gt;  == 关于&amp;lt;ref&amp;gt;参考： # [https://wangdoc.com/es6/module-loader 网道：ES6 教程：《Module 的加载实现》] # [https://zhuanlan.zhihu.com/p/113009496 《前端科普系列-CommonJS：不是前端却革命了前端》] &amp;lt;/ref&amp;gt; == {| class=&amp;quot;wikitable&amp;quot; |+ ESM 与 CJM |- !  !! ESM !! CJM |- | 应用场景 |  * 用于：浏览器、node.js  |  * 用于：node.js  |- | 加载方式 |  * 静态加载：&amp;#039;&amp;#039;&amp;#039;编译时&amp;#039;&amp;#039;&amp;#039;输出&amp;#039;&amp;#039;&amp;#039;模块接…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;[[category:JavaScript]]&lt;br /&gt;
&lt;br /&gt;
== 关于&amp;lt;ref&amp;gt;参考：&lt;br /&gt;
# [https://wangdoc.com/es6/module-loader 网道：ES6 教程：《Module 的加载实现》]&lt;br /&gt;
# [https://zhuanlan.zhihu.com/p/113009496 《前端科普系列-CommonJS：不是前端却革命了前端》]&lt;br /&gt;
&amp;lt;/ref&amp;gt; ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ ESM 与 CJM&lt;br /&gt;
|-&lt;br /&gt;
!  !! ESM !! CJM&lt;br /&gt;
|-&lt;br /&gt;
| 应用场景&lt;br /&gt;
| &lt;br /&gt;
* 用于：浏览器、node.js &lt;br /&gt;
| &lt;br /&gt;
* 用于：node.js &lt;br /&gt;
|-&lt;br /&gt;
| 加载方式&lt;br /&gt;
| &lt;br /&gt;
* 静态加载：'''编译时'''输出'''模块接口'''&amp;lt;sup&amp;gt;[[#“编译时加载”与“运行时加载” | “编译时加载”与“运行时加载”]]&amp;lt;/sup&amp;gt;&lt;br /&gt;
* '''异步'''加载&lt;br /&gt;
|&lt;br /&gt;
* 动态加载：'''运行时'''输出'''模块对象'''&amp;lt;sup&amp;gt;[[#“编译时加载”与“运行时加载” | “编译时加载”与“运行时加载”]]&amp;lt;/sup&amp;gt;&lt;br /&gt;
* '''同步'''加载&lt;br /&gt;
|-&lt;br /&gt;
| 模块机制&lt;br /&gt;
| &lt;br /&gt;
* 导出内容：'''各接口'''，多方式（单接口、多接口、对象）&lt;br /&gt;
* 导出方式：'''引用'''&amp;lt;sup&amp;gt;[[#“值引用”与“值拷贝” | “值引用”与“值拷贝”]]&amp;lt;/sup&amp;gt;&lt;br /&gt;
* this 指向：undefined&lt;br /&gt;
|&lt;br /&gt;
* 导出内容：'''对象“module.exports”，各接口作为其属性'''&lt;br /&gt;
* 导出方式：'''拷贝'''&amp;lt;sup&amp;gt;[[#“值引用”与“值拷贝” | “值引用”与“值拷贝”]]&amp;lt;/sup&amp;gt;&lt;br /&gt;
* this 指向：当前模块&lt;br /&gt;
|-&lt;br /&gt;
| 循环引用&amp;lt;sup&amp;gt;[[#循环引用 | 循环引用]]&amp;lt;/sup&amp;gt;&lt;br /&gt;
| &lt;br /&gt;
* 不会出现循环引用&lt;br /&gt;
|&lt;br /&gt;
* 应该避免循环引用&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== “编译时加载”与“运行时加载” ===&lt;br /&gt;
 “编译时加载”：编译时就确定模块的依赖关系，以及导入和导出的接口&lt;br /&gt;
 &lt;br /&gt;
 “运行时加载”：运行时才确定模块的依赖关系，以及导入和导出的对象&lt;br /&gt;
&lt;br /&gt;
CommonJS 示例：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// 代码合法&lt;br /&gt;
const name = getName()&lt;br /&gt;
console.log(name)&lt;br /&gt;
import { getName } from 'module.js'&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
:* 由于“运行时加载”，'''import 将会被提升至代码头部'''，先于 getName() 执行，所以代码是合法的。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ES Module 示例：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// 代码报错：import 中不能使用表达式&lt;br /&gt;
import { 'n' + 'ame' } from 'module.js'&lt;br /&gt;
&lt;br /&gt;
// 代码报错：import 中不能使用变量&lt;br /&gt;
let module = 'module.js'&lt;br /&gt;
import { name } from module&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
:* 由于“编译时加载”，'''import 中不能使用变量、表达式'''。&lt;br /&gt;
&lt;br /&gt;
=== “值引用”与“值拷贝” ===&lt;br /&gt;
 “值引用”：被导出的绑定值依然可以在本地进行修改&lt;br /&gt;
 &lt;br /&gt;
 “值拷贝”：一旦值被导出，模块内部的变化就不再影响该值&lt;br /&gt;
&lt;br /&gt;
CommonJS 示例：&lt;br /&gt;
# a.js：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
var name = 'morrain'&lt;br /&gt;
var age = 17&lt;br /&gt;
exports.name = name&lt;br /&gt;
exports.age = age&lt;br /&gt;
exports.setAge = function(a){&lt;br /&gt;
    age = a&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# b.js：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
var a = require('a.js')&lt;br /&gt;
console.log(a.age)  // 输出：18&lt;br /&gt;
a.setAge(19)&lt;br /&gt;
console.log(a.age)  // 输出：18&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ES Module 示例：&lt;br /&gt;
# a.js：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
var name = 'morrain'&lt;br /&gt;
var age = 17&lt;br /&gt;
const setAge = a =&amp;gt; age = a&lt;br /&gt;
export { name, age, setAge }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# b.js：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
import * as a from 'a.js'&lt;br /&gt;
console.log(a.age)  // 输出：18&lt;br /&gt;
a.setAge(19)&lt;br /&gt;
console.log(a.age)  // 输出：19&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 循环引用 ==&lt;br /&gt;
 CommonJS：模块在返回时可能尚未完成执行，不会出现无限循环。&lt;br /&gt;
 &lt;br /&gt;
 ES Module：&lt;br /&gt;
 —— 静态导入：模块在初始化完成之前不能访问 —— 应该避免“循环引用”。&lt;br /&gt;
 —— 动态导入：由于是异步执行，不会出现无限循环，但可能不能得到正确的内容 —— 应该避免“循环引用”。&lt;br /&gt;
&lt;br /&gt;
=== CommonJS 示例： ===&lt;br /&gt;
# a.js:&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
console.log('a starting');&lt;br /&gt;
exports.done = false;&lt;br /&gt;
const b = require('./b.js');&lt;br /&gt;
console.log('in a, b.done = %j', b.done);&lt;br /&gt;
exports.done = true;&lt;br /&gt;
console.log('a done');&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# b.js:&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
console.log('b starting');&lt;br /&gt;
exports.done = false;&lt;br /&gt;
const a = require('./a.js');&lt;br /&gt;
console.log('in b, a.done = %j', a.done);&lt;br /&gt;
exports.done = true;&lt;br /&gt;
console.log('b done');&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# main.js:&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
console.log('main starting');&lt;br /&gt;
const a = require('./a.js');&lt;br /&gt;
const b = require('./b.js');&lt;br /&gt;
console.log('in main, a.done = %j, b.done = %j', a.done, b.done);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 输出：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
$ node main.js&lt;br /&gt;
main starting&lt;br /&gt;
a starting&lt;br /&gt;
b starting&lt;br /&gt;
in b, a.done = false&lt;br /&gt;
b done&lt;br /&gt;
in a, b.done = true&lt;br /&gt;
a done&lt;br /&gt;
in main, a.done = true, b.done = true&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ES Module “静态导入”示例： ===&lt;br /&gt;
# a.mjs:&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
import b from './b.mjs'&lt;br /&gt;
&lt;br /&gt;
let done = false;&lt;br /&gt;
console.log('a starting');&lt;br /&gt;
console.log('in a, b.done = %j', b.done);&lt;br /&gt;
done = true;&lt;br /&gt;
console.log('a done');&lt;br /&gt;
export default done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# b.mjs:&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
import a from './a.mjs'&lt;br /&gt;
&lt;br /&gt;
let done = false;&lt;br /&gt;
console.log('b starting');&lt;br /&gt;
console.log('in b, a.done = %j', a.done);&lt;br /&gt;
done = true;&lt;br /&gt;
console.log('b done');&lt;br /&gt;
export default done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# main.mjs:&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
import a from './a.mjs'&lt;br /&gt;
import b from './b.mjs'&lt;br /&gt;
&lt;br /&gt;
console.log('main starting');&lt;br /&gt;
console.log('in main, a.done = %j, b.done = %j', a.done, b.done);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 输出：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
PS D:\Documents\VSCode\helloWorld&amp;gt; node &amp;quot;d:\Documents\VSCode\helloWorld\main.mjs&amp;quot;&lt;br /&gt;
b starting&lt;br /&gt;
file:///d:/Documents/VSCode/helloWorld/b.mjs:5&lt;br /&gt;
console.log('in b, a.done = %j', a.done);&lt;br /&gt;
                                 ^&lt;br /&gt;
&lt;br /&gt;
ReferenceError: Cannot access 'a' before initialization&lt;br /&gt;
    at file:///d:/Documents/VSCode/helloWorld/b.mjs:5:34&lt;br /&gt;
    at ModuleJob.run (node:internal/modules/esm/module_job:194:25)&lt;br /&gt;
&lt;br /&gt;
Node.js v18.15.0&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ES Module “动态导入”示例： ===&lt;br /&gt;
# a.mjs:&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
let done = false;&lt;br /&gt;
console.log('a starting');&lt;br /&gt;
async function load() {&lt;br /&gt;
    let b = await import('./b.mjs');&lt;br /&gt;
    console.log('in a, b.done = %j', b.done);&lt;br /&gt;
}&lt;br /&gt;
load()&lt;br /&gt;
done = true;&lt;br /&gt;
console.log('a done');&lt;br /&gt;
export default done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# b.mjs:&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
let done = false;&lt;br /&gt;
console.log('b starting');&lt;br /&gt;
async function load() {&lt;br /&gt;
    let a = await import('./a.mjs');&lt;br /&gt;
    console.log('in b, a.done = %j', a.done);&lt;br /&gt;
}&lt;br /&gt;
load()&lt;br /&gt;
done = true;&lt;br /&gt;
console.log('b done');&lt;br /&gt;
export default done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# main.mjs:&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
console.log('main starting');&lt;br /&gt;
async function load() {&lt;br /&gt;
    let a = await import('./a.mjs');&lt;br /&gt;
    let b = await import('./b.mjs');&lt;br /&gt;
    console.log('in main, a.done = %j, b.done = %j', a.done, b.done);&lt;br /&gt;
}&lt;br /&gt;
load()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 输出：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
PS D:\Documents\VSCode\helloWorld&amp;gt; node &amp;quot;d:\Documents\VSCode\helloWorld\main.mjs&amp;quot;&lt;br /&gt;
main starting&lt;br /&gt;
a starting&lt;br /&gt;
a done&lt;br /&gt;
b starting&lt;br /&gt;
b done&lt;br /&gt;
in a, b.done = undefined&lt;br /&gt;
in main, a.done = undefined, b.done = undefined&lt;br /&gt;
in b, a.done = undefined&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== ES Module：循环引用的处理 ==&lt;br /&gt;
 &amp;lt;big&amp;gt;💡&amp;lt;/big&amp;gt; 利用&amp;lt;span style=&amp;quot;color: blue; font-size: 120%&amp;quot;&amp;gt;'''“函数提升”'''&amp;lt;/span&amp;gt;解决循环引用 &amp;lt;code&amp;gt;&amp;lt;span style=&amp;quot;color: red&amp;quot;&amp;gt;ReferenceError: Cannot access 'a' before initialization&amp;lt;/span&amp;gt;&amp;lt;/code&amp;gt; 的问题；&lt;br /&gt;
&lt;br /&gt;
示例：&lt;br /&gt;
# a.mjs：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
import * as b from './b.mjs'&lt;br /&gt;
&lt;br /&gt;
console.log('a starting');&lt;br /&gt;
console.log(`in a, b.msg1 = ${b.msg1}, b.msg2 = ${b.msg2}, print:${b.print()}`);&lt;br /&gt;
// var 提升：只会提升声明，不会提升其初始化&lt;br /&gt;
var msg1 = 'msg1-a'&lt;br /&gt;
var msg2 = function(){&lt;br /&gt;
    return 'msg2-a';&lt;br /&gt;
}()&lt;br /&gt;
// 函数提升&lt;br /&gt;
function print(){&lt;br /&gt;
    return 'hello from a !'&lt;br /&gt;
}&lt;br /&gt;
console.log('a done');&lt;br /&gt;
export {msg1, msg2, print}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# b.mjs：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
import * as a from './a.mjs'&lt;br /&gt;
&lt;br /&gt;
console.log('b starting');&lt;br /&gt;
console.log(`in b, a.msg1 = ${a.msg1}, a.msg2 = ${a.msg2}, print:${a.print()}`);&lt;br /&gt;
// var 提升：只会提升声明，不会提升其初始化&lt;br /&gt;
var msg1 = 'msg1-b'&lt;br /&gt;
var msg2 = function(){&lt;br /&gt;
    return 'msg2-b';&lt;br /&gt;
}()&lt;br /&gt;
// 函数提升&lt;br /&gt;
function print(){&lt;br /&gt;
    return 'hello from b !'&lt;br /&gt;
}&lt;br /&gt;
console.log('b done');&lt;br /&gt;
export {msg1, msg2, print}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 运行 a.mjs 输出：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
PS D:\Documents\VSCode\demo&amp;gt; node &amp;quot;d:\Documents\VSCode\demo\a.mjs&amp;quot;&lt;br /&gt;
b starting&lt;br /&gt;
in b, a.msg1 = undefined, a.msg2 = undefined, print:hello from a !&lt;br /&gt;
b done&lt;br /&gt;
a starting&lt;br /&gt;
in a, b.msg1 = msg1-b, b.msg2 = msg2-b, print:hello from b !&lt;br /&gt;
a done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;big&amp;gt;📜&amp;lt;/big&amp;gt;：'''“变量提升”只能使不报错，但不能得到有效内容'''&lt;br /&gt;
 &lt;br /&gt;
 —— 1、&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;只有 &amp;lt;code&amp;gt;var&amp;lt;/code&amp;gt; 变量会进行提升&amp;lt;/span&amp;gt;；&lt;br /&gt;
 &lt;br /&gt;
 —— 2、&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;只会提升“声明”，不会提升“非初始化”&amp;lt;/span&amp;gt; —— 所以，上面变量为 &amp;lt;code&amp;gt;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''undefined'''&amp;lt;/span&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 在 node.js 中&amp;lt;ref&amp;gt;参考：[https://nodejs.cn/api-v18/packages.html Node.js文档：《module/package 包模块》]&amp;lt;/ref&amp;gt; ==&lt;br /&gt;
 Node.js 有两个模块系统：CommonJS 模块和 ECMAScript 模块。&lt;br /&gt;
&lt;br /&gt;
Node.js 会将以下视为 ES Module：&lt;br /&gt;
# 扩展名为 &amp;lt;code&amp;gt;'''.mjs'''&amp;lt;/code&amp;gt; 的文件。&lt;br /&gt;
# 最近的父“'''package.json'''”文件中“'''type'''”字段值为“'''module'''”时，扩展名为 &amp;lt;code&amp;gt;'''.js'''&amp;lt;/code&amp;gt; 的文件。&lt;br /&gt;
# 字符串作为参数传入 &amp;lt;code&amp;gt;'''--eval'''&amp;lt;/code&amp;gt;，或通过“'''STDIN'''”管道传输到 node，带有标志 &amp;lt;code&amp;gt;'''--input-type=module'''&amp;lt;/code&amp;gt;。&lt;br /&gt;
&lt;br /&gt;
Node.js 会将以下视为 CommonJS：&lt;br /&gt;
# 扩展名为 &amp;lt;code&amp;gt;'''.cjs'''&amp;lt;/code&amp;gt; 的文件。&lt;br /&gt;
# 最近的父“'''package.json'''”文件中“'''type'''”字段值为“'''commonjs'''”时，扩展名为 &amp;lt;code&amp;gt;'''.js'''&amp;lt;/code&amp;gt; 的文件。&lt;br /&gt;
# 字符串作为参数传入 &amp;lt;code&amp;gt;'''--eval'''&amp;lt;/code&amp;gt; 或 &amp;lt;code&amp;gt;'''--print'''&amp;lt;/code&amp;gt;，或通过“'''STDIN'''”管道传输到 node，带有标志 &amp;lt;code&amp;gt;'''--input-type=commonjs'''&amp;lt;/code&amp;gt;。&lt;br /&gt;
&lt;br /&gt;
 包作者应该设置“type”字段 ！&lt;br /&gt;
 &lt;br /&gt;
 应避免同时使用 ES Module 和 CommonJS ！&lt;br /&gt;
&lt;br /&gt;
== 参考 ==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
</feed>