前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【模块化】:JS 模块化极简史

【模块化】:JS 模块化极简史

作者头像
WEBJ2EE
发布2022-03-30 21:06:13
1.8K0
发布2022-03-30 21:06:13
举报
文章被收录于专栏:WebJ2EEWebJ2EE
代码语言:javascript
复制
目录
1. 什么是模块化?
2. 无模块化时代
3. 传统模块化阶段
  3.1. “对象”型模块
  3.2. “仿Java类”型模块
  3.3. “立即执行函数(IIFE)”型模块
  3.4. “全局变量输入”型模块
4. 百家争鸣:CommonJS、AMD、CMD
  4.1. CommonJS
  4.2. AMD
  4.3. CMD
5. 一统天下:ES6 Module

1. 什么是模块化?

模块化开发就是封装细节,提供使用接口,彼此之间互不影响,每个模块都是实现某一特定的功能。

——《软件工程》

在模块化编程中,开发者将程序分解成离散功能块(discrete chunks of functionality),并称之为模块。

每个模块具有比完整程序更小的接触面,使得校验、调试、测试轻而易举。精心编写的模块提供了可靠的抽象和封装界限,使得应用程序中每个模块都具有条理清楚的设计和明确的目的。

——《Webpack官网》

有啥好处?

a. 避免命名冲突(不占全局命名空间);

b. 便于依赖管理(无须手动组织JS文件顺序);

c. 利于性能优化(异步模块加载);

e. 提高可维护性;

f. 利于代码复用;

2. 无模块化时代

最初,大家只是把项目中的功能,以文件为单位进行划分;这么干的结果是.....所有的变量、函数都暴露在全局作用域;多人协作开发时,极易出现命名冲突,也容易为了避免命名冲突,硬造一些稀奇古怪的名字....时间越长,麻烦越多...维护成本也越高...

3. 传统模块化阶段

这一阶段,WEB 开发人员主要是利用 JS 语言的闭包、原型、函数作用域等特性,减少对全局命名空间的污染;方式方法各有不同,但结果都差不多,比较混乱...

3.1. “对象”型模块

3.2. “仿Java类”型模块

3.3. “立即执行函数(IIFE)”型模块

3.4. “全局变量输入”型模块

注:上面仅列举了传统模块化方法中的几种常见代码组织形式,还有“放大型”、“宽松放大型”等其它方法,这里就不一一列举了,有兴趣可以看看下面这篇文章... http://www.adequatelygood.com/JavaScript-Module-Pattern-In-Depth.html

传统模块化方法中

基本做到了让模块更独立、减少模块间冲突

但还有个更重要的问题没解决掉

如何清晰地描述模块间依赖

搞这么一大堆方法

优点肯定是有的

优点:传统模块化相比于无模块化时代,显然是进步的:减少了命名冲突,增强了模块的独立性;

但是

缺点同样明显

缺点: 1. 污染全局作用域:虽然我们通过各种手段尽力避免,但实际未从根本上解决; 2. 依赖关系不明显:对于大型项目,模块数量巨大,开发人员必须手动解决模块间依赖,这在复杂项目中极易出错维护成本高

4. 百家争鸣:CommonJS、AMD、CMD

JavaScript 在语言层面迟迟不推出模块化功能,这个背景下,各“民间组织”提出了CommonJSAMDCMD 模块化规范...

——《高手在民间》

4.1. CommonJS

Node.js的诞生,使JavaScript扩展到了服务器端, 为了让JavaScript在服务器端能跟Java、Phyton一样编写大型程序,于是有了CommonJS模块化规范;

(1). CommonJS是针对服务器端(非浏览器环境)的JavaScript开发,是Node.js的默认模块化规范; (2). CommonJS是一种只适用于JavaScript静态模块化规范注:只适用于JavaScript,意味着它无法把CSS等前端资源纳入模块化管理范围,但显然CSS也是组成前端模块的重要部分; 注:静态模块化规范,意味着它无法实现按需加载; (3). CommonJS所有模块均是同步阻塞式加载,无法实现异步加载; 注:服务器端加载模块是从硬盘直接读取,时间消耗和忽略不计;但浏览器端需要经网络下载,时间消耗取决于网速,同步加载策略容易出现“假死”,因此“同步阻塞式”加载策略不适用于浏览器环境

示例:

CommonJS是针对服务器端JavaScript的规范

但不适用于浏览器端

于是衍生出针对浏览器端的

AMD和CMD规范

4.2. AMD

AMD(Asynchronous Module Definition),异步模块定义;

实现:RequireJS; 特性:依赖前置,提前执行;

示例:

4.3. CMD

CMD(Common Module Definition),通用模块定义;CMD与AMD很类似,只是在模块的运行、解析时机上有所不同;

实现:SeaJS; 特性:依赖就近,延迟执行;

示例:

5. 一统天下:ES6 Module

ES6在语言规格的层面上实现了模块功能,而且实现的相当简单,完全可以取代现有的CommonJS、AMD和CMD规范,成为浏览器和服务器通用的模块解决方案

特点:

语言级、静态模块化规范; 实现按需加载的dynamic import语法提案现处于stage3阶段; 完全可替代CommonJS、AMD、CMD;

示例1(static import):

示例2(dynamic import):

总结一下

传统模块化手段:通过JS的闭包、对象、自执行函数等语言特性,避免模块间的命名冲突,提高模块的内聚性,但无统一编程标准,也无法把模块间的依赖关系描述清晰; CommonJS:Node.js让JavaScript延伸到“服务端”领域,促使针对“服务端”的JavaScript静态模块化规范CommonJS诞生,但此规范的“同步阻塞式”模块加载策略不适用于浏览器端环境; AMD,CMD:CommonJS规范的衍生品,支持模块“异步并行加载”,适用浏览器环境;AMD推崇“依赖前置”、CMD则是“依赖后置”;AMD规范的产物为RequireJS,CMD是SeaJS; ES6 Module:官方模块化标准,是语言的一部分,无需额外引入第三方库;ES6 Module同CommonJS一样,也是静态模块化规范,无法实现“按需加载”;但目前有一份处于stage3阶段的 dynamic import(tc39/proposal-dynamic-import)提案可用于动态模块加载;ES6完全可以取代CommonJS、AMD、CMD,成为浏览器和服务器端通用的模块化解决方案;

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-02-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 WebJ2EE 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
命令行工具
腾讯云命令行工具 TCCLI 是管理腾讯云资源的统一工具。使用腾讯云命令行工具,您可以快速调用腾讯云 API 来管理您的腾讯云资源。此外,您还可以基于腾讯云的命令行工具来做自动化和脚本处理,以更多样的方式进行组合和重用。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档