NPM node_modules

🌙
手机阅读
本文目录结构

node_modules 说明

npm 的工作是把将各种各样的包拉到您的计算机上,并且进行管理;

这是 Nodejs 周边生态的重要体现;

node_modules文档就是存放这些安装包的地方。

node_modules 注意事项

  • 本地安装(默认)
    • 将内容放入当前软项目根目录的./node_modules种。
  • 全局安装(带有 -g):
    • 将内容放入 /usr/local 或安装 Nodejs 的位置。
  • 如果你需要require()来使用,那么你要选择本地安装需要的包。
  • 如果你要在命令行上运行它,那么选择全局安装它的老铁,绝对没毛病。
  • 如果两者都需要,则将其安装在两个地方,或使用 npm link

位置查看,请使用 npm root

前置条件

该文件夹默认为全局的, nodejs 安装的位置。在大多数系统上,这是/usr/local

  • 在 Windows 上为 %AppData%\npm
  • Unix 系统上,它是同一级的,因为 node 通常安装在 {prefix}/bin/node而不是{prefix}/node.exe

设置global 该标志后,npm 会将东西安装到全局的node_modules中。

如果未设置,它将使用当前程序包的根目录,如果尚未在程序包中,则使用当前工作目录。

node_modules

在本地安装时,包将放入node_modules的文件夹中。

这意味着您可以 require("packagename")加载其主模块

require("packagename/lib/path/to/sub/module")加载其他模块。

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

范围包的安装方式相同,不同的是,它们在相关 node_modules 文件夹的子文件夹中分组在一起,并且该范围前缀的名称由 @符号表示

例如,npm install @myorg/package 将包放在中{prefix}/node_modules/@myorg/package

请参阅 scope 以获取更多详细信息。

如果您希望 require() 安装软件包,请在本地安装。

可执行文件

  • 在全局模式下,可执行文件指向的位置

    • Unix {prefix}/bin
    • Windows 到 {prefix}
  • 在本地模式下,可执行文件指向的位置;

    • ./node_modules/.bin 以便可以通过 npm 运行的脚本使用它们。
      • 例如,当您运行测试,将在路径中 npm test

帮助手册页

  • 在全局模式下,手册页链接到{prefix}/share/man
  • 在本地模式下,未安装手册页。
  • 手册页未安装在 Windows 系统上。

缓存

请参阅npm-cache

缓存文件存储在~/.npm

在 Windows 上,储存在%AppData%/npm-cache

具体在哪里,这由 cache 配置参数控制。

临时文件

默认情况下,临时文件存储在tmp配置指定的文件夹中,该文件夹 默认为TMPDIRTMPTEMP环境变量;

Unix 在/tmp,Windows 上在c:\windows\temp

临时文件在该根目录下为程序的每次运行提供一个唯一的文件夹,并在成功退出后被删除。

更多信息

在本地安装时,npm 首先尝试查找合适的 prefix 文件夹。这样 npm install foo@1.2.3,即使您碰巧 cd 进入其他文件夹,它也将安装到软件包的明智根目录。

从 $ PWD 开始,npm 将沿着文件夹树移动,检查包含 package.json 文件或 node_modules 文件夹的文件夹。如果找到这样的东西,则出于运行 npm 命令的目的,该目录将被视为有效的“当前目录”。

(此行为受 git 的。git-folder 在工作目录中运行 git 命令时的查找逻辑的启发和相似。)

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

运行时 npm install foo@1.2.3,程序包将加载到缓存中,然后解压缩到/node_modules/foo中。

然后,将 foo 的任何依赖项类似地解压缩到中 ./node_modules/foo/node_modules/...

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

全局安装

如果 global 配置设置为 true,则 npm 将“全局”安装软件包。

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

周期,冲突和文件夹简约

循环使用节点模块系统的属性来处理,该属性会在目录中查找 node_modules 文件夹。

因此,在每个阶段,如果某个软件包已经安装在祖先 node_modules 文件夹中,则不会在当前位置安装该软件包。

考虑上述情况,其中 foo -> bar -> baz。想象一下,除此之外,baz 是否依赖 bar,

因此您将拥有: foo -> bar -> baz -> bar -> baz …。

但是,由于文件夹结构为:foo/node_modules/bar/node_modules/baz,因此无需放入 bar 的另一个副本。

../baz/node_modules,因为当它调用 require("bar") 时,它将获取安装在中的副本 foo/node_modules/bar

仅当在多个嵌套 node_modules 文件夹中安装完全相同的版本时,才使用此快捷方式。

a/node_modules/b/node_modules/a 如果两个"a"软件包是不同的版本,则仍然可能存在。

但是,无需多次重复完全相同的程序包,就始终可以防止无限回归。

可以通过在本地化的“目标”文件夹下尽可能高的级别安装依赖项来进行另一项优化。

例子

考虑以下依赖关系图:

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

在这种情况下,我们可能期望这样的文件夹结构:

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

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

即使 blerg 的最新副本是 1.3.7,foo 仍对版本 1.2.5 有特定的依赖性。

因此,该安装在 [A]。由于 blerg 的父安装满足 bar 对的依赖 blerg@1.x,因此不会在 [B] 下安装另一个副本。

Bar [B] 也依赖bazasdf,因此它们安装在barnode_modules文件夹中。

由于依赖于 baz@2.x,因此它无法重复使用 baz@1.2.3node_modules文件夹 [D] 中安装的文件,而必须安装自己的副本 [C]

在条形图的下面,baz -> quux -> bar 依赖项创建了一个循环。

但是,由于 bar 已经在 quux 的祖先 [B] 中,因此它不会将 bar 的另一个副本解压缩到该文件夹 ​​ 中。

foo -> baz[D] 下,quux 的 [E] 文件夹树为空,因为它对 bar 的依赖关系由安装在 [B] 的父文件夹副本满足。

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

发布包

发布后,npm 将在 node_modules 文件夹中查找。

如果 bundledDependencies 数组中没有任何项目,那么它们将不会包含在压缩包中。

这允许软件包维护者在本地安装其所有依赖项(和开发依赖项),

但仅重新发布在其他地方找不到的那些项。

请参阅 package.json 以获取更多信息。

AXIHE / 精选资源

浏览全部教程

面试题

学习网站

前端培训
自己甄别

前端书籍

关于朱安邦

我叫 朱安邦,阿西河的站长,在杭州。

以前是一名平面设计师,后来开始接接触前端开发,主要研究前端技术中的JS方向。

业余时间我喜欢分享和交流自己的技术,欢迎大家关注我的 Bilibili

关注我: Github / 知乎

于2021年离开前端领域,目前重心放在研究区块链上面了

我叫朱安邦,阿西河的站长

目前在杭州从事区块链周边的开发工作,机械专业,以前从事平面设计工作。

2014年底脱产在老家自学6个月的前端技术,自学期间几乎从未出过家门,最终找到了满意的前端工作。更多>

于2021年离开前端领域,目前从事区块链方面工作了