AMD CMD 和ES6 模块化

这里写目录标题

  • AMD(Asynchronous Module Definition
  • CMD(Common Module Definition)
  • AMD/CMD比较
    • 定义module时对依赖的处理
    • 加载方式
    • 执行module的方式
    • 总结
  • ES6模块化
    • 默认的导入与导出
    • 按需导入与导出;
    • 直接导入并执行
  • 一些问题
    • 什么是模块化?
    • 为什么要用模块化?
    • 模块化的好处?
    • AMD、CMD、CommonJS模块规范的对比分析:

模块化的开发方式可以提高 代码复用率,方便进行代码的管理。通常 一个文件就是一个模块,有自己的作用域,只向外暴露特定的变量和函数。

AMD(Asynchronous Module Definition

AMD,异步模块定义。AMD不是javascript原生支持,它是RequireJS在推广的过程中对模块定义的范围化的产出。所以使用AMD规范进行页面开发需要用到对应的库,也就是RequireJS。

requireJS主要解决两个问题:

  • 多个js文件存在依赖关系时,被依赖的文件需要早于依赖它的文件加载到浏览器
  • js加载的时候浏览器会阻塞渲染线程,加载文件越多,页面失去响应的时间越长.

写法:

// index.js
define(function(){
     
	var drawMap ={
     
		init:function(){
     
		this.drawMarker();
		},
		drawMarker:function(){
     
			console.log(marker)
		}
	}
	return drawMap;
)
// html 引用
requirejs.config({
     
        paths: {
     
            	drawMap: '/js/index.js',
        	}
});
//第一个参数,要加载的模块  第二参数,回调函数
require(["drawMap"],function(drawMap){
     
        drawMap.init()
});

CMD(Common Module Definition)

CMD, 通用模块定义。 CMD是在SeaJS推广的过程中产生的,是一个同步模块定义(CMD是依赖就近、按需加载,在什么地方使用到插件就在什么地方require该插件,即用即返)。在CMD规范中,一个模块就是一个文件。

AMD/CMD比较

定义module时对依赖的处理

  • AMD推崇依赖前置,在定义的时候就要声明其依赖的模块
  • CMD推崇就近依赖,只有在用到这个module的时候才去require

加载方式

AMD: async
CMD: sync

执行module的方式

AMD加载module完成后就会执行该module,所有module都加载执行完成后会进入require的回调函数,执行主逻辑。依赖的执行顺序和书写的顺序不一定一致,谁先下载完谁先执行,但是主逻辑 一定在所有的依赖加载完成后才执行(有点类似Promise.all)。
CMD加载完某个依赖后并不执行,只是下载而已。在所有的module加载完成后进入主逻辑,遇到require语句的时候才会执行对应的module。module的执行顺序和书写的顺序是完全一致的。

总结

AMD、CMD采用异步加载,两者的区别就是AMD采用前置预加载模式,CMD采用就近原则加载模式。AMD的体验更好,CMD的性能更优,但是CMD需要考虑异步队列的执行顺序问题,所以这里的更好和更优要相对而言。

ES6模块化

ES6自带模块化,可以使用import关键字引入模块,通过export关键字到处模块,功能较之前几个方案更为强大,但是由于ES6目前无法在浏览器中执行,所以,需要通过babel将不支持的import编译为当前收到广泛支持的require。
ES6模块规范的设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系。而CommonJS和CMD,都只能在运行时确定依赖。

默认的导入与导出


//index.js
let a =1;
function draw(){
     
}
export default{
     
	a,
	draw()
}
import index from 'index.js'
console.log(index);
// 打印出来是  {a:0,draw:{function draw}}

注意

  • 在每一个模块中只允许使用唯一的一次 export default ,否则会报错
  • 在一个模块中如果没有向外 export default,则导入该模块时 默认输出 {}

    按需导入与导出;

    • 在使用CommonJS规范时,输出的是值的拷贝,也就是说输出之后,模块内部的变化不会影响输出。但在ES6中是恰好相反的,ES6规范中输出的是值的引用,也就是说模块内部变化会影响输出
// index.js
export let a = 'aaa'
// 向外按需 导出 b
export let b = 'bbb'
// 向外按需 导出方法 show
export function say(){
     
 console.log('say')
}

// 默认导入和按需导入同时使用
// import index,{ a, b, say } from './index.js'

// 导入模块成员
import {
      a, b, say } from './index.js'
console.log(a) // 打印 输出 aaa
console.log(b) // 打印 输出 bbb
console.log(say) // 打印 输出 [Function: say]

注意:

在每一个模块中 可以使用 n 多次按需导出

直接导入并执行

在 单纯执行 某个模块的代码,并不需要得到模块中向外暴露的成员时,就可以直接导入并执行模块代码

在模块中写一个 for 循环为例,代码如下:
// 当前是 e2.js 模块
for(let i = 0; i < 3; i++){
     
    console.log(i)
}
直接导入并执行模块代码,代码如下:
// 直接导入并执行 模块代码
import './e2.js' 

一些问题

什么是模块化?

答:模块化是指将一个复杂的系统分解为多个模块,方便编码。

为什么要用模块化?

答:降低复杂性,降低代码耦合度,部署方便,提高效率。

模块化的好处?

  • 避免命名冲突,减少变量空间污染;

  • 更好的分离代码,按序加载;

  • 更高复用性;

  • 更高可维护性;

AMD、CMD、CommonJS模块规范的对比分析:

AMD、CMD可以使用插件引入的方式实现JS代码模块化管理,CommonJS不兼容浏览器需要Browserify工具在nodejs环境下转换成浏览器可执行的JS文件。

Commonjs采用同步加载,会在一定程度上增加页面载入时间,如果在这个过程中出现某个模块错误,会导致页面加载失败。

你可能感兴趣的:(前端)