浅谈CommonJS规范
前端开发最初只需要使用JS实现一些基本的交互效果,所以早期一般在script标签中嵌入一些代码既可以达到要求。但随着各种WEB应用的兴起,JS的地位越来越重要,文件越来越复杂,一个项目里的文件势必要有良好的管理。模块化思想也就应运而生。
一个模块实际上就是管理一个特定功能的文件,当某个位置需要这个功能,我们就可以很方便的引入以达到复用和分治的目的。那么如何引入呢?这就需要一套规范来管理了。早期浏览器中没有官方定义的模块化规范,从AMD/CMD走来,目前已经可以拥抱ES6的模块化规范,再结合服务器端的Node.js的CommonJS规范与npm包管理,我们可以很方便的实现各种模块的调用与管理。今天我主要来谈谈Node.js采用的服务器端的模块化规范-CommonJS。
CommonJS概述
- Node搭建的后台都是由模块组成,所有模块都有自己的作用域
- 每个模块都有个module变量代表当前模块,导入和导出由exports和require方法实现
- 模块为同步加载。有缓存机制,只会在第一次加载时运行一次
module属性介绍
1. module.id
通常是带有绝对路径的模块文件名
2.module.filename
带有绝对路径的模块文件名
3.module.loaded
布尔值,表示模块是否加载完成
4.module.parent
对象,表示调用该对象的模块。如果在命令行下调用则为undefined,如果在脚本中调用,则为调用它的模块
5.module.children
数组,表示该模块require的模块
6.module.exports
表示对外输出的接口,node模块中存在一个exports指针指向该接口,可以通过给exports添加属性改变接口的输出,也可以重新传值切断指针和接口的联系。
require命令
基本功能
读入并执行一个JavaScript文件,然后返回module.exports。也可以读入一个JSON文件并返回。
路径规则
- 参数以"/"开头则表示加载一个绝对路径文件
- 参数以"./"开头则表示从同一目录开始查询加载一个相对路径文件
- 参数以"../"开头则表示从上级目录开始查询加载一个相对路径文件
- 参数不以"/"或"./"开头则表示加载全局或局部安装的默认核心模块
- 参数为不以"./"或"/"开头的路径时则先找到开头文件位置再进行后续查找
- 如果想得到require命令加载的确切文件名则使用require.resolve()方法
加载机制
- 输入的值是被输出的值的快照,即使原模块的值发生改变,加载模块的值也不会变化
- 模块可以调用加载也可以直接加载,当直接加载时require.main返回module
- require和exports类似,只是一个指向module.require方法的指针,后者通过调用module.load()真正的加载指定文件。加载之前会检查module.cache属性来决定是取出缓存或是直接加载,require.cache属性可以检查缓存模块。
解析模块顺序
require命令会根据相对路径还是绝对路径做出不同的行为。
相对路径
- 检查该路径下文件是否存在。
- 检查该路径下以该文件命名的目录是否存在包含有package.json文件,且指定了main模块。
- 若未指定main模块,则检查名称为index.js的文件是否存在。
非相对路径
- 检查当前目录下名为node_modules的文件夹下是否存在。
- 同理检查package.json的main模块。
- 同检查index.js。
- 递归的向上层文件夹中重复1~3步查询,直到root文件夹。
-- EOF --