vv13
博客Github

NPM 武功秘籍

依赖管理

应用依赖使用npm i,开发依赖使用npm i -D,这是人尽皆知的事情,但很多人也止步于此了,为了将它们更合理的应用起来,我们来分析一下几种不同dependencies的区别。

dependencies定义程序正常运行时所依赖的包,通过npm i即会安装所定义的依赖。

devDependencies用于定义测试编译也会通过npm i安装,但若使用npm i --production则不会安装其依赖。

peerDependencies通常用于定义插件形式的包,两者具备主从或同伴关系,这些插件在使用时一般都是基于特定版本的包,此时就可以在peerDependencies中进行限制。npm@1或npm@2会自动安装peerDependency内的包,而从npm@3开始,则会直接抛出错误,必须手动进行安装正确的版本。

依赖除了通过npm registroy进行查找,还能通过不同的形式进行安装:

  • Github地址,指定

全局包管理

当使用npm install -g安装包的时候,它去哪儿了呢?有几条命令可用于追踪:

  1. npm root -g,查看全局包的安装路径。
  2. npm list -g --depth 0,查看当前已安装的全局包。
  3. npm bin -g,查看npm可执行文件存放的路径。

命令缩写

当你熟练的使用npm命令以后,缩写能帮助人们节约不少时间,在此简单罗列一下常用的快捷参数,因为这总比你使用npm help或去官方文档搜索相关命令更节省时间:

  • npm i -> npm install

    • -D -> --save-dev,安装依赖到开发环境,即devDependencies.
    • -S,在npm5之前代表--save,现在此参数已被移除
    • -g -> --global,安装到全局包
  • npm un -> npm uninstall

对用npm init,我们也可以使用-y参数来使用默认配置避免手动回车确认。

npm-ci

npm install类似,npm ci主要用于安装项目依赖,它是一种更为快速、干净的方式,两者之间的区别为:

  • 工程项目中必须包含package-lock.json或npm-shrinkwrap.json。
  • npm ci一次只能安装整个工程的包,而不能进行单个包的安装。
  • 如果node_modules已经存在了,它会被自动移除掉。
  • 它不会改变package-locks或package.json,这些项在安装时是被冻结的。

package.json

publishConfig

若要频繁进行npm publish时会十分便捷,比如对scope包进行推送,npm默认推送行为是私有包,若没有进行付费注册私有库会推送失败,这时在每次推送时就应该使用:npm publish --access public,一劳永逸的办法是在package.json中加入:

  "publishConfig": {
    "access": "public"
  }

还有我们经常会修改.npmrc中的registry地址,通过换源提升依赖安装速度,但是这样在publish时也会默认使用换源地址,因此我们可以将官方仓库加入此配置里:

  "publishConfig": {
    "registry": "<http://registry.npmjs.org>"
  }

module

types

告诉Tpyescript和编辑器在哪里寻找类型定义。

npm全局管理

  • npm list -g --depth 0,查看全局安装了哪些npm包
  • npm root -g,查看全局node_modules路径
  • npm bin -g,查看全局可执行npm脚本存放的位置

当有了 nvm,就可以对全局包进行清除:

sudo rm -rf /usr/local/lib/node_modules #删除全局 node_modules 目录
sudo rm /usr/local/bin/node #删除 node
cd  /usr/local/bin && ls -l | grep "../lib/node_modules/" | awk '{print $9}'| xargs rm #删除全局 node 模块注册的软链

npmrc

npm会从以下以下源中读取配置信息,按优先级排序:

  1. 命令行标记,如--foo bar,表示参数foo的值为bar;--foo bar --bar则表示参数foo的值为bar,参数bar的值为true
  2. 环境变量,所有环境变量以npm_config_开头的都会被视作配置参数,它是不区分大小写的,

优化node_modules的体积

版本管理

node遵守semver语义化版本管理,并使用node-semver来解析版本号,简单来说,基于npm管理的版本格式为:主版本号.次版本号.修订号,版本号的递增规则如下:

  1. 主版本号:当你做了不兼容的 API 修改。
  2. 次版本号:当你做了向下兼容的功能性新增。
  3. 修订号:当你做了向下兼容的问题修正。

先行版本号与编译元数据

除了以上三种格式,修订号后还可以加上先行版本号与编辑元数据。

先行版本号可以(MAY)被标注在修订版之后,先加上一个连接号再加上一连串以句点分隔的标识符来修饰。标识符必须(MUST)由 ASCII 字母数字和连接号 [0-9A-Za-z-] 组成,且禁止(MUST NOT)留白。数字型的标识符禁止(MUST NOT)在前方补零。先行版的优先级低于相关联的标准版本。被标上先行版本号则表示这个版本并非稳定而且可能无法满足预期的兼容性需求。范例:1.0.0-alpha、1.0.0-alpha.1、1.0.0-0.3.7、1.0.0-x.7.z.92。

通常先行版本号的常用标识为:

  • alpha,通常指内部测试版,一般不会向外部发布,会存有Bug,公测试人员使用
  • beta,也是测试版本,这个版本还会加入新的功能
  • rc,正式环境候选版本,这个版本不会加入新的功能,着重与拍错

版本编译元数据可以(MAY)被标注在修订版或先行版本号之后,先加上一个加号再加上一连串以句点分隔的标识符来修饰。标识符必须(MUST)由 ASCII 字母数字和连接号 [0-9A-Za-z-] 组成,且禁止(MUST NOT)留白。当判断版本的优先层级时,版本编译元数据可(SHOULD)被忽略。因此当两个版本只有在版本编译元数据有差别时,属于相同的优先层级。范例:1.0.0-alpha+001、1.0.0+20130313144700、1.0.0-beta+exp.sha.5114f85。