commonJs模块
不久前,看到火狐在5月份将宣布支持js模块化,即会引入import,export方法。我自己一直都没有用过模块化的插件,比如commonJs,AMD,CMD,这些库的概念倒是都讲的是模块化操作,也就是模块化的编程。因为webpack具有这些插件的所有功能,并且更加强大,所以没有去了解这些插件库,其实webpack是怎样模块化的,我也搞不清楚,都是按照命令行操作,内部的实现没去弄学习,也没研究源码。
模块化的好处:
功能的复用,写好的功能,可以直接通过模块引入,文件划分也清楚明了。
大文件可以拆分为很多个模块,便于管理和维护。
以前需要某个js插件的功能,就用script标签加载这个js 文件,有的时候就会加载很多个文件。script标签的加载是同步的,浏览器会停止渲染,同步加载这些js文件,这样会增加浏览器的响应时间。
多个文件的命名冲突,全局变量的污染。
以前解决变量命名冲突的方法有,使用闭包,使用对象命名空间。
CommonJS 模块,nodejs用的这个规范
模块定义导出
通过exports 或modules.exports导出模块,也就是定义模块。注意es6用的是export,不能直接给exports赋值,并且es6有 export {...} ,node里不可以 exports {...};切记不能弄混了。
在上面的例子中 ,exports 指向的就是module.exports;当使用模块化的时候,就已经声明 var expoets = module.exports = {};其中module指的就是当前的模块。打印出module就可以看到
exports 是node 提供的一个变量指向module.exports,用来收集一些属性最后赋值给module.exports .这样一来,当我们在exports里导出变量a,再用module.exports 导出变量a,最后的结果是moudle.exports 的变量a.总之模块最终调用额是module.exports。
模块的分类,有两种模块
一类为原生模块,例如http、path,加载的时候不用指明路径直接加载,速度很快。
一类为文件模块,动态加载的模块,也就是需要导入或是自己写。引入的时候需要指定模块的路径
这两种模块加载的时候都会被缓存,也就是说第一次引用会加载,在引用的时候就会取缓存里的。
模块的加载机制————模块的引用规则
node的加载流程
找目录下的文件名,然后加上扩展名称,依次按照“ .js .node .json”查找,.node 和.json文件加上后缀名会快些。
已上面的a.js 为例, 当找到a.js,首先读取内容包上一层function,避免暴露于全局中,这个function闭包有五个参数:exports,require,module,_filename,\_dirname_
这就为什么在可以在js文件里直接用 require ,exports ,module,__dirname,__filename.
node是读取缓存的,可以用如下的图来描述:
CommonJs规范比较适合服务器端,浏览启端的需要异步加载,所以就有了CMD、AMD规范。
注意当导出一个模块的变量时,是对这个模块变量的缓存复制,也就是说模块块内的变量发生改变时,不影响导出的变量,读取的是缓存里的。这一点与es6的模块机制不同。
Last updated