from:https://www.jianshu.com/p/09ffac7a3b2cnode
随着JS模块化编程的发展,处理模块之间的依赖关系成为了维护的关键。npm
AMD,CMD,CommonJS是目前最经常使用的三种模块化书写规范。编程
CommonJS规范是诞生比较早的。NodeJS就采用了CommonJS。是这样加载模块:json
var clock = require('clock'); clock.start();
这种写法适合服务端,由于在服务器读取模块都是在本地磁盘,加载速度很快。可是若是在客户端,加载模块的时候有可能出现“假死”情况。好比上面的例子中clock的调用必须等待clock.js请求成功,加载完毕。那么,能不能异步加载模块呢?数组
一、CommonJs规范的出发点:JS没有模块系统、标准库较少、缺少包管理工具;为了让JS能够在任何地方运行,以达到Java、C#、PHP这些后台语言具有开发大型应用的能力;缓存
二、在CommonJs规范中:服务器
一个文件就是一个模块,拥有单独的做用域;异步
普通方式定义的变量、函数、对象都属于该模块内;模块化
经过require来加载模块;函数
经过exports和modul.exports来暴露模块中的内容;
三、全部代码都运行在模块做用域,不会污染全局做用域;模块能够屡次加载,但只会在第一次加载的时候运行一次,而后运行结果就被缓存了,之后再加载,就直接读取缓存结果;模块的加载顺序,按照代码的出现顺序是同步加载的;
四、__dirname表明当前模块文件所在的文件夹路径,__filename表明当前模块文件所在的文件夹路径+文件名;
五、require(同步加载)基本功能:读取并执行一个JS文件,而后返回该模块的exports对象,若是没有发现指定模块会报错;
六、模块内的exports:为了方便,node为每一个模块提供一个exports变量,其指向module.exports,至关于在模块头部加了这句话:var exports = module.exports,在对外输出时,能够给exports对象添加方法,PS:不能直接赋值(由于这样就切断了exports和module.exports的联系);
七、npm root -g:查看npm全局包安装位置,建议在nvm目录下新建npm\node_modules目录,而后设置npm的全局包安装位置:npm config set prefix "",而后将该路径添加到环境变量中;
八、npm init -y:初始化一个package.json文件,加上-y就会默认生成该文件,无需一步一步填写;npm docs 包名:查看包的文档;npm install:安装package.json中dependencies属性中全部依赖的包
九、因为npm的服务器是国外的,因此若是你没有和谐工具是下载不了的,这里推荐使用淘宝NPM镜像:http://npm.taobao.org/,与官方NPM的同步频率目前为10分钟一次;安装命令:npm install -g cnpm --registry=https://registry.npm.taobao.org,安装包:cnpm install 包名(其它命令基本一致);
十、若是你不想下载cnpm,npm还提供了一个镜像源管理工具:npm install -g nrm,经过:nrm ls,查看镜像源列表 ,经过:npm use 镜像源,来切换;
十一、NPM的模块加载机制:
若是require的是绝对路径文件,查找不会去遍历每一个node_modules目录,其速度最快
1).从module.paths数组中(由当前执行文件目录到磁盘根目录)取出第一个目录做为查找基准
2).直接从目录中查找该文件,若是存在则结束查找,若是不存在则进行下一条查找
3).尝试添加.js、.node、.json后缀以后查找,若是存在文件则结束查找,若是不存在则进行下一条查找
4).尝试将require的参数做为一个包来进行查找,读取目录下的package.json文件,取得Main参数指定的文件
5).尝试查找该文件,若是存在则结束查找,若是不存在则进行第3条查找
6).若是继续失败,则取出module.paths数组中的下一目录做为基准查找,循环第1-5个步骤
7).若是继续失败,循环第1-6个步骤,直到module.paths中的最后一个值
8).若是继续失败,则抛出异常
AMD,即 (Asynchronous Module Definition),这种规范是异步的加载模块,requireJs应用了这一规范。先定义全部依赖,而后在加载完成后的回调函数中执行:
require([module], callback);
用AMD写上一个模块:
require(['clock'],function(clock){ clock.start(); });
AMD虽然实现了异步加载,可是开始就把全部依赖写出来是不符合书写的逻辑顺序的,能不能像commonJS那样用的时候再require,并且还支持异步加载后再执行呢?
CMD (Common Module Definition), 是seajs推崇的规范,CMD则是依赖就近,用的时候再require。它写起来是这样的:
define(function(require, exports, module) { var clock = require('clock'); clock.start(); });
AMD和CMD最大的区别是对依赖模块的执行时机处理不一样,而不是加载的时机或者方式不一样,两者皆为异步加载模块。
AMD依赖前置,js能够方便知道依赖模块是谁,当即加载;而CMD就近依赖,须要使用把模块变为字符串解析一遍才知道依赖了那些模块,这也是不少人诟病CMD的一点,牺牲性能来带来开发的便利性,实际上解析模块用的时间短到能够忽略。
以上就是三者的异同,若有疑问或建议,请参考如下文章或联系我,谢谢。
</br></br>
做者:乘着风连接:https://www.jianshu.com/p/09ffac7a3b2c來源:简书著做权归做者全部。商业转载请联系做者得到受权,非商业转载请注明出处。