JavaScript实现模块化
- AMD
- CMD
- CommonJs
- es6 module
AMD【依赖前置】
1 define(['package/lib'],function(lib){
2 function foo(){
3 lib.log("hello world");
4 };
5 return {
6 foo:foo
7 };
8 })
RequireJS:异步加载JS文件。
通过define()函数定义,第一个参数是一个数组,里面定义一些需要依赖的包;第二个参数是一个回调函数,通过变量来引用模块里面的方法,最后通过return来输出。采用异步方式加载模块,加载完成之后,回调函数才会运行。
CMD 【依赖就近】
CMD是SeaJS在推广过程中对模块定义的规范化产出。
1 //所有模块通过defined来定义
2 define(function(require,export,module){
3 //通过require引入依赖
4 var $=require('jqurey');
5 var spinning=require('./spinning');
6 })
CommonJs
- CommonJS是服务器端模块的规范,加载模块是同步的,也就是说,只有加载完成,才能执行后面的操作。
- Node.js采用了这个规范。Node.JS首先采用了js模块化的概念。根据CommonJS规范,一个单独的文件就是一个模块。每一个模块都是一个单独的作用域,也就是说,在该模块内部定义的变量,无法被其他模块读取,除非定义为global对象的属性。
- CommonJS模块的加载机制是,输入的是被输出的值的拷贝。也就是说,一旦输出一个值,模块内部的变化就影响不到这个值。
http://javascript.ruanyifeng.com/nodejs/module.html
es6 module
- 编译时加载
- 模块的加载机制是:值的引用
ES6 模块与 CommonJS 模块的差异
- CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用。
- CommonJS 模块输出的是值的拷贝,也就是说,一旦输出一个值,模块内部的变化就影响不到这个值。原始类型的值,会被缓存,除非写成一个函数,才能得到内部变动后的值;ESM 模块是动态引用,并且不会缓存值,动态地去被加载的模块取值,并且变量总是绑定其所在的模块
- CommonJS 模块是运行时加载,ESM 模块是编译时输出接口。
- CommonJS 模块的require()是同步加载模块,ESM 模块的import命令是异步加载,有一个独立的模块依赖的解析阶段。
- CommonJS 模块的顶层this指向当前模块;ESM 模块之中,顶层的this指向undefined.并且这些顶层变量不存在了:
- arguments
- require
- module
- exports
- __filename
- __dirname
参考资料