<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>JavaScript Module Systems on 日日是好日</title><link>https://jjjjjjy.github.io/posts/javascript/javascriptmodulesystems/</link><description>Recent content in JavaScript Module Systems on 日日是好日</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Sat, 28 Feb 2026 14:26:13 +0800</lastBuildDate><atom:link href="https://jjjjjjy.github.io/posts/javascript/javascriptmodulesystems/index.xml" rel="self" type="application/rss+xml"/><item><title>JS模块化</title><link>https://jjjjjjy.github.io/posts/javascript/javascriptmodulesystems/jsmodule/</link><pubDate>Sat, 28 Feb 2026 14:26:13 +0800</pubDate><guid>https://jjjjjjy.github.io/posts/javascript/javascriptmodulesystems/jsmodule/</guid><description>&lt;h1 id="模块化"&gt;模块化
&lt;/h1&gt;&lt;p&gt;模块化（Module）指把代码拆分成独立、可复用、可维护的单元。每个模块能够：1️⃣ 独立作用域 2️⃣ 明确依赖 3️⃣ 对外暴露接口；&lt;strong&gt;目的&lt;/strong&gt;：防止变量污染、提高代码复用、提升可维护性、支持大型工程&lt;/p&gt;
&lt;h1 id="javascript-模块化发展历史"&gt;JavaScript 模块化发展历史
&lt;/h1&gt;&lt;h2 id="阶段1iife"&gt;阶段1：IIFE
&lt;/h2&gt;&lt;p&gt;IIFE = 立即执行函数&lt;/p&gt;
&lt;h2 id="阶段2commonjs"&gt;阶段2：CommonJS
&lt;/h2&gt;&lt;p&gt;CommonJS 是 Node.js 的模块规范。&lt;/p&gt;
&lt;p&gt;特点：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;同步加载（Node 可以同步读文件。浏览器不行。）&lt;/li&gt;
&lt;li&gt;运行时加载&lt;/li&gt;
&lt;li&gt;适合服务器环境&lt;/li&gt;
&lt;li&gt;值拷贝（CommonJS 导出是 值拷贝）&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;CommonJS 加载过程&lt;/strong&gt;： const module = require(&amp;rsquo;./math&amp;rsquo;);&lt;/p&gt;
&lt;h2 id="阶段3amd--cmd"&gt;阶段3：AMD / CMD
&lt;/h2&gt;&lt;h3 id="amd异步模块定义asynchronous-module-definition"&gt;AMD&lt;code&gt;异步模块定义&lt;/code&gt;(Asynchronous Module Definition)
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;使用 define 定义模块&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;使用 require 加载模块&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="cmd-公共模块定义common-module-definition"&gt;CMD &lt;code&gt;公共模块定义&lt;/code&gt;(Common Module Definition)
&lt;/h3&gt;&lt;p&gt;在 CMD 规范中，一个模块就是一个文件。
&lt;strong&gt;使用 define 定义模块&lt;/strong&gt;
&lt;strong&gt;使用 SeaJs 的 use 加载模块&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="umd通用模块定义universal-module-definition"&gt;UMD&lt;code&gt;通用模块定义&lt;/code&gt;(Universal Module Definition)
&lt;/h3&gt;&lt;p&gt;UMD 是 AMD 和 CommonJS 的一个糅合。
AMD 是浏览器优先，异步加载；
CommonJS 是服务器优先，同步加载。
既然要通用，怎么办呢？
那就先判断是否支持 node 的模块，支持就使用 node；
再判断是否支持 AMD，支持则使用 AMD 的方式加载。
这就是所谓的 UMD。&lt;/p&gt;
&lt;h3 id="amd-和-cmd-的区别"&gt;AMD 和 CMD 的区别
&lt;/h3&gt;&lt;p&gt;对于依赖的模块，AMD 是 提前执行，CMD 是 延迟就近执行。
AMD是立即执行，CMD是按需执行。&lt;/p&gt;
&lt;p&gt;AMD 推崇 依赖前置，CMD 推崇 依赖就近。&lt;/p&gt;
&lt;p&gt;AMD 的 API 默认是一个当多个用，CMD 的 API 严格区分，推崇职责单一。&lt;/p&gt;
&lt;h2 id="阶段4es-module"&gt;阶段4：ES Module
&lt;/h2&gt;&lt;p&gt;ES6 模块的设计思想是尽量的 &lt;strong&gt;静态化&lt;/strong&gt;，即在&lt;strong&gt;编译阶段&lt;/strong&gt;就确定模块的依赖关系，以及输入和输出的变量。&lt;/p&gt;
&lt;p&gt;｜ CommonJS 和 AMD 模块，都只能在运行时确定这些东西。&lt;/p&gt;
&lt;p&gt;在 ES6 中，我们使用 export 关键字来导出模块，使用 import 关键字来引入模块。&lt;/p&gt;
&lt;p&gt;🔥 优点：Tree Shaking 和 编译优化&lt;/p&gt;
&lt;p&gt;ESM导出的是值引用。&lt;/p&gt;
&lt;h2 id="es6-模块与-commonjs-模块的差异"&gt;💡ES6 模块与 CommonJS 模块的差异
&lt;/h2&gt;&lt;p&gt;｜ 区别&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: center"&gt;区别&lt;/th&gt;
&lt;th style="text-align: center"&gt;CommonJS&lt;/th&gt;
&lt;th style="text-align: center"&gt;ESM&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;加载方式&lt;/td&gt;
&lt;td style="text-align: center"&gt;运行时加载&lt;/td&gt;
&lt;td style="text-align: center"&gt;编译时输出接口&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;加载方式&lt;/td&gt;
&lt;td style="text-align: center"&gt;同步加载&lt;/td&gt;
&lt;td style="text-align: center"&gt;异步加载，有一个独立的模块依赖的解析阶段。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;模块输出&lt;/td&gt;
&lt;td style="text-align: center"&gt;值的拷贝&lt;/td&gt;
&lt;td style="text-align: center"&gt;值的引用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;语法&lt;/td&gt;
&lt;td style="text-align: center"&gt;require()&lt;/td&gt;
&lt;td style="text-align: center"&gt;import&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;适用环境&lt;/td&gt;
&lt;td style="text-align: center"&gt;Node&lt;/td&gt;
&lt;td style="text-align: center"&gt;浏览器+Node&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;Tree Shaking&lt;/td&gt;
&lt;td style="text-align: center"&gt;不能，因为require是动态执行，编译期无法确定依赖&lt;/td&gt;
&lt;td style="text-align: center"&gt;可以，因为依赖关系可以静态分析&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;🌼 引申&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;require和import的区别：require()是运行时加载，import是编译时输出接口。&lt;/li&gt;
&lt;li&gt;treeShaking是在哪个阶段做的？&lt;/li&gt;
&lt;li&gt;Node 为什么最早用 CommonJS？&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;因为node读取本地文件是同步的，而CJS同步加载没有问题&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="4"&gt;
&lt;li&gt;module.exports 和 exports 的区别？&lt;/li&gt;
&lt;/ol&gt;</description></item></channel></rss>