对AMD,CMD,CommonJs的理解
AMD
规范即异步模块加载机制。从规范描述页面看,AMD
很短也很简单,但却完整描述了模块的定义,依赖关系,引用关系以及加载机制。 AMD规范其实只有一个主要接口 define(id,dependencies,factory)
,它要在声明模块的时候指定所有的依赖dependencies
,并且还要当做形参传到factory
中,对于依赖的模块提前执行,依赖前置
1 | 1. define("module", ["dep1", "dep2"], function(d1, d2) { |
优点:1、适合在浏览器环境异步加载2、并行加载多个模块
缺点:1、提高开发成本,代码阅读和书写比较困难2、不符合通用的模块思维方式,是一种妥协的实现
实现:requireJS,NodeJs,Dojo,JQuery
CMD规范和AMD相似,尽量保持简单,并且与CommonJS
和NodeJS
的Modules
规范保持了很大的兼容性。在CMD中,一个模块就是一个文件,格式为:define( factory )
1 | 6. define("module", ["dep1", "dep2"], function(d1, d2) { |
优点:1、依赖就近,延迟执行2、很容易在node中运行
缺点:1、依赖SPM打包,模块的加载逻辑偏重
实现:SeaJSCommonJS
是在浏览器环境之外构建JavaScript
生态系统为目标产生的项目,比如服务器和桌面环境中。CommonJS
规范是为了解决JavaScript
的作用域问题而定义的模块形式,可以使每个模块在它自身的命名空间中执行。该规范的主要内容是:模块必须通过 module.exports
导出对外的变量或接口,通过require()
来导入其他模块的输出到当前模块。
1 | 10. // moduleA.js |
CommonJS
是同步加载模块,一个单独的文件就是一个模块。但其实也有浏览器端的实现,其原理是将所有模块都定义好并通过id进行索引,这样就可以浏览器进行解析了 服务器端的Node.js
遵循CommonJS
规范。核心思想是允许模块通过require
方法来同步加载所要依赖的其他模块,然后通过 exports
或module.exports
来导出需要暴露的接口。
1 | 17. require("module"); |
优点:1、服务器端便于重用2、NPM中已经将近20w个模块包3、简单并容易使用
缺点:1、同步的模块方式不适合在浏览器环境中,同步意味着阻塞加载,浏览器资源是异步加载的2、不能非阻塞的并行加载多个模块
区别:(AMD or CMD)
1 对于依赖的模块,AMD
是提前执行,CMD
是延迟执行。不过 RequireJS
从 2.0 开始,也改成可以延迟执行(根据写法不同,处理方式不同)。CMD
推崇 as lazy as possible
.
2 CMD
推崇依赖就近,AMD
推崇依赖前置
3 AMD
的 API
默认是一个当多个用,CMD
的 API
严格区分,推崇职责单一。
4 CMD
相当于按需加载,定义一个模块的时候不需要立即制定依赖模块,在需要的时候require就可以了,比较方便;而AMD
则相反,定义模块的时候需要制定依赖模块。
为什么要模块化?不用的时候和用RequireJS的时候代码该如何书写
1 方便大量的js脚本代码的管理维护以及团队配合开发
2 有效解决命名空间冲突及文件依赖加载顺序问题
3 有利于模块的版本管理,提高可维护性,有利于前端性能优化,跨环境共享模块
同步和异步模块化的应用场景,AMD异步模块化实现的原理
引入JS时会遇到需要异步加载文件,此时require.async便可满足异步加载需求