CommonJS、requirejs、ES6的Modules

 

CommonJS

CommonJs模块输出的是值的拷贝,也就是说,一旦输出一个值,模块内部的变化不会影响到这个值。

CommonJS是nodejs也就是服务器端广泛使用的模块化机制。

该规范的主要内容是,模块必须通过module.exports 导出对外的变量或接口,通过 require() 来导入其他模块的输出到当前模块作用域中。

 

// common.js
var count = 1;

var printCount = () =>{ 
   return ++count;
}

module.exports = {
     printCount: printCount,
     count: count
};
 // index.js
let v = require('./common');
console.log(v.count); // 1
console.log(v.printCount()); // 2
console.log(v.count); // 1

 

你可以看到明明common.js里面改变了count,但是输出的结果还是原来的。这是因为count是一个原始类型的值,会被缓存。除非写成一个函数,才能得到内部变动的值。将common.js里面的

对于基本数据类型,属于复制。即会被模块缓存。同时,在另一个模块可以对该模块输出的变量重新赋值。

对于复杂数据类型,属于浅拷贝。由于两个模块引用的对象指向同一个内存空间,因此对该模块的值做修改时会影响另一个模块。

当使用require命令加载某个模块时,就会运行整个模块的代码。

当使用require命令加载同一个模块时,不会再执行该模块,而是取到缓存之中的值。也就是说,commonjs模块无论加载多少次,都只会在第一次加载时运行一次,以后再加载,就返回第一次运行的结果,除非手动清除系统缓存。

循环加载时,属于加载时执行。即脚本代码在require的时候,就会全部执行。一旦出现某个模块被"循环加载",就只输出已经执行的部分,还未执行的部分不会输出。

对于基本数据类型,属于复制。即会被模块缓存。同时,在另一个模块可以对该模块输出的变量重新赋值。
 
module.exports 改写成
module.exports = {
     printCount: printCount,
     get count(){
         return count
     }
};
这样子的输出结果是 1,2,2

 

CommonJS模块规范主要分为三部分:模块引用、模块定义、模块标识。

1、模块标识

模块标识指的是传递给require方法的参数,必须是符合小驼峰命名的字符串,或者以 . 、… 、开头的相对路径,或者绝对路径。

 

CommonJS模块规范的好处

CommonJS模块规范很好地解决变量污染问题,每个模块具有独立空间,互不干扰,命名空间等方案与之相比相形见绌。

CommonJS规范定义模块十分简单,接口十分简洁。

CommonJS模块规范支持引入和导出功能,这样可以顺畅地连接各个模块,实现彼此间的依赖关系。

 

 

 

 

AMD

AMD(异步模块定义)是为浏览器环境设计的,因为 CommonJS 模块系统是同步加载的,当前浏览器环境还没有准备好同步加载模块的条件。

requirejs即为遵循AMD规范的模块化工具。 

RequireJS的基本思想是,通过define方法,将代码定义为模块;通过require方法,实现代码的模块加载。

 

 

 

 

ES6 Modules



而在ES6当中,写法是这样的,是利用export 和import导入的

// es6.js
export let count = 1;
export function printCount() {
     ++count;
}
// main1.js
import  { count, printCount } from './es6';
console.log(count)
console.log(printCount());
console.log(count)
ES6模块是动态引用,并且不会缓存,模块里面的便令绑定其所在的模块,而是动态地去加载值,并且不能重新赋值

对于只读来说,即不允许修改引入变量的值,import的变量是只读的,不论是基本数据类型还是复杂数据类型。当模块遇到import命令时,就会生成一个只读引用。等到脚本真正执行时,再根据这个只读引用,到被加载的那个模块里面去取值。

对于动态来说,原始值发生变化,import加载的值也会发生变化。不论是基本数据类型还是复杂数据类型。

循环加载时,ES6模块是动态引用。只要两个模块之间存在某个引用,代码就能够执行。

 



另外还想说一个export default

模块的默认值是使用 default 关键字所指定的单个变量、函数或类,而你在每个模块中只能设置一个默认导出。
let count = 1;
function printCount() {
     ++count;
} 
export
default { count, printCount} // main3.js import res form './main3.js' console.log(res.count)

 

 

CMD

CMD是SeaJS 在推广过程中对模块定义的规范化产出

 

 

总结:

commonJS 模块

commonJS的模块规范在Node中发扬光大,总的来说,它的特性有这几个:

1.动态加载模块
commonJS和es6的最大区别大概就在于此了吧,commonJS模块的动态加载能够很轻松的实现懒加载,优化用户体验。

2.加载整个模块
commonJS模块中,导出的是整个模块。

3.每个模块皆为对象
commonJS模块都被视作一个对象。

4.值拷贝
commonJS的模块输出和 函数的值传递相似,都是值的拷贝

es6 模块
1.静态解析
即在解析阶段就确定输出的模块,所以es6模块的import一般写在被引入文件的开头。

2.模块不是对象
在es6里,每个模块并不会当做一个对象看待

3.加载的不是整个模块
在es6模块中经常会看见一个模块中有好几个export 导出

4.模块的引用
es6模块中,导出的并不是模块的值拷贝,而是这个模块的引用

posted @ 2020-05-31 18:11  清明|雨上  阅读(289)  评论(0)    收藏  举报