NodeJS NPM和包

555 阅读6分钟

包组织模块示意图

image.png

CommonJS 的包规范

  • 包结构

    • 用于组织包中的各种文件
  • 包描述

    • 用于描述包的相关信息,以供外部读取分析

包结构

包实际上是一个存档文件,即一个目录直接打包为.zip或者tar.gz格式的文件,安装后解压还原为目录。

完全符合CommonJS规范的包目录应该包含:

  • package.json:包描述文件

  • bin:用于存放可执行二进制文件的目录

  • lib:用于存放JavaScript代码的目录

  • doc:用于存放文档的目录

  • test:用于存放单元测试用例的代码

包描述文件与npm

包描述文件用于表达非代码相关的信息,它是JSON格式的文件 ----- package.json, 位于包的根目录下,是包的重要组成部分。

CommonJS为package.json文件定义了如下必须的字段:

  • name 包名
    • 小写的字母和数字组成
    • 可以包含.、_和-,但不允许出现空格
    • 包名必须唯一
  • description 包简介
  • version 版本号
  • keywords 关键字数组,NPM中主要用来做分类搜索
  • maintariners 包维护者列表
    • 每个维护者由 name、email、web 3个属性组成
"maintainers":[{"name":"TaoFenG", "email":"as.fengtao@gmail.com", "url":"http://fengtao.site"}]
  • contributors 贡献者列表

    • 列表欧中第一个贡献者应当是包作者本人
    • 格式与维护者列表相同
  • bugs 一个可以反馈bug的网页地址或邮件地址

  • licenses 当前包所使用的许可证列表,表示这个包可以在哪些许可证下使用

  • respositories 托管源代码的位置列表,表明可以通过哪些方式或地址访问包的源代码

  • dependencies 使用当前包所需以来的包列表

  • homepage 当前包的网站地址

  • os 操作系统支持列表

  • cpu cpu 架构的支持列表

  • engine 支持javascript引擎列表 - v8 - spidermonkey

  • builtin 标志当前包是否是内建在底层系统的标准组件

  • directories 包目录说明

  • implements 实现规范的列表

  • scripts 脚本说明对象 - 主要被包管理器用来安装、编译、测试、和卸载包

NPM 字段

NPM 实际需要的字段主要有 name、 version、 description、 keywords、 repositories、 author、 bin、 main、 scripts、 engines、 dependencies、 devDependencies。

与包规范的区别在于多了author、bin、main和devDependencies这4个字段

author 包作者

bin 一些包作者希望包可以作为命令行工具使用, 配置好bin字段后, 通过 npm install package_name -g 命令,可以通过脚本添加到执行路径中,之后可以在命令行中直接执行。

main 模块引入方法 require() 在引入包时,会有限检查这个字段,并将其作为包中其余模块的入口。如果不存在字段,默认为index

devDependencies 一些模块只在开发时需要依赖。配置这个属性,可以提示包的后续开发者安装依赖包。

NPM 的常用功能

查看帮助:

npm -v    查看npm版本信息
npm       查看帮助引导
npm help <command> 查看具体的命令说明

安装依赖包:

npm install express
    - 执行该命令, npm 会在当前目录下创建 node_modules目录, 然后在 node_modules目录下创建 express目录,接着解压到这个目录下
    - 安装好依赖包后,可以在代码中调用 require('express') 即可引入该包。
    
npm install express -g 
    - 进行全局模式安装
    - 全局模式并不是将一个模块包安装为一个全局包的意思,并不意味着可以从任何地方通过 require() 来引用它。
    - -g 是将包安装为全局可用的可执行命令
    - 它根据包描述文件中的bin字段配置,将实际脚本链接到与Node可执行问价你想通的路径下
    
    - 通过全局模式安装的所有模块包都被安装进了统一的目录, 这个目录可以通过如下方式推算。
    path.resolve(process.execPath, '..', '..', 'lib', 'node_modules')
    
    - 如果Node的可执行文件的位置是 /usr/local/bin/node,那么模块目录就是 /usr/local/lib/node_modules, 最后通过软连接的方式将 bin字段配置的可执行文件链接到Node的可执行目录下

本地安装:

没有发布到npm上的包,或是因为网络原因导致无法直接安装的包,可以通过将包下载到本地,然后进行本地安装。 本地安装主需要为NPM指明package.json文件即可:可以使一个包含package.json的存档文件,也可以是一个URL地址,也可以是一个目录下有package.json文件的目录位置。

npm install <tarball file>
npm install <tarball url>
npm install <folder>

从非官方源安装:

 npm install underscore --registry=http://registry.url

如果使用过程中几乎都采用镜像源安装,设置默认源:
npm config set registry http://registry.url

NPM 钩子命令:

package.json 中 scripts 字段的提出就是让包在安装或卸载等过程中提供钩子机制。
"scripts": {
    "preinstall":"preinstall.js",
    "install":"install.js",
    "uninstall":"uninstall.js",
    "test":"test.js"
}

在执行 npm install <package> 时,preinstall 指向的脚本将本加载执行,install指向的脚本会被执行。
在执行 npm uninstall <package> 时,uninstall 指向的脚本会执行。

当在一个具体的包目录下执行 npm test 时, 将会运行 test执行的脚本。

发布包:

 编写模块:
 sayHello为例:
 
    exports.sayHello = function() {
        return 'Hellow world.';
    };
将代码保存为 hello.js 

初始化包描述文件:

package.json 文件的内容尽管相对较多,但实际发布一个包时并不需要一行一行的编写。 NPM 提供了 NPM init 命令会帮助我们生成 package.json 文件。

npm init 

NPM通过提问式的交互逐个填入选项, 最后生成预览的包描述文件。满意输入yes.会自动生成 package.json 文件。

注册包仓库账号:

为了维护包, NPM必须要使用仓库账号才允许将包发布到仓库中。 
注册账号的命令是 npm adduser, 也是一个提问式交互过程。

上传包:

上传包的命令是 npm publist <folder>
在刚刚创建的 package.json 文件所在的目录下, 执行 npm publist . 开始上传包

安装包:

体验和测试自己上传的包, 更换一个目录,并运行命令:
    npm install package_name 进行安装

管理包权限:

通常一个包只有一个人拥有权限进行发布,如果需要多人进行发布,使用 npm owner 命令管理包的所有者:

npm owner ls eventproxy

npm http GET https://registry.npmjs.org/eventproxy
npm http 200 https://registry.npmjs.org/eventproxy
TaoFenG <as.fengtao@gmail.com>

npm owner ls <package name>
npm owner add <user> <package name>
npm ownere rm <user> <package name>

分析包:

npm ls 分析包
分析出当前路径下能够通过模块路径找到的所有包,并生成依赖树。

一个优秀的模块应该具备哪些内容

  • 具备良好的测试
  • 具备良好的文档 (README、API)
  • 具备良好的测试覆盖率
  • 具备良好的编码规范
  • 更多条件