JavaScript 包管理器 - NPM 和 Yarn 完全指南
包管理器是开发人员用来自动寻找、下载、安装、配置、升级和删除系统包的工具。
本文将向你展示开始使用NPM和Yarn等软件包管理器所需的一切。
但是,究竟为什么我们在开发工作流程中需要一个软件包管理器呢?让我们来了解一下。
为什么你需要一个软件包管理器?
假设没有软件包管理器。在这种情况下,你将不得不手动完成以下工作:
- 为你的项目找到所有正确的软件包
- 验证这些包是否有任何已知的漏洞
- 下载软件包
- 在适当的位置安装它们
- 跟踪所有软件包的最新更新
- 当有新的版本时,升级每个软件包
- 删除你不再需要的软件包
手动管理几十或几百个软件包是一项令人厌烦和耗时的工作。
因此,软件包管理器--如NPM、pNPM、Bower和Yarn--有助于自动化和消除手动管理所有软件包的繁琐过程。
请记住,软件包管理器与软件包注册表是不同的。因此,让我们找出主要的区别。
软件包管理器与软件包注册表 - 有什么区别?
包管理器是开发人员用来自动查找、下载、安装、配置、升级和卸载计算机包的工具。
NPM(Node Package Manager)和Yarn(Yet Another Resource Negotiator)是两个常用的软件包管理器。
包注册表是一个数据库(存储),用于存储成千上万的包(库、插件、框架或工具)。
换句话说,包注册表是包被发布到和安装的地方。
NPM注册处和GitHub包是两个常用的包注册处。
所以,现在我们知道了什么是包管理器以及为什么需要它,我们可以讨论如何使用两个流行的包管理器-NPM和Yarn。
请注意,外面有许多NPM与Yarn的争论--所以我们在这里将避免它们,因为最好的软件包管理器是最适合你的那一个。
因此,本文将向你展示NPM和Yarn是如何工作的,而不是告诉你哪个软件包管理器是最好的。然后由你来决定你喜欢哪一个。
另外,你可以选择在一个特定的项目中使用NPM,而在另一个项目中使用Yarn--取决于你认为哪个管理器最适合这项工作。
所以,不再多说,让我们开始学习如何安装这两个管理器。
如何安装Node包管理器(NPM)
NPM会在安装Node时自动安装。
因此,要在你的系统上安装NPM,请到NodeJS网站上获取Node的最新LTS或当前版本。
如何安装Yarn
最好是通过NPM来安装Yarn。所以,首先,从Node.js网站上安装NPM。
一旦你安装了NPM,就像这样继续安装Yarn:
npm install -g yarn
如何检查已安装的Node版本
要检查你系统上安装的Node.js版本,请运行:
node -v
上面的代码段中的-v
标志是对--version
的缩写。
如何检查已安装的NPM版本
要检查您系统上安装的NPM版本,请运行:
npm -v
如何检查已安装的Yarn版本
要检查你的系统上安装的Yarn版本,请运行:
yarn -v
如何升级Node Package Manager
通过运行以下内容更新到最新的NPM版本:
npm install npm@latest -g
如何升级NodeJS
假设你希望升级你的Node.js安装。在这种情况下,你有两个选择。
选项1:通过NodeJS网站升级
升级你的NodeJS安装的一种方法是手动从Node.js网站下载并安装最新版本。
选项2:通过版本管理工具升级
另一种升级你的NodeJS安装的方法是使用一个版本管理器,如NVM,n,或nvs。
如何升级Yarn
通过运行更新到最新的Yarn版本:
yarn set version latest
所以,现在我们的电脑上有了NPM(或Yarn),我们可以开始使用安装管理器来寻找、安装、配置和删除我们项目的包。
但究竟什么是包?让我们来了解一下。
包到底是什么?
一个包是一个目录(或项目),它有一个package.json
文件,用来记录它的信息。
**注意:**你只能将包(由package.json
文件描述的项目)发布到NPM注册表。
如何安装包
有两种方法来安装软件包:本地或全局。
本地包的安装
一个本地安装的包是你只能在你安装它的项目中使用的。
要在本地安装一个包,请执行以下操作:
- 从命令行导航到你项目的根目录。
- 使用下面的NPM或Yarn安装命令安装你的包(取决于你选择的项目使用的包管理器)。
注意:你必须在你的系统上安装Node和NPM,下面的NPM(和Yarn)安装命令才能工作。你可以通过安装最新的LTS或Node.js网站的当前版本来获得这两者。
NPM安装命令
npm install package-name --save
注意,上面的--save
命令指示NPM在package.json
文件中保存package-name
,作为项目所依赖的包之一。
假设你希望安装一个包的精确版本。在这种情况下,像这样在软件包的名字后面添加一个@[version-number]
。
npm install package-name@4.14.1 --save
或者,如果你要安装的包是用于开发和测试的,则使用。
npm install package-name --save-dev
上面的命令将使NPM下载三个项目到你的项目根目录中:一个node_modules
文件夹、一个package.json
文件和一个package-lock.json
文件。我们将在本文的后面详细讨论这些项目。
Yarn安装命令
yarn add package-name
假设你希望安装一个精确版本的软件包。在这种情况下,像这样在软件包的名字后面添加一个@[version-number]
。
yarn add package-name@4.14.1
或者,如果你要安装的包是用于开发和测试的,可以使用。
yarn add package-name --dev
上面的命令将使Yarn下载三个项目到你的项目的根目录中:一个node_modules
文件夹,一个package.json
文件和一个yarn.lock
文件。我们将在本文的后面详细讨论这些项目。
所以,现在我们知道了如何在本地安装一个包,我们可以讨论全局包的安装。
全局软件包的安装
全局安装的软件包是一个你可以在系统的任何地方使用的软件包。
要在全局范围内安装一个包,在你的终端上运行下面的代码:
npm install package-name -g
或者,你也可以像这样使用Yarn。
yarn global add package-name
注意,你可以从你系统的任何位置运行上述命令。
本地与全局软件包的安装
一般来说,在本地安装一个软件包会更好。下面是本地安装和全局安装之间的一些区别。
区别1:安装位置
本地安装的软件包会被安装在你执行npm install package-name
(或yarn add package-name
)命令的目录中。
具体来说,你可以在一个项目的node_module
目录中找到本地安装的软件包。
相比之下,全局安装的软件包会被安装在你系统中的一个位置。具体位置取决于你系统的配置。
区别2:软件包版本
假设你在本地安装了你的软件包。那么,你可以使用同一个包的不同版本来开发多个应用程序。
然而,当你在全球范围内安装时,你不得不为你的所有应用程序使用相同的软件包版本。
区别3:更新
本地安装允许你选择你想升级到最新版本的项目包。这使你更容易管理破坏与其他软件包兼容性的升级。
然而,升级一个全局安装的包会更新所有项目的包--如果升级破坏了与其他包的兼容性,这可能会造成维护的噩梦。
区别4:使用建议
全局安装对于你打算只在你的命令行上使用的软件包是最好的--特别是当它们提供可执行的命令可以在不同的项目中重复使用时。
然而,本地安装对于你打算在你的程序中使用的软件包是最好的--通过import
语句或require()
函数。
区别5:例子
NPM、React Native CLI、Gatsby CLI、Grunt CLI和Vue CLI是著名的全局包的例子。
本地包的常见例子是Webpack、Lodash、Jest和MomentJS。
注意:
- 你可以在命令行和项目中同时对你打算使用的包进行本地和全局安装。这种包的典型例子是ExpressJS和CoffeeScript。
- 你的包管理器不会执行已安装的包。NPM(和Yarn)只将包安装到
node_modules
目录中。而如果你指定了--save
命令,你的管理器会把软件包的细节添加到package.json
文件中。 - 要执行(运行)任何可执行包,你必须自己明确地这样做。我们将在本文后面的章节中讨论如何做。
但究竟什么是node_modules
文件夹、package.json
文件、package-lock.json
文件和yarn.lock
文件?让我们来了解一下。
什么是node_modules
文件夹?
node_modules目录是NPM放置所有为你的项目下载的软件包的文件夹。
什么是package.json
文件?
package.json文件是一个JSON文档,包管理器(如NPM和Yarn)使用它来存储关于特定项目的信息。
换句话说,package.json
文件是一个项目的元数据文件。
package.json
文件的优点
一个package.json
文件:
- 使得将你的项目发布到NPM注册中心成为可能
- 使得其他人容易管理和安装你的软件包
- 帮助NPM轻松管理模块的依赖关系
- 使你的软件包可以重现并与其他开发者共享
如何创建一个package.json
文件
进入你的项目的根目录,通过运行初始化创建一个package.json
文件:
npm init
或者,如果你的软件包管理器是Yarn,运行:
yarn init
一旦你执行了上面的初始化命令,你的软件包管理器将通过询问一些关于你的项目的问题来指导你创建package.json
文件。
如果你希望跳过问卷调查,你可以创建一个默认的package.json
文件。让我们来看看如何。
如何创建一个默认的package.json
文件
假设你想跳过npm init
(或yarn init
)命令所提示的调查问卷。在这种情况下,进入你的项目根目录并运行:
npm init -y
或者,如果你的软件包管理器是Yarn,运行:
yarn init -y
上面的命令将使用从当前目录中提取的默认值来创建你的项目的package.json
文件。
注意: -y
标志是--yes
的缩写。
一旦你的包管理器完成了它的初始化过程,你的项目的package.json
文件将包含一个具有一系列属性的对象。
这里有一个例子
{
"name": "codesweetly-project",
"version": "1.0.0",
"main": "index.js"
}
你可以看到上面的package.json
文件包含name
,version
, 和main
字段。下面我们来了解一下这些属性。
package.json
's Fields
package.json
的属性使你的项目能够被包管理器和最终用户使用。
假设你希望将你的包发布到NPM注册中心。在这种情况下,你的package.json
文件必须有"name"
和"version"
字段。
然而,如果你不打算发布你的包,在这种情况下,所有字段--包括"name"
和"version"
属性--都是可选的。
让我们来了解一下package.json
文件中常用的字段。
名称
"name"
字段是一个用来记录项目名称的属性。
"name"
属性的值必须是。
- 一个单字
- 小写字母
- 并且小于或等于214个字符
注意,你可以用连字符和下划线将单词连接起来。
下面是一个例子
{
"name": "code_sweetly-project"
}
版本
"version"
字段表示一个项目的当前版本号。
"version"
属性必须以major.minor.patch
的格式出现。它还必须遵循语义上的版本划分准则。
下面是一个例子
{
"version": "1.0.0"
}
描述
"description"
字段是一个包含对项目的目的进行简要描述的属性。
NPM建议拥有一个"description"
属性,以使你的包在NPM网站上更容易找到。
你的描述将是人们运行npm search
命令时显示的内容之一。
下面是一个例子
{
"description": "A brief description about this package (project)"
}
主
"main"
字段表示一个项目的入口点。
换句话说,当有人运行require()
函数时,Node将把调用解析为require(<package.json:main>)
。
下面是一个例子
{
"main": "./src/index.js"
}
私有
"private"
字段让包管理器知道他们是否应该将你的项目发布到NPM注册表上。
这里有一个例子
{
"private": true
}
如果你将package.json的"private"
属性设置为true
,包管理器将不会发布你的项目。
因此,设置该属性是防止意外发布你的包的一个好办法。
脚本
"scripts"
字段定义了你想在项目生命周期的不同时期运行的脚本命令。
这里有一个例子
{
"scripts": {
"test": "jest",
"dev": "webpack --mode development",
"build": "webpack --mode production",
"predeploy": "npm run build",
"deploy": "gh-pages -d build"
}
}
上面的"scripts"
字段包含五个属性,其值是我们希望我们的软件包管理器在调用该属性的键时运行的命令。
因此,举例来说,运行npm run dev
将执行"webpack --mode development"
命令。
关键字
"keywords"
字段指定了一个可以帮助人们发现你的包的关键字阵列。
这里有一个例子
{
"keywords": [
"drag",
"drop",
"drag and drop",
"dragndrop",
"draggable"
]
}
"keywords"
属性是人们运行npm search
命令时显示的信息的一部分。
作者
"author"
字段列出了一个项目的作者的详细信息。
这里有一个例子
{
"author": "Oluwatobi Sofela <oluwatobiss@codesweetly.com> (https://www.codesweetly.com)"
}
你也可以把上面的片段写成。
{
"author": {
"name": "Oluwatobi Sofela",
"email": "oluwatobiss@codesweetly.com",
"url": "https://www.codesweetly.com"
}
}
注意,"email"
和"url"
属性是可选的。
依赖性
"dependencies"
字段列出了一个项目在生产中所依赖的所有软件包。
这里有一个例子
{
"dependencies": {
"first-package": "^1.0.4",
"second-package": "~2.1.3"
}
}
因此,每当用户从NPM注册表安装你的项目时,依赖项属性确保包管理器可以自动找到并安装列出的包。
请注意,你可以通过以下两种方式将一个包添加到"dependencies"
字段。
- 手动添加你的项目在生产中依赖的每个软件包的名称和语义版本。
- 在你的终端上运行
npm install package-name --save-prod
命令。如果Yarn是你的软件包管理器,则可以使用yarn add package-name
。
devDependencies
"devDependencies"
字段列出了一个项目在生产中不需要的所有软件包,但为了其本地开发和测试目的而需要。
下面是一个例子
{
"devDependencies": {
"first-dev-package": "^5.8.1",
"second-dev-package": "3.2.2—4.0.0"
}
}
请注意,"devDependencies"
字段中列出的包将在项目的开发环境中可用,但在其生产服务器上没有。
假设一个用户通过npm install
(或yarn add
)命令安装项目。在这种情况下,软件包管理器将找到并下载所有列出的devDependencies
到项目的node_modules
目录。
请记住,你可以通过以下任何一种方式将软件包添加到"devDependencies"
领域。
- 手动添加你的项目在开发和测试方面所依赖的每个软件包的名称和语义版本。
- 在你的终端上运行
npm install package-name --save-dev
命令。或者,如果Yarn是您的软件包管理器,则yarn add package-name --dev
。
主页
"homepage"
字段指定了你的项目主页的URL。
这里有一个例子
{
"homepage": "https://codesweetly.com/package-json-file-explained"
}
所以,现在我们知道了什么是package.json
文件,我们可以讨论package-lock.json
。
什么是package-lock.json
文件?
package-lock.json 文件是NPM用来记录你在本地安装到项目的node_modules
目录中的所有软件包的确切版本。
一个package-lock.json
文件可以使一个应用程序以你发布到NPM注册表的确切方式100%地复制。
因此,假设一个用户克隆了你的应用程序并运行npm install
命令。在这种情况下,package-lock.json
,确保用户下载的是你用来开发应用程序的软件包的确切版本。
例如,假设一个用户克隆了你的应用程序,其中没有 package-lock.json
文件,而该应用程序中使用的一个依赖项有一个较新的版本。
假设在package.json
文件中,该依赖的版本号有一个圆点符号(例如,^2.6.2
)。在这种情况下,NPM将安装该依赖的最新次要版本--这可能导致应用程序产生错误的结果。
然而,假设用户克隆了你的应用程序,其中包含一个package-lock.json
文件。在这种情况下,NPM将安装package-lock.json
文件中记录的依赖关系的确切版本--不管是否存在更新的版本。
因此,用户将始终以你发布到NPM注册表中的精确方式获得你的应用程序。
换句话说,NPM使用package-lock.json
文件将你的包的依赖关系锁定在你用于项目开发的特定版本号上。
注意:只要你运行npm update
命令,NPM就会更新记录在package-lock.json
文件中的软件包。
什么是yarn.lock
文件?
yarn.lock
文件是Yarn用来记录你在本地安装到项目的node_modules
目录中的所有软件包的确切版本。
yarn.lock
文件与NPM的package-lock.jsonlockfile相类似。
我们前面提到,你的软件包管理器不会执行已安装的软件包--你必须自己明确地这样做。让我们来讨论一下如何做。
如何运行一个可执行包
有几种方法来运行一个可执行包,下面是标准的技术。
手动查找并执行软件包
运行可执行包的一种方法是在你的命令行上输入其本地路径,像这样:
./node_modules/.bin/package-name
将软件包添加到package.json的scripts
字段中。
另一种执行软件包的方法是首先将其添加到你项目的package.json文件的"scripts"
字段中,像这样:
{
"name": "your_package",
"version": "1.0.0",
"scripts": {
"desired-name": "name-of-package-to-execute"
}
}
之后,你可以像这样运行该软件包:
npm run desired-name
注意,上面的命令是对npm run-script desired-name
的速记。
另外,你也可以用Yarn来执行这个包,像这样:
yarn run desired-name
下面是一个例子
{
"name": "codesweetly-app",
"version": "1.0.0",
"scripts": {
"build": "webpack",
}
}
上面的片段将webpack添加到你的package.json
'的"scripts"
领域。因此,我们现在可以像这样在命令行中执行webpack
。
npm run build
或者,如果你的软件包管理器是Yarn,你可以像这样运行webpack:
yarn run build
使用NPX
运行可执行包的一个更快的方法是像这样使用NPX:
npx package-name
使用NPX,你不再需要将你的包添加到项目的package.json
文件的"scripts"
字段。
NPX(Node Package Execute)是一个Node包运行器,可以自动找到并执行指定的包。
这里有一个例子
npx webpack
上面的命令会自动找到并执行webpack。所以,我们不需要在我们的package.json
文件的"scripts"
字段中添加"build": "webpack"
属性。
注意:当你安装Node 8.2/NPM 5.2.0或更高版本时,NPX会自动被安装。
你也可以使用你喜欢的Node.js版本运行一些代码。让我们来看看如何。
如何使用你喜欢的Node.js版本来运行代码
你可以使用@
字符和node npm包来指定你希望用来执行代码的Node.js版本。
这里有一个例子
npx node@7 index.js
上面的片段告诉NPX用最新的Node版本从7大版本运行index.js
。
使用node@
命令是一种有用的方法,可以避免使用Node.js版本管理工具(如nvm)来切换Node版本。
假设你希望确认NPX将使用哪个Node版本来运行你的代码。在这种情况下,运行。
npx node@7 -v
上面的片段将显示NPX将用于运行你的代码的最新Node版本(从7大版本开始)--例如,v7.10.1
。
如何检查过期的本地软件包
要确定你的项目中是否有过期的软件包,请运行:
npm outdated
如果该命令没有任何输出,说明你项目的所有软件包都是最新的。
否则,请看这篇npm-outdated文章,了解该命令输出的详细解释。
或者,你也可以像这样使用Yarn:
yarn outdated
注意:要检查某个特定软件包的过期状态,请在outdated
关键字后面加上该软件包的名称--例如,npm outdated lodash
。
如何检查过期的全局包
要确认哪个全局包是过时的,请运行:
npm outdated -g --depth=0
如何检查本地安装的软件包
这里有三种方法来检查本地安装的软件包。
本地安装的软件包和它们的依赖关系
npm list
或者像这样使用Yarn:
yarn list
本地安装的软件包--不包括它们的依赖项
npm list --depth=0
或者
yarn list --depth=0
检查某个特定的包是否在本地安装了
npm list package-name
如何检查全球范围内安装的软件包
这里有三种方法来检查全局安装的软件包。
全局安装的包和它们的依赖关系
npm list -g
或者像这样使用Yarn。
yarn list -g
全局安装的软件包--不包括它们的依赖项
npm list -g --depth=0
或者
yarn list -g --depth=0
检查某个特定的软件包是否被全局安装
npm list -g package-name
如何更新软件包
下面是如何用NPM和Yarn来更新软件包。
如何将一个特定的软件包更新到其最新版本
npm update package-name
或者,对于用Yarn管理的项目,运行:
yarn upgrade package-name
如何更新一个项目的所有本地安装的包
npm update
或者:
yarn upgrade
如何更新一个特定的全局安装的包
你可以像这样更新一个全局安装的软件包:
npm update package-name -g
如何更新你系统中的所有全局安装的软件包
npm update -g
如何卸载软件包
下面是如何用NPM和Yarn卸载软件包。
如何从一个特定的项目中卸载一个包
首先,从命令行导航到项目的根目录并运行:
npm uninstall package-name
注意:
- 添加
-S
(或--save
) 标志,以删除项目的package.json
文件的dependencies
字段中对该包的引用。 - 添加
-D
(或--save-dev
) 标志,删除项目package.json
文件中devDependencies
字段对软件包的引用。
对于用Yarn管理的项目,运行。
yarn remove package-name
注意 :yarn remove
命令将自动更新项目的package.json
和yarn.lock
文件。
如何卸载一个全局包
npm uninstall package-name -g
注意,最好的做法是不要从node_modules
文件夹中手动删除包,因为这样的操作会影响到依赖它的其他模块 。
但NodeJS中的模块到底是什么?让我们来看看下面的内容。
到底什么是NodeJS的模块?
NodeJS中的模块是node_modules
文件夹中的任何文件,计算机可以通过Node的require()
功能加载。
这里有一个例子
const myModule = require("./codesweetly.js");
假设计算机成功地使用require()
函数来加载codesweetly.js
文件。在这种情况下,这意味着codesweetly.js
是一个模块-分配给myModule
变量。
请记住,一个模块也可能是一个包,但不一定。
如果一个模块没有一个用于记录其信息的package.json
文件,那么它就不是一个包。
另外,请注意,要使一个模块能够被require()
,该模块必须是下列之一。
- 一个包,它的
package.json
文件包含一个"main"
字段。 - 一个JavaScript文件。
如何将你的项目发布到NPM注册中心
NPM是一个为公共包作者提供的免费注册机构。
因此,你可以用它来发布你电脑中任何有package.json
文件的项目(文件夹)。
以下是与世界分享你的软件包所需的步骤。
第1步:登录或注册
进入NPM网站并登录(如果你还没有账户,可以注册)。
注意:确保你在创建新账户后验证你的电子邮件。否则,你在发布你的包时将会得到一个403 Forbidden
的错误。
第2步:登录
像这样从命令行登录到你的NPM账户。
npm login
注意:你可以使用npm whoami
命令来检查你当前是否已经登录。
第3步:发布你的软件包!
进入你的项目的根目录,像这样发布它。
npm publish
确保你的包的名字目前在NPM上不存在。否则,你在发布时将得到一个错误。
你可以使用npm search
命令(或NPM网站的搜索栏)来搜索你想使用的名字是否已经存在于NPM上。
假设所有适合你的包的名字都已经被占用了。在这种情况下,NPM允许你将你的项目作为一个范围发布。
换句话说,你可以把你的包作为你的用户名的一个子部分发布。让我们看看下面的方法。
如何将你的包作为你的用户名的一个范围来发布
打开你的package.json
文件,在你的包的名字前加上你的用户名。
这里有一个例子
{
"name": "@username/package-name",
"version": "1.0.0",
"main": "index.js",
"license": "MIT"
}
NPM的默认设置是假定一个范围内的名称包是一个私人项目。因此,如果你使用npm publish
命令来共享一个范围名称的包,你会得到一个错误。
因此,要把你的包作为你的用户名的范围发布,请在npm publish
命令中添加--access=public
标志。
npm publish --access=public
注意:你可以在初始化过程中通过使用npm init --scope=username
命令而不是npm init
,使你的项目成为范围内的包。
概述
这篇文章讨论了什么是软件包管理器。我们还看了两个流行的包管理器(NPM和Yarn)是如何工作的。
谢谢你的阅读!
下一篇: Yarn 离线安装 - 前端构建