共计 7934 个字符,预计需要花费 20 分钟才能阅读完成。
本文参考了 NPM 中文文档写作而成的
npm install 功能
安装软件包
npm install 使用
npm install (with no args, in package dir) | |
npm install [<@scope>/]<name> | |
npm install [<@scope>/]<name>@<tag> | |
npm install [<@scope>/]<name>@<version> | |
npm install [<@scope>/]<name>@<version range> | |
npm install <git-host>:<git-user>/<repo-name> | |
npm install <git repo url> | |
npm install <tarball file> | |
npm install <tarball url> | |
npm install <folder> | |
aliases: npm i, npm add | |
common options: [-P|--save-prod|-D|--save-dev|-O|--save-optional][-e|--save-exact] [-B|--save-bundle][--no-save] [--dry-run] |
npm install 说明
此命令将安装软件包及其依赖的任何软件包。如果程序包具有程序包锁定或收缩包装文件,则依赖项的安装将由该程序驱动,npm-shrinkwrap.json 如果两个文件都存在,则优先。请参阅 package-lock.json 和 npm- shrinkwrap。
A package 是:
- a)包含文件描述的程序的 package.json 文件夹
- b)包含(a)的压缩 tarball
- c)解析为(b)的网址
- d)
<name>@<version>
在 npm-registry(c)的注册表中发布的 a - e)指向(d)的 a
<name>@<tag>
(参见 npm-dist-tag) - f)
<name>
具有满足(e)的“最新”标签的 a - g)
<git remote url>
解析为(a)的 a
即使您从未发布过软件包,如果您只想编写一个节点程序(a),或者如果您还希望能够在打包后将其轻松安装到其他地方,使用 npm 仍然可以获得很多好处。放入压缩档(b)。
npm install
在软件包目录中,没有参数:
将依赖项安装在本地 node_modules 文件夹中。
在全局模式下(即,带有命令 -g 或 –global 附加到命令后),它将当前程序包上下文(即,当前工作目录)安装为全局程序包。
默认情况下,npm install 将安装列为依赖项的所有模块 package.json。
使用该 –production 标志(或将 NODE_ENV 环境变量设置为 production)时,npm 将不会安装中列出的模块 devDependencies。
注意:将 –production 依赖项添加到项目时,该标志没有特殊含义。
npm install <folder>
:
将软件包作为当前项目中的符号链接安装在目录中。它的依赖项将在链接之前安装。如果 <folder>
位于项目的根目录下,则其依赖关系可能会 node_modules 像其他类型的依赖关系一样被提升到顶层。
npm install <tarball file>
:
安装位于文件系统上的软件包。注意:如果只想将 dev 目录链接到 npm 根目录,则可以使用来更轻松地做到这一点 npm link。
Tarball 要求:
- 文件名必须使用。tar,.tar.gz 或。tgz 作为扩展名。
- 包装内容应位于 tarball 的子文件夹中(通常称为 package/)。安装软件包时,npm 会剥离一个目录层(相当于 tar x –strip-components=1 运行)。
- 程序包必须包含 package.json 具有 name 和 version 属性的文件。
例:
npm install ./package.tgz
npm install <tarball url>
提取 tarball 网址,然后安装它。为了区分此选项和其他选项,参数必须以“http://”或“https://”开头
例:
npm install https://github.com/indexzero/forever/tarball/v0.5.6
npm install [<@scope>/]<name>
进行 <name>@<tag>
安装,<tag>
“标签”配置在哪里。(请参阅 npm config
。配置的默认值为 latest。)
在大多数情况下,这将安装 latest 在 npm 注册表上标记为的模块的版本。
例:
npm install sax
npm install dependencies 默认将所有指定的软件包保存到其中。此外,您可以使用一些其他标志来控制在何处以及如何保存它们:
- -P, –save-prod:包将出现在您的中 dependencies。这是默认设置,除非 -D 或 -O 存在。
- -D, –save-dev:包将出现在您的中 devDependencies。
- -O, –save-optional:包将出现在您的中 optionalDependencies。
- –no-save:防止保存到 dependencies。
使用上述任何选项将依赖项保存到 package.json 时,还有两个附加的可选标志:
- -E, –save-exact 注意:保存的依赖项将使用确切的版本配置,而不是使用 npm 的默认 semver range 运算符。
- -B, –save-bundle:保存的依赖项也将添加到您的 bundleDependencies 列表中。
此外,如果您具有 npm-shrinkwrap.json 或,package-lock.json 那么它也会被更新。
<scope>
是可选的。该包将从与指定范围关联的注册表中下载。如果没有注册表与给定范围相关联,则采用默认注册表。请参阅 npm-scope。
注意:如果您的作用域名称上未包含 @ -symbol,则 npm 会将其解释为 GitHub 存储库,请参见下文。范围名称也必须后面加上斜杠。
例子:
npm install sax | |
npm install githubname/reponame | |
npm install @myorg/privatepackage | |
npm install node-tap --save-dev | |
npm install dtrace-provider --save-optional | |
npm install readable-stream --save-exact | |
npm install ansi-regex --save-bundle |
注意:如果 <name> 当前工作目录中有一个文件或文件夹命名,则它将尝试安装该文件或文件夹,并且仅在名称无效时才尝试按名称获取该软件包。
npm install [<@scope>/]<name>@<tag>
安装指定标签引用的软件包的版本。如果该程序包的注册表数据中不存在该标记,则此操作将失败。
例:
npm install sax@latest | |
npm install @myorg/mypackage@latest |
npm install [<@scope>/]<name>@<version>
安装指定版本的软件包。如果该版本尚未发布到注册表,则将失败。
例:
npm install sax@0.1.1 | |
npm install @myorg/privatepackage@1.5.0 |
npm install [<@scope>/]<name>@<version range>
安装与指定版本范围匹配的软件包版本。这将遵循解决依赖性的相同规则 package.json。
请注意,大多数版本范围必须用引号引起来,以便您的外壳将其视为单个参数。
例:
npm install sax@">=0.1.0 <0.2.0" | |
npm install @myorg/privatepackage@">=0.1.0 <0.2.0" |
npm install <git remote url>
从托管的 git 提供程序安装软件包,并使用克隆该软件包 git。对于完整的 git 远程 URL,将仅尝试该 URL。
<protocol>://[<user>[:<password>]@]<hostname>[:<port>][:][/]<path>[#<commit-ish> | #semver:<semver>]
<protocol>
是以下之一 git,git+ssh,git+http,git+https,或 git+file。
如果 #<commit-ish>
提供,它将用于精确克隆该提交。如果 commit-ish 的格式为 #semver:<semver>
,则<semver>
可以是任何有效的 semver 范围或确切的版本,并且 npm 会在远程存储库中查找与该范围匹配的任何标记或引用,这与注册表依赖性类似。如果未指定 #<commit-ish>
或#semver:<semver>
,则使用存储库的默认分支。
如果存储库使用了子模块,那么这些子模块也将被克隆。
如果要安装的软件包包含 prepare 脚本,则在打包和安装软件包之前 dependencies,devDependencies 将安装和,并运行 prepare 脚本。
以下 git 环境变量被 npm 识别,并在运行 git 时添加到环境中:
- GIT_ASKPASS
- GIT_EXEC_PATH
- GIT_PROXY_COMMAND
- GIT_SSH
- GIT_SSH_COMMAND
- GIT_SSL_CAINFO
- GIT_SSL_NO_VERIFY
有关详细信息,请参见 git 手册页。
例子:
npm install git+ssh://git@github.com:npm/cli.git#v1.0.27 | |
npm install git+ssh://git@github.com:npm/cli#semver:^5.0 | |
npm install git+https://isaacs@github.com/npm/cli.git | |
npm install git://github.com/npm/cli.git#v1.0.27 | |
GIT_SSH_COMMAND='ssh -i ~/.ssh/custom_ident' npm install git+ssh://git@github.com:npm/cli.git |
npm install <githubname>/<githubrepo>[#<commit-ish>]
npm install github:<githubname>/<githubrepo>[#<commit-ish>]
https://github.com/githubname/githubrepo
通过尝试使用克隆它来安装软件包 git。
如果 #<commit-ish>
提供,它将用于精确克隆该提交。如果 commit-ish 的格式为 #semver:<semver>
,则<semver>
可以是任何有效的 semver 范围或确切的版本,并且 npm 会在远程存储库中查找与该范围匹配的任何标记或引用,这与注册表依赖性类似。如果未指定 #<commit-ish>
或#semver:<semver>
,则 master 使用。
与常规 git 的依赖,dependencies 并且 devDependencies 将安装如果包有一个 prepare 脚本,做包,然后再安装。
例子:
npm install mygithubuser/myproject | |
npm install github:mygithubuser/myproject |
npm install gist:[<githubname>/]<gistID>[#<commit-ish>|#semver:<semver>]
https://gist.github.com/gistID
通过尝试使用克隆它来安装软件包 git。与 gist 关联的 GitHub 用户名是可选的,不会保存在中 package.json。
与常规 git 的依赖,dependencies 并且 devDependencies 将安装如果包有一个 prepare 脚本,做包,然后再安装。
例:
npm install gist:101a11beef
npm install bitbucket:<bitbucketname>/<bitbucketrepo>[#<commit-ish>]
https://bitbucket.org/bitbucketname/bitbucketrepo
通过尝试使用克隆它来安装软件包 git。
如果 #<commit-ish>
提供,它将用于精确克隆该提交。如果 commit-ish 的格式为 #semver:<semver>
,则<semver>
可以是任何有效的 semver 范围或确切的版本,并且 npm 会在远程存储库中查找与该范围匹配的任何标记或引用,这与注册表依赖性类似。如果未指定 #<commit-ish>
或#semver:<semver>
,则 master 使用。
与常规 git 的依赖,dependencies 并且 devDependencies 将安装如果包有一个 prepare 脚本,做包,然后再安装。
例:
npm install bitbucket:mybitbucketuser/myproject:
npm install gitlab:<gitlabname>/<gitlabrepo>[#<commit-ish>]
https://gitlab.com/gitlabname/gitlabrepo
通过尝试使用克隆它来安装软件包 git。
如果 #<commit-ish>
提供,它将用于精确克隆该提交。如果 commit-ish 的格式为 #semver:<semver>
,则<semver>
可以是任何有效的 semver 范围或确切的版本,并且 npm 会在远程存储库中查找与该范围匹配的任何标记或引用,这与注册表依赖性类似。如果未指定 #<commit-ish>
或#semver:<semver>
,则 master 使用。
与常规 git 的依赖,dependencies 并且 devDependencies 将安装如果包有一个 prepare 脚本,做包,然后再安装。
例:
npm install gitlab:mygitlabuser/myproject | |
npm install gitlab:myusr/myproj#semver:^5.0: |
您可以组合多个参数,甚至多种类型的参数。例如:
:
npm install sax@">=0.1.0 <0.2.0" bench supervisor:
该--tag
参数将应用于所有指定的安装目标。如果存在具有给定名称的标签,则带标签的版本优先于较新的版本。
该--dry-run
参数将以通常的方式报告在没有实际安装任何内容的情况下安装将完成的操作。
在--package-lock-only
争吵只会更新 package-lock.json,而不是检查 node_modules 和下载依赖。
即使磁盘上存在本地副本,-for
--force
参数也将强制 npm 获取远程资源。
npm install sax --force:
该-g
或--global
参数会导致 NPM 在全球范围内,而不是在本地安装包。请参阅 npm-folders。
该--global-style
参数将使 npm 以 node_modules 与全局 node_modules 文件夹相同的布局将软件包安装到本地文件夹中。只有直接依赖项会显示在其中 node_modules,它们所依赖的所有内容都将在其 node_modules 文件夹中展平。显然,这将消除一些重复数据删除。
该 --ignore-scripts
参数将导致 npm 不执行 package.json 中定义的任何脚本。请参阅 npm-scripts。
该--legacy-bundling
参数将导致 npm 安装软件包,以便 1.4 之前的 npm 版本(例如节点 0.8 附带的版本)可以安装软件包。这消除了所有自动重复数据删除。
--link
在某些情况下,该参数将导致 npm 将全局安装链接到本地 空间。
该--no-bin-links
参数将阻止 npm 为软件包可能包含的任何二进制文件创建符号链接。
该--no-optional
参数将防止安装可选的依赖项。
该--no-shrinkwrap
参数将忽略可用的程序包锁定或收缩包装文件,而改用 package.json。
该--no-package-lock
参数将阻止 npm 创建 package-lock.json 文件。在禁用包锁的情况下运行时,npm 不会在安装时自动修剪节点模块。
该 –-nodedir=/path/to/node/source
参数将允许 npm 查找节点源代码,以便 npm 可以编译本机模块。
该 --only={prod[uction]|dev[elopment]}
参数将导致仅 安装 devDependencies 或仅非 devDependencies 安装 NODE_ENV。
该--no-audit
参数可用于禁用将审核报告发送到已配置的注册表。有关 npm-audit 详细信息,请参见。
请参阅 npm config
。许多配置参数都会对安装产生影响,因为这是 npm 的大部分工作。
算法
要安装软件包,npm 使用以下算法:
:
load the existing node_modules tree from disk | |
clone the tree | |
fetch the package.json and assorted metadata and add it to the clone | |
walk the clone and add any missing dependencies | |
dependencies will be added as close to the top as is possible | |
without breaking any other modules | |
compare the original tree with the cloned tree and make a list of | |
actions to take to convert one to the other | |
execute all of the actions, deepest first | |
kinds of actions are install, update, remove and move: |
对于以下 package{dep}结构:A{B,C}, B{C}, C{D},此算法产生:
:
A | |
+-- B | |
+-- C | |
+-- D: |
即,通过 A 已经使 C 被安装在更高级别的事实,满足了从 B 到 C 的依赖性。D 仍安装在顶层,因为没有冲突。
对于 A{B,C}, B{C,D@1}, C{D@2},此算法产生:
:
A | |
+-- B | |
+-- C | |
`-- D@2 | |
+-- D@1: |
由于 B 的 D @ 1 将安装在顶层,因此 C 现在必须 自己私下安装 D @ 2。该算法是确定性的,但是如果请求以两个不同的顺序安装两个依赖项,则可能会生成不同的树。
有关 npm 创建的特定文件夹结构的详细说明,请参见 npm-folders。
npm 安装算法的局限性
npm 将拒绝安装任何与当前软件包名称相同的软件包。可以用该 –force 标志覆盖它,但是在大多数情况下,可以通过更改本地程序包名称来解决。
在一些非常罕见的病理性极端情况下,循环可能导致 npm 尝试安装永无休止的软件包树。这是最简单的情况:
:
A -> B -> A'-> B' -> A -> B -> A'-> B' -> A -> ...:
其中 A 是某个程序包的某个版本,并且 A’ 是同一程序包的另一个版本。由于所 B 依赖的版本 A 与树中已有版本的版本不同,因此必须安装单独的副本。同样 A’,必须安装 B’。由于 B’ 取决于的原始版本(A 已被覆盖),因此循环陷入无限回归。
为了避免这种情况,npm flat-out 拒绝安装 name@version 软件包文件夹祖先树中任何位置已经存在的任何内容。一个更正确但更复杂的解决方案是将现有版本符号链接到新位置。如果这影响了实际用例,将对其进行调查。
本文参考 NPM 中文文档