NPM指南
文章目录
npm 全称:Node Package Manager (Node 包管理器),目前是Web前端开发重要依赖工具之一。安装Node.js默认会安装npm,前端各种资源都可以通过一个npm命令下载到自己的本地计算机上。
用户通过一个命令将npm上发布的包下载自己本地计算机并在项目中使用,也可以将自己的包发布到npm上供全球Web前端开发者下载使用。
npm的出现极大提升了前端开发体验。
npm 命令
npm help
1 | npm help <command> |
通过该命令可以帮助我们快速查看具体npm
命令的用途。
npm help -l
可以查看所有所有npm
命令
npm init
npm
包必须有个 package.json
文件,通过npm init
可以让自动在目录下创建一个package.json
文件,命令行会弹出几个问题用于填充package.json
。如果你想快速跳过可以使用npm init -y
命令。
npm install
npm install
用于将依赖的包下载到本地node_modules
目录中
npm install <package name>
可以是注册在npm服务上的包,也可以是Github上一个具体项目地址。
1 | $ npm install express |
npm
安装的包会记录在package.json
文件中。
package.json
文件有两种记录安装包的方式:生产依赖(dependencies
)和开发依赖(devDependencies
)。
1 | "dependencies": { |
1 | "devDependencies": { |
npm install <packagename>
安装默认是生产依赖,也可以使用npm install -save <packagename>
或npm install -S <packagename>
开发依赖的安装命令是:npm install -save-dev <packagename>
或npm install -D <packagename>
npm ci
npm ci
功能和npm install
命令作用一样,它比npm install
安装更快,因为它会跳过一些面向用户的操作,它的安装比npm install
更严格,它可以帮助捕获由大多数npm用户的增量安装的本地环境引起的错误或不一致。
npm ci
和npm install
区别有:
- 安装前目录必须存在
package-lock.json
或npm-shrinkwrap.json
。 - 如果
package-lock.json
包中锁定的包版本和package.json
中包版本不一致,则npm ci
将提示错误并提示错误。 npm ci
只能整项目依赖包的安装,不能安装单个依赖包。- 如果
node_modules
目录存在,在npm ci
安装前会移除node_modules
目录。 - 它不会对
package.json
和任何锁定包版本的文件进行操作。
npm ci
一般在自动话环境中使用,例如:测试平台,持续化集成,部署。
npm update
npm update
用于更新本地依赖包。它会先查询远程服务器最新包的版本,再与本地版本进行比较,如果远程版本更新并符合本地版本安装规,它就将本地依赖包更新到最新版本。
npm update
更新时,添加参数-S
或-D
。它会将package.json
中的版本号更新。
npm dist-tag
npm dist-tag
是管理包标签指令
1 | $ npm dist-tag add <pkg>@<version> [<tag>] |
add
:使用给指定的包版本设定标签rm
:将包中不需要的标签移除ls
:将包的所有标签展示出来
在安装包时,可以通过设定标签名称下载指定版本的包
1 | $ npm install <name>@<tag> |
npm config
npm config
命令用于管理npm
包管理文件
1 | $ npm config set <key> <value> [-g|--global] |
用的最多的npm config
命令是npm config set registry https://registry.npm.taobao.org
npm version
你还在手动更新package.json
中的版本号嘛?现在一个npm version xxx
命令就可以搞定了。它会将你设置的版本号写入package.json
文件中。
npm
包版本号的规则是:重大版本号.功能版本号.修复优化版本号
npm outdated
此命令将检查注册表,查看是否有安装的包已过时
1 | npm outdated [[<@scope>/]<pkg> ...] |
如果不指定pkg,则检查所有过期的包;若指定pkg,则检查指定的pkg。\
- wanted 显示符合semver规范的最大版本号。若没有多余版本号,则显示当前版本。
- latest 显示注册表中被标记为latest的版本。默认情况下latest标记表示最新版本,特殊情况下不是,这取决于开发人员的包管理制度。
- location 显示包在依赖关系树中的位置。请注意,npm outdated默认depth为0,仅看到过期包的顶级依赖项。
- package 显示包名。若使用了(–long/-l)则还是显示这个包属于dependencies还是devDependency。
1 | npm outdated --depth=1 // 显示依赖关系树最大深度,默认是 0 |
npm ls
用于查询工程或全局已安装的npm包依赖树。
可以设定 包名查看 安装情况。
1 | npm ls [[<@scope>/]<pkg> ...] |
可以通过--depth n
指定层级
npm view
打印指定包的信息.
1 | npm view [<@scope>/]<name>[@<version>] [<field>[.<subfield>]...] |
package.json
每个npm
包根目录下都会有一个package.json
文件,该文件含有包的所有重要信息,例如:包名,版本号,许可协议等。
name
name
表示该项目的名称,它的命名规则是限制的:
- 名称长度必须小于214个字节
- 不能以
.
和_
下划线开头 - 不能包含大些字母
name
会成为URL的一部分,所以不能包含非法的URL字符
npm
官方给了一些命名的建议:
- 不要使用和node.js模块相同的名称
- 名称中主要包含
js
,node
字符串 - 名称也许会被写入require参数中,所以最好取个简单有意义的名称
- 创建一个名称前先到https://www.npmjs.com/查询下该名称是否已经被使用
version
如果你计划发布你的npm
包,你必须要确保在package.json
文件中定义了name
和version
字段。
name
和package
字段是包的唯一性标志,包的区分就是依靠name
和package
字段。
version
字段定义当前包的版本号,版本号的命名规则是:重大版本号.功能版本号.修复优化版本号
发布稳定版本
1 | # 更新版本号(major | minor | patch | premajor | preminor | prepatch | prerelease) |
预发布版本
1 | # 发布一个 prelease 版本,tag=beta |
description
description
字段描述包的一些信息,可以方便用户通过npm search
搜索到你的npm
包
homepage
homepage
字段声明包的主页地址
license
license
字段定义你的包使用的许可证,不同的许可证定义了你的包使用范围和用途。https://spdx.org/licenses/可以看到所有许可证和它的详细说明
main
main
定义了包入口的文件,通过require()
引入你的包时,包管理器会将main
中定义的文件引入进去。main
默认入口文件名是index.js
dependencies
dependencies
字段用于定义项目运行所依赖的库。它定义为一个对象,key
表示包名称,value
是包的版本号。
依赖包的版本号定义有四种形式:
- 指定固定的版本:
1.2.0
- 波浪号+指定版本号:
~1.2.0
它表示安装1.2.x
最新的版本,不低于1.2.0
,但不安装1.3.0
。安装时不改变大版本号和次要版本号 - 插入号+指定版本包:
^1.2.0
,它表示安装1.x.x
最新的版本,不安装2.x.x
版本,也就是不改变大版本号。但是如果大版本号是0
,则它的意义和波浪号一样,它不改变次版本号。因为大版本号是0
说明该包还只是测试简单。 latest
: 安装最新的版本
devDependencies
devDependencies
字段定义开发是依赖的包,它表示项目运行时并不依赖的包。
peerDependencies
1 | 如果你安装我,那么你最好也安装X,Y和Z. |
有时候做一些插件开发,比如grunt等工具的插件,它们往往是在grunt的某个版本的基础上开发的,而在他们的代码中并不会出现require(“grunt”)这样的依赖,dependencies配置里边也不会写上grunt的依赖,为了说明此模块只能作为插件跑在宿主的某个版本范围下,可以配置peerDependencies:
1 | { |
上面这个配置确保再npm install的时候tea-latte会和2.x版本的tea一起安装,而且它们两个的依赖关系是同级的:
├── tea-latte@1.3.5
└── tea@2.2.0
这个配置的目的是让npm知道,如果要使用此插件模块,请确保在宿主环境按照了我需要的依赖包(peerDependencies中声明的包
)。
即使宿主环境并没有使用该依赖包,但还是会在它的node_modules中按照该依赖包.
npm2和npm3中peerDependencies的区别
正如上一节谈论的,在npm2中,PackageA包中peerDependencies所指定的依赖会随着npm install PackageA一起被强制安装,所以不需要在宿主环境的package.json文件中指定对PackageA中peerDependencies内容的依赖。
但是在npm3中,peerDependencies的表现与npm2不同:
npm3中不会再要求peerDependencies所指定的依赖包被强制安装,相反npm3会在安装结束后检查本次安装是否正确,如果不正确会给用户打印警告提示。
就拿上面的例子来说,如果我们npm install PackageA安装PackageA时,你会得到一个警告提示说:
PackageB是一个需要的依赖,但是没有被安装。
这时,你需要手动的在MyProject项目的package.json文件指定PackageB的依赖。
另外,在npm3的项目中,可能存在一个问题就是你所依赖的一个package包更新了它peerDependencies的版本,那么你可能也需要在项目的package.json文件中手动更新到正确的版本。
bundledDependencies
上面的单词少个d,写成bundleDependencies也可以。
指定发布的时候会被一起打包的模块。
optionalDependencies
如果一个依赖模块可以被使用, 同时你也希望在该模块找不到或无法获取时npm继续运行,你可以把这个模块依赖放到optionalDependencies配置中。这个配置的写法和dependencies的写法一样,不同的是这里边写的模块安装失败不会导致npm install失败。
1 | try { |
optionalDependencies 中的配置会覆盖dependencies中的配置,最好只在一个地方写。
config
用来设置一些项目不怎么变化的项目配置,例如port等。
用户用的时候可以使用如下用法:
1 | http.createServer(...).listen(process.env.npm_package_config_port) |
可以通过npm config set foo:port 80来修改config
1 | { |
npx
npx
用于执行npm
包的二进制脚本。
npx <command>
它会查找node_modules/.bin
目录对于的可执行二进制脚本。如果本地没有对于的可执行二进制脚本,它会去全局查找。如果全局也没有,它就会从远程仓库下载对应的npm
包。
1 | $ npm i -D webpack |
npm
5.2.0版本之后会默认安装npx
包。
有了npx
,对于需要执行的npm
包二进制命令,你不用将它写进scripts
或进行全局安装。
发布npm包
将包发布到npm
远程仓库非常简单,只需要三个步骤(确保你的包准备好了)。
npm adduser
注册一个npmjs.com的账号npm login
登录已有的账号npm publish
发布包(在包的根目录执行)
注意: 在发布前,你应该登录https://www.npmjs.com 看下自己的包名是否已经存在。
如果你的registry
指向其它镜像,你需要将它设定为https://registry.npmjs.com/
一个完整的npm
包,应该包括:
package.json
文件README.md
文件,说明包的用途和使用方式index.js
文件,包的入口文件tests
目录,单元测试文件目录
作者: Fynn
链接: https://fynn90.github.io/2018/11/18/npm%E6%8C%87%E5%8D%97/
本文采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可