文件夹

npm 使用的文件夹结构

选择命令行版本:

描述

¥Description

npm 在你的计算机上放置各种东西。这就是它的工作。

¥npm puts various things on your computer. That's its job.

这份文件会告诉你它把什么放在哪里。

¥This document will tell you what it puts where.

tl;dr

  • 本地安装(默认):将内容放入当前包根目录的 ./node_modules 中。

    ¥Local install (default): puts stuff in ./node_modules of the current package root.

  • 全局安装(使用 -g):将东西放在 /usr/local 或安装节点的任何地方。

    ¥Global install (with -g): puts stuff in /usr/local or wherever node is installed.

  • 如果你要对其进行 require(),请在本地安装。

    ¥Install it locally if you're going to require() it.

  • 如果要在命令行上运行它,请全局安装它。

    ¥Install it globally if you're going to run it on the command line.

  • 如果两者都需要,那么在两个地方都安装,或者使用 npm link

    ¥If you need both, then install it in both places, or use npm link.

前缀配置

¥prefix Configuration

prefix 配置 默认是安装 node 的位置。在大多数系统上,这是 /usr/local。在 Windows 上,它是 %AppData%\npm。在 Unix 系统上,它是上一级的,因为 node 通常安装在 {prefix}/bin/node 而不是 {prefix}/node.exe

¥The prefix config defaults to the location where node is installed. On most systems, this is /usr/local. On Windows, it's %AppData%\npm. On Unix systems, it's one level up, since node is typically installed at {prefix}/bin/node rather than {prefix}/node.exe.

当设置 global 标志时,npm 会将内容安装到此前缀中。如果未设置,则使用当前包的根目录,如果不在包中,则使用当前工作目录。

¥When the global flag is set, npm installs things into this prefix. When it is not set, it uses the root of the current package, or the current working directory if not in a package already.

Node 模块

¥Node Modules

包被放到 prefix 下的 node_modules 文件夹中。在本地安装时,这意味着你可以 require("packagename") 加载它的主模块,或者 require("packagename/lib/path/to/sub/module") 加载其他模块。

¥Packages are dropped into the node_modules folder under the prefix. When installing locally, this means that you can require("packagename") to load its main module, or require("packagename/lib/path/to/sub/module") to load other modules.

Unix 系统上的全局安装转到 {prefix}/lib/node_modules。Windows 上的全局安装转到 {prefix}/node_modules(即没有 lib 文件夹。)

¥Global installs on Unix systems go to {prefix}/lib/node_modules. Global installs on Windows go to {prefix}/node_modules (that is, no lib folder.)

范围包的安装方式相同,除了它们被组合在相关 node_modules 文件夹的子文件夹中,并以 @ 符号作为该作用域前缀的名称,例如 npm install @myorg/package 会将包放在 {prefix}/node_modules/@myorg/package 中。有关详细信息,请参阅 scope

¥Scoped packages are installed the same way, except they are grouped together in a sub-folder of the relevant node_modules folder with the name of that scope prefix by the @ symbol, e.g. npm install @myorg/package would place the package in {prefix}/node_modules/@myorg/package. See scope for more details.

如果你想 require() 一个包,那么在本地安装它。

¥If you wish to require() a package, then install it locally.

可执行文件

¥Executables

在全局模式下,可执行文件链接到 Unix 上的 {prefix}/bin,或直接链接到 Windows 上的 {prefix}。确保路径在终端的 PATH 环境中以运行它们。

¥When in global mode, executables are linked into {prefix}/bin on Unix, or directly into {prefix} on Windows. Ensure that path is in your terminal's PATH environment to run them.

在本地模式下,可执行文件被链接到 ./node_modules/.bin,以便它们可用于通过 npm 运行的脚本。(例如,当你运行 npm test 时,测试运行程序将在路径中。)

¥When in local mode, executables are linked into ./node_modules/.bin so that they can be made available to scripts run through npm. (For example, so that a test runner will be in the path when you run npm test.)

手册页

¥Man Pages

在全局模式下,手册页链接到 {prefix}/share/man

¥When in global mode, man pages are linked into {prefix}/share/man.

在本地模式下,不安装手册页。

¥When in local mode, man pages are not installed.

手册页未安装在 Windows 系统上。

¥Man pages are not installed on Windows systems.

缓存

¥Cache

npm cache。缓存文件存储在 Posix 上的 ~/.npm 或 Windows 上的 %LocalAppData%/npm-cache 中。

¥See npm cache. Cache files are stored in ~/.npm on Posix, or %LocalAppData%/npm-cache on Windows.

这由 cache 配置 参数控制。

¥This is controlled by the cache config param.

临时文件

¥Temp Files

临时文件默认存储在 tmp 配置 指定的文件夹中,默认为 TMPDIR、TMP 或 TEMP 环境变量,或者 Unix 上的 /tmp 和 Windows 上的 c:\windows\temp

¥Temporary files are stored by default in the folder specified by the tmp config, which defaults to the TMPDIR, TMP, or TEMP environment variables, or /tmp on Unix and c:\windows\temp on Windows.

每次运行程序时,都会在此根目录下为临时文件分配一个唯一文件夹,并在成功退出后删除。

¥Temp files are given a unique folder under this root for each run of the program, and are deleted upon successful exit.

更多信息

¥More Information

在本地安装时,npm 首先尝试找到合适的 prefix 文件夹。这样,即使你碰巧将 cd 安装到其他文件夹中,npm install foo@1.2.3 也会安装到软件包的合理根目录中。

¥When installing locally, npm first tries to find an appropriate prefix folder. This is so that npm install foo@1.2.3 will install to the sensible root of your package, even if you happen to have cded into some other folder.

从 $PWD 开始,npm 将遍历文件夹树,检查包含 package.json 文件或 node_modules 文件夹的文件夹。如果找到这样的东西,那么为了运行 npm 命令,它被视为有效的 "当前目录"。(在工作目录中运行 git 命令时,此行为受到 git 的 .git-folder 搜索逻辑的启发并与之类似。)

¥Starting at the $PWD, npm will walk up the folder tree checking for a folder that contains either a package.json file, or a node_modules folder. If such a thing is found, then that is treated as the effective "current directory" for the purpose of running npm commands. (This behavior is inspired by and similar to git's .git-folder seeking logic when running git commands in a working dir.)

如果没有找到包根目录,则使用当前文件夹。

¥If no package root is found, then the current folder is used.

当你运行 npm install foo@1.2.3 时,包被加载到缓存中,然后解压到 ./node_modules/foo 中。然后,任何 foo 的依赖都被类似地解包到 ./node_modules/foo/node_modules/... 中。

¥When you run npm install foo@1.2.3, then the package is loaded into the cache, and then unpacked into ./node_modules/foo. Then, any of foo's dependencies are similarly unpacked into ./node_modules/foo/node_modules/....

任何 bin 文件都符号链接到 ./node_modules/.bin/,以便在必要时可以通过 npm 脚本找到它们。

¥Any bin files are symlinked to ./node_modules/.bin/, so that they may be found by npm scripts when necessary.

全局安装

¥Global Installation

如果 global 配置 设置为 true,则 npm 将安装包 "globally"。

¥If the global config is set to true, then npm will install packages "globally".

对于全局安装,包的安装方式大致相同,但使用上述文件夹。

¥For global installation, packages are installed roughly the same way, but using the folders described above.

循环、冲突和文件夹简约

¥Cycles, Conflicts, and Folder Parsimony

循环使用 node 模块系统的属性处理,它遍历目录查找 node_modules 文件夹。因此,在每个阶段,如果一个包已经安装在祖级 node_modules 文件夹中,那么它不会安装在当前位置。

¥Cycles are handled using the property of node's module system that it walks up the directories looking for node_modules folders. So, at every stage, if a package is already installed in an ancestor node_modules folder, then it is not installed at the current location.

考虑上面的情况,其中 foo -> bar -> baz。想象一下,如果除此之外,baz 还依赖于 bar,那么你将拥有:foo -> bar -> baz -> bar -> baz ...。但是,由于文件夹结构是:foo/node_modules/bar/node_modules/baz,没有必要将另一个 bar 副本放入 .../baz/node_modules,因为当 baz 调用 require("bar") 时,它将获得安装在 foo/node_modules/bar 中的副本。

¥Consider the case above, where foo -> bar -> baz. Imagine if, in addition to that, baz depended on bar, so you'd have: foo -> bar -> baz -> bar -> baz .... However, since the folder structure is: foo/node_modules/bar/node_modules/baz, there's no need to put another copy of bar into .../baz/node_modules, since when baz calls require("bar"), it will get the copy that is installed in foo/node_modules/bar.

只有在多个嵌套的 node_modules 文件夹中安装完全相同的版本时,才使用此快捷方式。如果两个 "a" 包是不同的版本,仍然可以有 a/node_modules/b/node_modules/a。但是,如果不多次重复完全相同的包,将始终防止无限倒退。

¥This shortcut is only used if the exact same version would be installed in multiple nested node_modules folders. It is still possible to have a/node_modules/b/node_modules/a if the two "a" packages are different versions. However, without repeating the exact same package multiple times, an infinite regress will always be prevented.

通过在本地化的 "target" 文件夹(提升)下安装可能的最高级别的依赖,可以进行另一种优化。从版本 3 开始,npm 默认会提升依赖。

¥Another optimization can be made by installing dependencies at the highest level possible, below the localized "target" folder (hoisting). Since version 3, npm hoists dependencies by default.

示例

¥Example

考虑这个依赖图:

¥Consider this dependency graph:

foo
+-- blerg@1.2.5
+-- bar@1.2.3
| +-- blerg@1.x (latest=1.3.7)
| +-- baz@2.x
| | `-- quux@3.x
| | `-- bar@1.2.3 (cycle)
| `-- asdf@*
`-- baz@1.2.3
`-- quux@3.x
`-- bar

在这种情况下,我们可能期望这样的文件夹结构(所有依赖都提升到可能的最高级别):

¥In this case, we might expect a folder structure like this (with all dependencies hoisted to the highest level possible):

foo
+-- node_modules
+-- blerg (1.2.5) <---[A]
+-- bar (1.2.3) <---[B]
| +-- node_modules
| +-- baz (2.0.2) <---[C]
+-- asdf (2.3.4)
+-- baz (1.2.3) <---[D]
+-- quux (3.2.0) <---[E]

由于 foo 直接依赖于 bar@1.2.3baz@1.2.3,因此它们安装在 foo 的 node_modules 文件夹中。

¥Since foo depends directly on bar@1.2.3 and baz@1.2.3, those are installed in foo's node_modules folder.

尽管 blerg 的最新版本是 1.3.7,但 foo 对 1.2.5 版本有特定的依赖。所以,它被安装在 [A]。由于 blerg 的父安装满足 bar 对 blerg@1.x 的依赖,所以没有在 [B]下安装另一个副本。

¥Even though the latest copy of blerg is 1.3.7, foo has a specific dependency on version 1.2.5. So, that gets installed at [A]. Since the parent installation of blerg satisfies bar's dependency on blerg@1.x, it does not install another copy under [B].

Bar [B] 也依赖于 baz 和 asdf。因为它依赖于 baz@2.x,所以它不能重复使用安装在父 node_modules 文件夹 [D]中的 baz@1.2.3,必须安装自己的副本 [C]。为了尽量减少重复,npm 默认将依赖提升到顶层,所以 asdf 安装在 [A] 下。

¥Bar [B] also has dependencies on baz and asdf. Because it depends on baz@2.x, it cannot re-use the baz@1.2.3 installed in the parent node_modules folder [D], and must install its own copy [C]. In order to minimize duplication, npm hoists dependencies to the top level by default, so asdf is installed under [A].

在条形下方,baz -> quux -> bar 依赖创建了一个循环。但是,因为 bar 已经在 quux 的祖级 [B] 中,所以它不会将 bar 的另一个副本解压缩到该文件夹​​中。同样,quux 的 [E] 文件夹树是空的,因为它对 bar 的依赖由安装在 [B] 的父文件夹副本满足。

¥Underneath bar, the baz -> quux -> bar dependency creates a cycle. However, because bar is already in quux's ancestry [B], it does not unpack another copy of bar into that folder. Likewise, quux's [E] folder tree is empty, because its dependency on bar is satisfied by the parent folder copy installed at [B].

有关安装位置的图形细分,请使用 npm ls

¥For a graphical breakdown of what is installed where, use npm ls.

发布

¥Publishing

发布后,npm 将在 node_modules 文件夹中查找。如果有任何项目不在 bundleDependencies 数组中,则它们将不会包含在包 tarball 中。

¥Upon publishing, npm will look in the node_modules folder. If any of the items there are not in the bundleDependencies array, then they will not be included in the package tarball.

这允许包维护者在本地安装他们所有的依赖(和开发依赖),但只重新发布那些在其他地方找不到的项目。有关详细信息,请参阅 package.json

¥This allows a package maintainer to install all of their dependencies (and dev dependencies) locally, but only re-publish those items that cannot be found elsewhere. See package.json for more information.

也可以看看

¥See also

npm 中文网 - 粤ICP备13048890号