npm知识

server/2025/2/5 17:40:23/

npm__0">npm 是什么

npm 为你和你的团队打开了连接整个 JavaScript 天才世界的一扇大门。它是世界上最大的软件注册表,每星期大约有 30 亿次的下载量,包含超过 600000 个包(package)(即,代码模块)。来自各大洲的开源软件开发者使用 npm 互相分享和借鉴。包的结构使您能够轻松跟踪依赖项和版本。

npm 由三个独立的部分组成:

  • 网站 —— 是开发者查找包(package)、设置参数以及管理 npm 使用体验的主要途径。
  • 注册表(registry) —— 是一个巨大的数据库,保存了每个包(package)的信息。
  • 命令行工具 (CLI) —— 通过命令行或终端运行。开发者通过 CLI 与 npm 打交道。

npm__10">公共 npm 注册表

公共 npm 注册表是一个 JavaScript 包数据库,每个包都由软件和元数据组成。开源开发人员和公司的开发人员使用 npm 注册表向整个社区或其组织成员贡献包,并下载包以在他们自己的项目中使用。

要开始使用注册表,请注册一个 npm 帐户并查看“入门”和 CLI 文档。

包和模块

npm 注册表包含包,其中许多也是 Node 模块,或者包含 Node 模块。请继续阅读以了解它们有何不同以及它们如何相互作用。

包是由 package.json 文件描述的文件或目录。包必须包含 package.json 文件才能发布到 npm 注册表。包可以不受限制,也可以限定为用户或组织,范围限定的包可以是私有或公共的。

包的格式

  • a) 包含由 package.json 文件描述的程序的文件夹。
  • b) 一个包含(a)的 gzip 压缩包。
  • c) 解析为(b)的 URL。
  • d) 在注册表中发布(c)的 <name>@<version>
  • e) 指向(d)的 <name>@<tag>
  • f) 具有满足(e)的最新标记的 <name>
  • g) 一个 git url,克隆后会导致(a)。

模块

模块是 node_modules 目录中可由 Node.js require() 函数加载的任何文件或目录。

要通过 Node.js require() 函数加载,模块必须是以下之一:

  • 一个文件夹,其中包含一个 package.json 文件,其中包含 “main” 字段。
  • 一个 JavaScript 文件。

**注意:**由于模块不需要具有 package.json 文件,因此并非所有模块都是包。只有具有 package.json 文件的模块也是包。

scope

所有 npm 包都有一个名称。一些包名称也有范围(作用域)。作用域遵循包名称的通常规则(URL安全字符,没有前导点或下划线)。在包名称中使用时,作用域前面有一个 @ 符号,后面有一个斜线,例如:

@somescope/somepackagename

作用域 (Scope) 是一种将相关包组合在一起的方法,也会影响 npm 处理包的方式。

每个 npm 用户/组织都有自己的范围,只有你才能在你的范围中添加包。这意味着您不必担心有人会抢在您之前使用您的软件包名称。因此,这也是向组织发送官方软件包的好方法。

范围包可以从 npm@2 开始发布和安装,并且受主 npm 注册表支持。无范围包可以依赖于 scoped 包,反之亦然。npm 客户端向后兼容无范围注册表,因此它可以用于同时处理有范围和无范围注册表。

安装范围包

作用域包安装到常规安装文件夹的子文件夹中,例如,如果普通包安装在 node_modules/packagename 中,则作用域包将安装在 node_modules/@myorg/packagename 中。范围文件夹 (@myorg) 只是范围的名称,前面有一个 @ 符号,可以包含任意数量的范围包。

通过在 npm install 中按名称引用 @ 符号来安装范围包:

npm install @myorg/mypackage

或者用 package.json

"dependencies": {"@myorg/mypackage": "^1.3.0"
}

请注意,如果省略 @ 符号,则在任何一种情况下,npm 都将尝试从 GitHub 安装。

导入范围包

由于范围包安装在 scope 文件夹中,因此在代码中需要它们时,您必须包含范围的名称,例如:

require("@myorg/mypackage");

Node 处理范围文件夹的方式并没有什么特别之处。这只需要名为 @myorg 的文件夹中的 mypackage 模块。

发布范围包

范围包可以从 npm 2.0 或更高版本中发布,并且可以发布到支持它们的任何注册表,包括主 npm 注册表。

npm__93">将公共范围的包发布到主 npm 注册表

发布到范围时,您有两个选项:

  • 发布到您的用户范围(示例:@username/模块
  • 发布到组织范围(示例:@org/module

如果要将公共模块发布到组织范围,则必须首先使用要发布到的范围名称创建组织,或者将其添加到具有适当权限的现有组织。例如,如果要发布到 @org,则需要在尝试发布之前在 npmjs.com 上创建 org 组织。

默认情况下,范围包不是公共的。您需要使用初始 npm publish 命令指定 --access public。这将发布包并将访问权限设置为 public,就像您在发布后运行 npm access public 一样。在发布现有范围包的新版本时,您无需执行此操作。

npm__104">将私有范围的包发布到 npm 注册表

要将私有范围的包发布到 npm 注册表,您必须拥有 npm 私有模块帐户。

然后,您可以使用 npm publishnpm publish --access restricted 发布模块,它将出现在 npm 注册表中,但访问权限受限。然后,如果需要,您可以使用 npm access 或在 npmjs.com 网站上更改访问权限。

将范围与注册表相关联

范围可以与单独的注册表相关联。这样,您就可以无缝地混合使用来自主 npm 注册表和一个或多个私有注册表的包,例如 GitHub Packages 或开源 Verdaccio 项目。

您可以在登录时将范围与注册表相关联,例如

npm login --registry=http://reg.example.com --scope=@myco

范围与 registry 具有多对一的关系:一个 registry 可以托管多个 scope,但一个 scope 只指向一个 registry。

您还可以使用 npm config 将范围与注册表关联:

npm config set @myco:registry=http://reg.example.com

一旦范围与注册表关联,具有该范围的包的任何 npm install 都将改为从该注册表请求包。包含范围的包名称的任何 npm publish 都将发布到该注册表。

npm_install__130">npm install 原理

  1. 首先得有 package.json 包管理文件才可以执行 npm install

  2. npm install -> 看是否有 package-lock.json 文件

  3. 没有 package-lock.json 文件,则构建依赖关系,然后从 registry 仓库下载安装包(压缩文件),将压缩包添加到本地的缓存文件中再将下载的压缩包解压到 node_modules 中,同时生成 package-lock.json 文件,完成安装

  4. package-lock.json 文件,则先检查下载的包和 package-lock.json 文件中的包版本是否符合 semver 版本规范,不一定非要完全一样,像 2.2.1 和 2.2.2 是一样的

  5. 不一致,则重新构建依赖关系,然后就是和第 3 步一样,去仓库下载,加压,添加缓存,解压到 node_modules 中,生成新的 package-lock.json

  6. 一致,则会去本地缓存文件中去查找缓存文件,找到缓存文件,将压缩包解压到 node_modules 中,完成安装

在这里插入图片描述

在这里插入图片描述

package.json 文件

‌package.json 文件是项目的清单,用于存储与项目有关的元数据以及依赖项包列表。它向‌ npm 提供信息,使其能够识别项目并处理所有项目的依赖项。通过 package.json 文件,其他人可以轻松安装和管理与项目相关的软件包。‌

package.json 文件必须是实际的 JSON,而不仅仅是 JavaScript 对象文本。

name

如果您计划发布包,则 package.json 中最重要的内容是 nameversion 字段,因为它们是必需的。名称和版本共同构成一个标识符,该标识符假定为完全唯一。对包的更改应随版本更改一起进行。如果您不打算发布包,则 name (名称) 和 version (版本) 字段是可选的。

一些规则:

  • 名称必须小于或等于 214 个字符。这包括 scoped 包的范围。
  • 作用域包的名称可以以点或下划线开头。如果没有范围,则不允许这样做。
  • 包的名称中不能包含大写字母。
  • 名称最终成为 URL、命令行上的参数和文件夹名称的一部分。因此,名称不能包含任何非 URL 安全字符。

一些提示:

  • 不要使用与核心 Node 模块相同的名称。
  • 不要在名称中添加 “js” 或 “node” 。假设它是 js,因为你正在编写一个 package.json 文件,你可以使用 engines 字段指定引擎。
  • 该名称可能会作为参数传递给 require(),因此它应该简短,但也具有合理的描述性。
  • 在你开发依赖之前,你可能要检查 npm 注册表,看看是否已经有这个名字。
  • 名称可以选择以范围为前缀,例如 @myorg/mypackage

version

如果您计划发布包,则 package.json 中最重要的内容是 nameversion 字段,因为它们是必需的。名称和版本共同构成一个标识符,该标识符假定为完全唯一。对包的更改应随版本更改一起进行。如果您不打算发布包,则 name (名称) 和 version (版本) 字段是可选的。

版本必须可由 node-semver 解析,它作为依赖项与 npm 捆绑在一起。(npm install semver 自己使用它)

description

在其中添加描述。它是一个字符串。这有助于人们发现你的包,因为它在 npm search 中列出。

keywords

在其中放置关键字。它是一个字符串数组。这有助于人们发现你的包,因为它在 npm search中列出。

author

顾名思义就是作者,表示该项目包的作者。它有两种形式,一种是字符串格式:

{"author": "CUGGZ <xxxxx@xx.com> (https://juejin.cn/user/3544481220801815)"
}

另一种是对象形式:

{"author": {"name" : "CUGGZ","email" : "xxxxx@xx.com","url" : "https://juejin.cn/user/3544481220801815"}
}

main

该字段用来指定加载的入口文件,在 browser 和 Node 环境中都可以使用。如果我们将项目发布为 npm 包,那么当使用 require 导入 npm 包时,返回的就是 main 字段所列出的文件的 module.exports 属性。如果不指定该字段,默认是项目根目录下的 index.js。如果没找到,就会报错。

该字段的值是一个字符串:

{"main": "./src/index.js"
}

browser

如果您的模块打算在客户端使用,则应使用 browser 字段而不是 main 字段。这有助于提示用户它可能依赖于 Node.js 模块中不可用的原语。(例如:window

{"browser": "./src/index.js"
}

repository

表示代码的存放仓库地址,通常有两种书写形式。第一种是字符串形式:

{
"repository": "https://github.com/facebook/react.git"
}

除此之外,还可以显式地设置版本控制系统,这时就是对象的形式:

{"repository": {"type": "git","url": "https://github.com/facebook/react.git"}
}

homepage

项目主页的 URL。

例如:

"homepage": "https://github.com/my-project"

scripts

scripts 属性是一个对象,其中包含在包生命周期中的不同时间运行的脚本命令。key 是生命周期事件,value 是要在该点运行的命令。

{"scripts": {"serve": "webpack server --mode=development","dev": "webpack --mode=development","build": "webpack --mode=production"}
}

可以配置任何 cmd 支持的命令,运行方式是 npm run 脚本名称,不仅如此,npm 还对某些常用的脚本名称进行了简化,下面的脚本名称是不需要使用 run 的:

  • start
  • stop
  • test

一些细节:

  • 脚本中可以省略 npx,因为会将 node_module 中的 bin 目录添加到环境变量中,执行完成后会删除。
  • start 脚本有默认值:node server.js。

dependencies

该字段中声明的是项目的生产环境中所必须的依赖包。当使用 npm 或 yarn 安装 npm 包时,该 npm 包会被自动插入到此配置项中:

npm install <PACKAGENAME>
yarn add <PACKAGENAME>

当在安装依赖时使用 --save 或 -S 参数,也会将新安装的 npm 包写入 dependencies 属性。

npm install --save <PACKAGENAME>

使用版本号

该字段的值是一个对象,该对象的各个成员,分别由模块名和对应的版本要求组成,表示依赖的模块及其版本范围:

{"dependencies": {"react": "^17.0.2","react-dom": "^17.0.2","react-scripts": "~4.0.3",}
}

使用 URL

您可以指定一个 URL 来代替版本范围。

使用 git URL

Git URL 的形式如下:

<protocol>://[<user>[:<password>]@]<hostname>[:<port>][:][/]<path>[#<commit-ish> | #semver:<semver>]

<protocol>gitgit+sshgit+httpgit+httpsgit+file 之一。

如果提供了 #<commit-ish>,它将用于克隆该提交。如果 commit-ish 的格式为 #semver:<semver>,则 <semver> 可以是任何有效的 semver 范围或确切版本,并且 npm 将在远程存储库中查找与该范围匹配的任何标签或引用,就像注册表依赖项一样。如果未指定 #<commit-ish>#semver:<semver>,则使用默认分支。

git+ssh://git@github.com:npm/cli.git#v1.0.27
git+ssh://git@github.com:npm/cli#semver:^5.0
git+https://isaacs@github.com/npm/cli.git
git://github.com/npm/cli.git#v1.0.27

使用 GitHub URL

就像 git URL 一样,可以包含 commit-ish 后缀。例如:

{"name": "foo","version": "0.0.0","dependencies": {"express": "expressjs/express","mocha": "mochajs/mocha#4727d357ea","module": "user/repo#feature\/branch"}
}

使用本地路径

从版本 2.0.0 开始,您可以提供包含包的本地目录的路径。可以使用 npm install -Snpm install --save 使用以下任何形式保存本地路径:

../foo/bar
~/foo/bar
./foo/bar
/foo/bar

在这种情况下,它们将被规范化为相对路径并添加到您的package.json中。例如:

{"name": "baz","dependencies": {"bar": "file:../foo/bar"}
}

此功能有助于本地离线开发和创建需要安装 npm 的测试,这些测试您不想访问外部服务器,但在将包发布到公共注册表时不应使用。

在这种情况下,运行 npm install 时,通过本地路径链接的包将不会安装自己的依赖项。您必须从本地路径本身内部运行 npm install

devDependencies

devDependencies 中声明的是开发阶段需要的依赖包,如 Webpack、Eslint、Babel 等,用于辅助开发。它们不同于 dependencies,因为它们只需安装在开发设备上,而无需在生产环境中运行代码。当打包上线时并不需要这些包,所以可以把这些依赖添加到 devDependencies 中,这些依赖依然会在本地指定 npm install 时被安装和管理,但是不会被安装到生产环境中。

当使用 npm 安装软件包时,指定以下参数后,新安装的 npm 包会被自动插入到此列表中:

npm install --save-dev <PACKAGENAME>
npm install -D <PACKAGENAME>
{"devDependencies": {"webpack": "^5.96.1","webpack-cli": "^5.1.4","webpack-dev-server": "^5.1.0"}
}

private

private 字段可以防止我们意外地将私有库发布到 npm 服务器。只需要将该字段设置为 true

{"private": true
}

语义化版本

版本规范:主版本号.次版本号.修订号

  • 主版本号(major):当你做了不兼容的 API 修改。

  • 次版本号(minor):当你做了向下兼容的功能性新增。

  • 修订号(patch,补丁版本号):当你做了向下兼容的问题修正。

版本号范围

>

大于某个版本,例如:>1.2.1,则说明依赖要大于 1.2.1 版本。

>=

大于等于某个版本,例如:>=1.2.1,则说明依赖要大于等于 1.2.1 版本。

<

小于某个版本,例如:<1.2.1,则说明依赖要小于 1.2.1 版本。

<=

小于等于某个版本,例如:<=1.2.1,则说明依赖要小于等于 1.2.1 版本。

比较器可以用空格连接起来形成一个比较器集,它由它包含的所有比较器的交集来满足。例如,范围 >=1.2.7 <1.3.0 将匹配版本 1.2.71.2.81.2.99,但不包括版本 1.2.61.3.01.1.0

一个范围由一个或多个比较器集组成,由 || 连接。一个版本匹配一个范围,当且仅当至少一个 || 分隔的比较器集中的每个比较器都满足该版本。范围 1.2.7 || >=1.2.9 <2.0.0 将与版本 1.2.7、1.2.9 和 1.4.6 匹配,但与版本 1.2.8 或 2.0.0 不匹配。

-

指定介于两个版本之间的范围,例如:1.2.3 - 2.3.4 ,相当于 >=1.2.3 <=2.3.4

如果提供部分版本作为包含范围内的第一个版本,则缺失的部分将替换为零。例如:1.2 - 2.3.4,相当于 >=1.2.0 <=2.3.4

如果提供部分版本作为包含范围内的第二个版本,则接受以提供的第二个版本开头的所有版本,但不接受大于提供的第二个版本。例如:1.2.3 - 2.3,相当于 >=1.2.3 <2.4.0-01.2.3 - 2,相当于 >=1.2.3 <3.0.0-0

X/x/*

Xx* 中的任何一个都可以用来 “代替” [major, minor, patch] 中的某个数值。

  • *

    相当于 >=0.0.0,任何非预发行版本都满足。

  • 1.x

    相当于 >=1.0.0 <2.0.0-0,匹配主版本号。

  • 1.2.x

    相当于 >=1.2.0 <1.3.0-0,匹配主版本号和次要版本号。

部分版本范围被视为 X 范围,因此特殊字符实际上是可选的。

  • ""

    空字符串,相当于 *>=0.0.0

  • 1

    相当于 1.x.x>=1.0.0 <2.0.0-0

  • 1.2

    相当于 1.2.x>=1.2.0 <1.3.0-0

~

如果指定了次要版本,则允许补丁级更改。如果没有指定次要版本,则允许次要级别的更改。

  • ~1.2.3

    相当于 >=1.2.3 <1.(2+1).0>=1.2.3 <1.3.0-0

  • ~1.2

    相当于 >=1.2.0 <1.(2+1).0>=1.2.0 <1.3.0-0(与 1.2.x 相同)。

  • ~1

    相当于 >=1.0.0 <(1+1).0.0>=1.0.0 <2.0.0-0(与 1.x 相同)。

  • ~0.2.3

    相当于 >=0.2.3 <0.(2+1).0>=0.2.3 <0.3.0-0

  • ~0.2

    相当于 >=0.2.0 <0.(2+1).0>=0.2.0 <0.3.0-0(与 0.2.x 相同)。

  • ~0

    相当于 >=0.0.0 <(0+1).0.0>=0.0.0 <1.0.0-0(同 0.x)。

^

允许对版本 1.0.0 及更高版本进行补丁更新和次要更新,对版本 0.X >=0.1.0 进行补丁更新,而对版本 0.0.X 没有更新。

  • ^1.2.3

    相当于 >=1.2.3 <2.0.0-0

  • ^0.2.3

    相当于 >=0.2.3 <0.3.0-0

  • ^0.0.3

    相当于 >=0.0.3 <0.0.4-0

解析插入符号范围时,缺少的 patch 值会降级为数字 0,但即使在主要版本和次要版本均为 0 时,该值也会允许灵活性。

  • ^1.2.x

    相当于 >=1.2.0 <2.0.0-0

  • ^0.0.x

    相当于 >=0.0.0 <0.1.0-0

  • ^0.0

    相当于 >=0.0.0 <0.1.0-0

缺少的 minorpatch 值会将糖化为零,但也允许在这些值内灵活使用,即使主要版本为零也是如此。

  • ^1.x

    相当于 >=1.0.0 <2.0.0-0

  • ^0.x

    相当于 >=0.0.0 <1.0.0-0
    ^

允许对版本 1.0.0 及更高版本进行补丁更新和次要更新,对版本 0.X >=0.1.0 进行补丁更新,而对版本 0.0.X 没有更新。

  • ^1.2.3

    相当于 >=1.2.3 <2.0.0-0

  • ^0.2.3

    相当于 >=0.2.3 <0.3.0-0

  • ^0.0.3

    相当于 >=0.0.3 <0.0.4-0

解析插入符号范围时,缺少的 patch 值会降级为数字 0,但即使在主要版本和次要版本均为 0 时,该值也会允许灵活性。

  • ^1.2.x

    相当于 >=1.2.0 <2.0.0-0

  • ^0.0.x

    相当于 >=0.0.0 <0.1.0-0

  • ^0.0

    相当于 >=0.0.0 <0.1.0-0

缺少的 minorpatch 值会将糖化为零,但也允许在这些值内灵活使用,即使主要版本为零也是如此。

  • ^1.x

    相当于 >=1.0.0 <2.0.0-0

  • ^0.x

    相当于 >=0.0.0 <1.0.0-0


http://www.ppmy.cn/server/165191.html

相关文章

三路排序算法

三路排序算法 引言 排序算法是计算机科学中基础且重要的算法之一。在数据分析和处理中&#xff0c;排序算法的效率直接影响着程序的执行速度和系统的稳定性。本文将深入探讨三路排序算法&#xff0c;包括其原理、实现和应用场景。 一、三路排序算法的原理 三路排序算法是一…

STM32 ADC

stm32单片机- ADC-技术详细解程序示范&#xff08;FREERTOSHAL多通道DMA&#xff09; - 知乎 (zhihu.com) 记录自己的嵌入式学习之路-CSDN博客 【STM32】ADC_stm32 adc-CSDN博客 STM32——ADC篇&#xff08;ADC的使用&#xff09;_stm32 adc-CSDN博客 【STM32 ADC】-CSDN博客…

Linux02——Linux的基本命令

目录 ls 常用选项及功能 综合示例 注意事项 cd和pwd命令 cd命令 pwd命令 相对路径、绝对路径和特殊路径符 特殊路径符号 mkdir命令 1. 功能与基本用法 2. 示例 3. 语法与参数 4. -p选项 touch-cat-more命令 1. touch命令 2. cat命令 3. more命令 cp-mv-rm命…

vue3 store刷新失效场景解决方案

1. 安装 vuex-persistedstate 插件 vuex-persistedstate 是一个常用的插件&#xff0c;可以方便地将 Vuex 状态持久化到 localStorage 或 sessionStorage 中 npm install vuex-persistedstate2. 配置 Vuex Store 使用 sessionStorage // store/index.js import { createStore }…

文件读写操作

写入文本文件 #include <iostream> #include <fstream>//ofstream类需要包含的头文件 using namespace std;void test01() {//1、包含头文件 fstream//2、创建流对象ofstream fout;/*3、指定打开方式&#xff1a;1.ios::out、ios::trunc 清除文件内容后打开2.ios:…

机器学习常用包numpy篇(四)函数运算

目录 前言 一、三角函数 二、双曲函数 三、数值修约 四、 求和、求积与差分 五、 指数与对数 六、算术运算 七、 矩阵与向量运算 八、代数运算 九、 其他数学工具 总结 前言 Python 的原生运算符可实现基础数学运算&#xff08;加减乘除、取余、取整、幂运算&#…

低代码产品插件功能一览

下图是统计的目前市面上流行的低代码、零代码产品的插件功能。 产品名称 产品类型 官方插件数量 支持拓展 官方插件功能 宜搭 零代码 3 暂不支持 云打印、CAD看图、打印表单详情 微搭 低代码 1 暂不支持 小程序 明道云 低代码 2 支持 视图、工作流节点 简道…

《大语言模型》综述学习笔记

《A Survey of Large Language Models》英文版综述最近出了中文版书——《大语言模型》&#xff0c;本博客作为阅读笔记记录一下&#xff0c;综述主页&#xff1a;https://github.com/RUCAIBox/LLMSurvey 关于LLM的一些概述和理解 记录一些有启发性的说法&#xff1a; 1、当前…