1.javascript存在几个缺陷:
没有模块系统
标准库较少
没有标准接口
缺乏包管理系统
commonjs的出现时为了实现js到处运行的可能。
Node与浏览器以及W3C组织,CommonJS组织,ECMAScript之间的关系,共同构成一个繁荣的生态,如下图:
CommonJS规定的模块引用:var math =require('math');
模块的定义:
模块标识:
就是传递给require方法的参数,它必须是符合小驼峰命名的字符串,或者以.、..开头的相对路径或者绝对路径,可以没有文件的后缀名js
CommonJS构建的这套导入到处机制使得用户完全不用考虑变量污染,相比命名空间要好的多。
2.Node模块实现
在node中引入模块,经历如下3个步骤:
路径分析->文件定位->编译执行
node中的模块:node提供的模块称为核心模块;用户编写的模块称为文件模块。
部分核心模块在node进程启动时已经直接加载进内存,所以,文件定位和编译执行这两个步骤不需要,相比普通用户编写的文件模块要经历的三个过程,必然要快很多。
2.1 优先从缓存加载
node对引入过的模块都会进行缓存,减少二次引入的开销。浏览器只能缓存文件,而node缓存的时编译和执行后的对象。核心模块的缓存检查优先于文件模块的缓存检查。
2.2 路径分析和文件定位
2.2.1模块标识符分析
模块标识符在node中主要分为以下几类:核心模块,如http,fs,path等
.或..开始的相对路径文件模块
以/开始的绝对路径文件模块
非路径形式的文件模块,如自定义的connect模块
核心模块
核心模块的优先级仅次于缓存,所以,想加载一个与核心模块相同标识的用户模块是不会成功的,必须把用户模块标识符变更为与核心模块不同才可以加载成功。
路径形式的文件模块
以.或者..或者/开始的路径,最终都会转换为真实路径,并以真实路径作为索引放入缓存,来让二次加载更快。但仍然会慢于核心模块。
自定义模块
查找顺序:
当前文件目录下的node_module
父目录下的node_module
父目录的父目录下的node_module
逐级递归,直到根目录下的node_modules目录
2.2.2 文件定位
CommonJS规范规定,在标识符中可以不包括文件扩展名,node会按照.js,.json,.node的次序补足扩展名,并依次尝试。
2.2.3 模块编译
exports和module.exports的区别
2.6 包与npm
包组织模块示意图:
2.6.1 包结构
完全符合CommonJS规范的包目录应该包含如下文件:
package.json:包描述文件
bin:用于存放可执行二进制文件的目录
lib:用于存放javascript代码的目录
doc:用于存放文档的目录
test:用于存放单元测试用例的代码
2.6.3 npm常用功能
npm -v 查看当前npm版本
npm install 模块 -g
-g表示全局安装,其实意思是讲一个包安装为全局可用的执行那个命令。
console.log(path.resolve(process.execPath,'..','..','lib','node_modules'))
这个目录就是可执行文件链接到node下的可执行目录
从本地安装: npm install url/folder
从非官方源安装: npm install 模块 --registry=http://registry.url
如果想完全用这个非官方的源,可以执行:npm config set registry http://registry.url
package.json中scripts 的
就是 包在 者 过程中 机 , 下
"scripts": {
"preinstall": "preinstall.js",
"install": "install.js",
"uninstall": "uninstall.js",
"test": "test.js"
}
在以上 中 npm install 时,preinstall 指向的脚本会被夹在执行 , 然后,install指向的脚本会被执行,在 npm uninstall 时,uninstall 的脚本也会执行一些清理工作。
关于发布包的文章,有专门的一片文章介绍,可以去查看。
npm仓库支持混搭,可以企业仓库和开源公共仓库同时使用。
好npm包的几大特点:
具备良好的测试
具备良好的文档
具备良好的测试覆盖率
具备良好个的编码规范
。。。。
网友评论