这是我参与8月更文挑战的第8天,活动详情查看:8月更文挑战前端
优势
:模块化
就是将系统分离成独立功能的模块,这样咱们须要什么功能,就加载什么功能。web
模块化的优势
:编程
CommonJS(服务端)
=>AMD(浏览器)
=> CMD
=> ES6 Module模块化
浏览器
前端模块规范有三种:CommonJs,AMD和CMD。
CommonJs用在服务器端,AMD和CMD用在浏览器环境
AMD 是 RequireJS 在推广过程当中对模块定义的规范化产出。
CMD 是 SeaJS 在推广过程当中对模块定义的规范化产出。\缓存
AMD:提早执行(异步加载:依赖先执行)+延迟执行
CMD:延迟执行(运行到需加载,根据顺序执行)服务器
Node 应用由模块组成,采用 CommonJS 模块规范。markdown
每一个文件就是一个独立模块
,有本身的做用域
。在一个文件里面定义的变量、函数、类,都是私有的
,对其余文件不可见。网络
主要分为定义模块和引入模块两个步骤。异步
定义模块模块化
CommonJS规范规定,每一个模块内部,module
变量表明当前模块。这个变量是一个对象,它的exports
属性(即module.exports
)是对外的接口。加载某个模块,实际上是加载该模块的module.exports
属性。
// 经过`module.exports`输出变量`x`和函数`addX`
let x = 1;
let addX = function (value) {
return value + x;
};
module.exports.x = x;
module.exports.addX = addX;
复制代码
引入模块
require
方法用于加载模块。
var example = require('./example.js');
复制代码
CommonJS模块的加载机制是,输入的是被输出的值的拷贝。也就是说,一旦输出一个值,模块内部的变化就影响不到这个值。
AMD规范全称是Asynchronous Module Definition,即异步模块加载机制,主要用于浏览器。它完整描述了模块的定义,依赖关系,引用关系以及加载机制。因为该规范不是原生js
支持的,使用AMD规范进行开发的时候须要引入第三方的库函数,AMD对应的就是鼎鼎大名的RequireJS。
define和require这两个定义模块、调用模块的方法,合称为AMD模式。它的模块定义的方法很是清晰,不会污染全局环境,可以清楚地显示依赖关系。
使用define
用来暴露模块,使用require
用来引入模块;require()异步加载模块,浏览器不会失去响应;它指定的回调函数,只有前面的模块都加载成功后,才会运行,解决了依赖性的问题。
AMD模式能够用于浏览器环境
,而且容许异步加载模块
,也能够根据须要动态加载模块。
define方法用于定义模块
,RequireJS要求每一个模块放在一个单独的文件里。 按照是否依赖其余模块,能够分红两种状况讨论。第一种状况是定义独立模块
,即所定义的模块不依赖其余模块;第二种状况是定义非独立模块
,即所定义的模块依赖于其余模块。
require方法用于调用模块。它的参数与define方法相似。
RequireJS
主要解决了两个问题:js
文件可能有依赖关系,被依赖的文件须要早于依赖它的文件加载到浏览器js
加载的时候浏览器会中止页面渲染,加载文件越多,页面失去响应时间越长CommonJS规范加载模块是同步的,也就是说,只有加载完成,才能执行后面的操做。AMD规范则是非同步加载模块,容许指定回调函数。因为Node.js主要用于服务器编程,模块文件通常都已经存在于本地硬盘,因此加载起来比较快,不用考虑非同步加载的方式,因此CommonJS规范比较适用。可是,若是是浏览器环境,要从服务器端加载模块,这时就必须采用非同步模式,所以浏览器端通常采用AMD规范。
CMD(Common Module Definition) ,通用模块定义,它解决的问题和AMD规范是同样的,只不过在模块定义方式和模块加载时机上不一样,CMD也须要额外的引入第三方的库文件,SeaJS
,SeaJS
推崇一个模块一个文件
(对于模块的引入,具备同步和异步两中方式)
define
是一个全局函数,用来定义模块
SeaJS
提供了seajs.use
来加载模块
SeaJS的出现,是CommonJS在浏览器的践行者,并吸取了RequireJS的优势
ES6 规范只支持静态的导入和导出,ES Module 须要在编译时期进行模块静态优化,也就是必需要在编译时就能肯定。
为何要这么作,主要是两点:
export
和import
export
用于暴露接口,import
用于引入模块在使用 ES Module 值得注意的是:import 和 export 命令只能在模块的顶层,在代码块中将会报错,这是由于 ES Module 须要在编译时期进行模块静态优化,import 和 export 命令会被 JavaScript 引擎静态分析,先于模块内的其余语句执行,这种设计有利于编译器提升效率,但也致使没法在运行时加载模块(动态加载)。
对于这个缺点,TC39 有了一个新的提案 – Dynamic Import,提案的内容是建议引入 import()
方法,实现模块动态加载。
// specifier: 指定所要加载的模块的位置
import(specifier)
复制代码
它是运行时执行,也就是说,何时运行到这句话,就会加载到指定的模块。另外,import()函数所加载的模块没有静态连接关系,这点也是与import语法不一样
模块定义时对依赖的处理不一样
AMD推崇前置依赖,在定义模块时就要声明其依赖的模块;而CMD推从就近依赖,只有在用到某个模块时再使用require导入;
对依赖模块的处理机制不一样
首先AMD和CMD对模块的加载方式都是异步的 不过区别在于AMD当加载了依赖模块以后当即执行依赖模块,依赖模块的执行顺序和咱们书写的顺序不必定一致; 而CMD加载完依赖模块以后,并不会当即执行,等全部的依赖模块都加载好以后,进入回到函数逻辑,遇到require语句的时候,才执行对应的模块,这样模块的执行顺序就和咱们书写的时候一致了
CommonJS时运行时加载
,由于ComminJS加载是先加载整个模块,生成一个对象
(这个对象包含了path这个模块的全部API),而后再从这个对象上面读取方法-----运行时加载 ES6是编译时加载
,ES6模块不是对象
,它的对外接口只是一种静态定义,在代码静态定义阶段就会生成-----编译时加载
//ES6模块
import { basename, dirname, parse } from 'path';
//CommonJS模块
let { basename, dirname, parse } = require('path');
复制代码
以上这种写法与CommonJS的模块加载有什么不一样?
模块化
就是将系统分离成独立功能的模块,这样咱们须要什么功能,就加载什么功能。
模块化的优势
:
JS模块化发展产物:CommonJS(服务端)
=>AMD(浏览器)
=> CMD
=> ES6 Module模块化
CommonJs主要用在服务器端,AMD和CMD用在浏览器环境 AMD 是 RequireJS 在推广过程当中对模块定义的规范化产出。 CMD 是 SeaJS 在推广过程当中对模块定义的规范化产出。 ES6 规范只支持静态的导入和导出,与CommonJS 的运行时加载
不一样的是ES6是编译时加载
,ES Module 是在编译时期进行模块静态优化。
若是这篇文章帮到了你,记得点赞👍收藏加关注哦😊,但愿点赞多多多多...
文中若有错误,欢迎在评论区指正