🗒️使用 npm
来自官网 https://docs.npmjs.com/
npm 是一个 software registry(软件注册中心)。
npm 有三个组件:
website:发现 packages,设置 profiles(配置文件),管理 npm 的其它方面
command-line interface, CLI, 命令行界面:大多数开发者和 npm 的交互方式
registry:一个大型公共 database,关于 JavaScript 软件及其元信息
npm 可以:
管理代码所需要的 packages
下载可以立即使用的独立工具
运行 package 而不用下载它,使用 npx
管理代码及其依赖的多个版本
管理代码的开发权限、创建组织和虚拟团队
...
1. 入门
1.1 创建 account
创建一个 npm user account,以便在 public registry(公共注册表)上共享和下载 Javascript packages。
npm login
:在网页上注册成功之后,可以使用该命令测试登录下此时需要输入 username, password, email address
若启用了 two-factor authentication,则还需要再输入一次性密码
npm whoami
:测试是否登录成功
1.2 安装 npm
使用 CLI 安装 npm。
安装 Node.js 时,会自动安装 npm。
然而考虑到 npm 的发布频率要高于 Node.js,所以建议安装 npm 的最新稳定版本,命令如下:
1.3 故障排除
详见 Getting started / Troubleshooting
2. packages 和 modules
public npm registry(注册表)是一个关于 JavaScript packages(包括软件和元数据)的 database。开发人员可以使用 npm registry 贡献 packages,这样其他人就能在自己的项目中下载和使用这些 packages 了。
npm registry 包含 packages,其中很多 packages 也是 Node modules 或包含 Node modules。
为了解析 package 的 name 和 version,npm 和一个 registry website(注册网站)进行对话,该网站实现了 CommonJS Package Registry 规范以读取 package 的信息。详见 npm CLI / Using npm / Registry:JavaScript Package Registry(注册表)。
2.1 packages
package 就是一个由 package.json
描述的文件或文件夹。package 必须包含 package.json
文件才能被发布到 npm registry(注册表)。
packages 可以是 unscoped(不限定范围的)也可以是 scoped(限定范围的)。scoped packages 可以是 private 也可以是 public。
package formats 可以是以下之一:
一个包含代码的文件夹,由
package.json
文件描述包含 (1) 的 gzipped tarball(压缩包)
解析为 (2) 的 URL
使用 (3) 在 registry 上发布的
<name>@<version>
指向 (4) 的
<name>@<tag>
满足 (5) 的
<name>@latest
一个 git url,被 cloned 了之后就是 (1)
git URL 的格式可以是:
git://github.com/user/project.git#commit-ish
git+ssh://user@hostname:project.git#commit-ish
git+http://user@hostname/project/blah.git#commit-ish
git+https://user@hostname/project/blah.git#commit-ish
commit-ish
可以是任何能作为参数提供给git checkout
的 tag, sha 或 branch。commit-ish
默认是master
2.2 modules
module 是 node_modules
目录下的任何文件或目录,能通过 Node.js 的 require()
函数加载。
module 必须是以下之一:
一个文件夹,它包含
package.json
文件且里面有main
字段一个 JavaScript 文件
包含 package.json
文件的 modules 也是 packages。
在 Node 程序的上下文中,module 也是从文件加载的内容,比如以下代码,我们也会说变量 req
指向 request
module。
2.3 scope
当注册一个 npm user account 或创建一个组织时,我们将被授予一个与之匹配的 scope。不同 scope 里的两个 package 可以重名。
在 package.json
文件中列出的依赖,scope 名就是 @
和 /
之间的内容。比如:
@npm/package-name
@npmcorp/package-name
npm packages 的可见性取决于它所在的 scope(namespace)以及为它设置的访问级别(private 或 public)。
org
✔️
✔️ 默认
user
✔️
✔️ 默认
unscoped
✔️ 始终
--
相关说明:
关于 private packages
private packages 始终是 scoped
scoped packages 默认是 private,如果想变 public 则在发布时要传一个命令行标识
关于 public packages(任何人都可以下载并使用)
unscoped packages 始终是 public
unscoped public packages 存在于 global public registry namespace
scoped public packages 属于某个用户或组织。当作为依赖包含在
package.json
里时必须以用户名或组织名开头@username/package-name
@org-name/package-name
2.4 创建 package.json
package.json
详见《贡献 package》。
3. 指定依赖项
在 package.json
文件中指定 dependencies
和 devDependencies
,当运行 npm install
时 npm 会下载它们。
dependencies
应用程序在 production 环境中需要的 packagesdevDependencies
仅在 local development 和 testing 时需要的 packages
4. 版本和 tag
4.1 语义版本
semantic versioning,语义版本控制。
首次发布
New product
从 1.0.0
开始
1.0.0
向后兼容的 bug fixes
Patch release
增加第三位
1.0.1
向后兼容的 new features
Minor release
增加中间数字
并将最后的数字置零
1.1.0
破坏向后兼容的更改
Major release
增加第一个数字
并将中间+最后的数字置零
2.0.0
4.2 分发标签
dist-tags, distribution tags, 分发标签
dist-tags 是对语义版本控制的补充:更易于人类阅读,也能更有效地分发 packages。
由于 dist-tags 和语义版本共享一个命名空间,因此需要避免和现有版本号冲突,所以尽量不要使用以数字或者字母“v”开头的 dist-tags。
5. 从 registry 获取 packages
5.1 安装和下载
npm install
命令会在当前目录中创建 node_modules
目录(如果尚不存在),并将 package 下载到该目录。如果本地(local)目录没有 package.json
文件,则 npm 会安装最新版本的 package,否则就会安装满足声明的 semantic versioning rule 的最新版本。
如果使用的是 npm 5.2+,推荐使用 npx
来 globally 运行 packages。全局安装 package 是让我们将 package code 作为本地计算机上的一组工具来使用。 Introducing npx: an npm package runner
相关阅读:全局安装时的 EACCES
permissions errors
5.2 update
5.3 uninstall
uninstall 一个 package,npm 会完全删除和它相关的所有东西。
6. 依赖的安全漏洞
当使用 npm install
安装 package 时,npm audit
会自动运行。也可以手动运行 npm audit
。
npm audit
会生成一份 audit reports(审计报告),里面包含了项目 dependencies 相关的 security vulnerabilities(安全漏洞),能帮我们修复漏洞或进一步排除故障。审计报告包含以下字段:
severity:漏洞的严重程度
critical 立即解决
high 尽快解决
moderate 时间允许地解决
low 自己定
description:关于漏洞的描述
package:存在漏洞的包名
patched in:漏洞被修复的版本
dependency of:存在漏洞的包的依赖 module
path:包含漏洞的代码路径
more info:关于 security report 的链接
npm audit
会检查 direct dependencies, devDependencies, bundledDependencies 和 optionalDependencies,但不检查 peerDependencies
7. scripts
npm 如何处理 scripts
字段。
package.json
文件里的 scripts
属性支持多种 built-in scripts 及其 preset life cycle events,也支持任意 scripts。这些脚本可以通过 npm run-script <stage>
或简写的 npm run <stage>
来执行。来自 dependencies 的 scripts 可以通过 npm explore <pkg> -- npm run <stage>
来运行。
7.1 pre 和 post 脚本
名字以 pre
或 post
开头即可。
当运行命令 npm run compress
时会执行上面的那三个脚本。
7.2 life cycle 脚本
一些特殊的 life cycle scripts 只在特定的情况下发生。
prepare
prepublishprepublishOnly
prepack
postpack
dependencies
:只要npm
命令导致node_modules
目录发生更改,该脚本就会执行,它运行在更改(changes 以及package.json
和package-lock.json
的文件更新)之后。
7.3 最佳实践
不要以 non-zero error code 退出
尽量不要使用 scripts 来做 npm 可以为我们做的事情
npm 可以做的事情,详见(npm CLI / Configuring npm / package.json)
检查 env 以确定把东西放哪
不要在脚本命令前加上
"sudo"
如果失败了,要用 root permissions,那就 sudo 有问题的 npm command
不要使用
install
scripts 从 package folder 的 root 运行,不管当调用
npm
时的 current working directory 在哪里如果想让 script 基于某个子目录运行,可以使用
INIT_CWD
环境变量
Last updated