内容简介:包管理是使用 Node.js 进行编程的一个组成部分。Node Package Manager(npm)不仅仅是一个程序,还是一个完整的生态系统。在 Node.js 学习路径的第七部分中,我们来认识 npm 及其所有组件:快速说明:在谈论 npm 生态系统时,我会将其称为 npm。在专门提及 npm CLI 时,我将使用我的 GitHub 存储库中提供了跟随此学习路径中的示例进行操作所需的代码。
包管理是使用 Node.js 进行编程的一个组成部分。Node Package Manager(npm)不仅仅是一个程序,还是一个完整的生态系统。在 Node.js 学习路径的第七部分中,我们来认识 npm 及其所有组件:
Node.js 学习路径
本教程是 Node.js 学习路径的一部分。这些单元彼此互为基础,查看 学习 Node.js,第 1 单元:Node.js 学习路径的概述 从头开始学习。
npm
快速说明:在谈论 npm 生态系统时,我会将其称为 npm。在专门提及 npm CLI 时,我将使用 npm
。
获取代码
我的 GitHub 存储库中提供了跟随此学习路径中的示例进行操作所需的代码。
npm 注册表
在第 3 单元中,您了解到 npm 注册表 包含数十万个开源 Node 包,这些包由大型互动开发者社区提供支持。
在第 4 单元和第 5 单元中,您可能会从 npm 注册表经常出现的情况推断出,该注册表作为 特定 位置,用于寻找要在 Node 应用程序中使用的模块。
在知道包名的情况下找到并安装该包,这是一种情况,而在另一种情况下,假设您正在寻找 一种软件 ,而不是特定的包。您将如何在注册表中找到所需内容?
例如,假设您在查找 JavaScript linter 。要在 npm
注册表中众多的 linter
中查找某一项,转到 npm 网站 。在页面顶部的搜索字段中输入 linter,您将看到以下结果:
图 1. 在 npmjs.com 中搜索 linter
选项太多!这里有超过 3000 个与关键字 linter 匹配的包,您将如何决定要使用哪一个?
首先,您可以缩小一下搜索范围。从第 3 单元 得知,JavaScript 是一个 ECMAScript 实现,因此让我们来看看在向搜索词中添加 ecmascript 后会发生什么。
图 2. 在 npmjs.com 中搜索 ecmascript linter
这样显然更好。筛选 50 个包比 3000 个包更容易。但是,进一步缩小搜索范围会不会有所帮助?
包评分
npmjs.com 的搜索功能(由 npms.io 提供)提供了三个有用的关键指标:
- 流行度
- 质量
- 维护
npm 注册表中的每个包都受制于 计算这些分数的算法 。这些指标大体上意味着您对它们的认识,但如果想要获取更详细的解释,可查看 npms.io 上的 About 页面 。
分数以条形图格式显示在每个条目的右上角, p
表示流行度, q
表示质量, m
表示维护。将鼠标悬停在每个链接上,就会弹出相关的数字分数。(我正在使用 Chrome;您看到的情况可能会有所不同。)
您也可以直接在 npms.io 上搜索包,同样搜索 ecmascript linter
产生了 53 条结果:
图 3. 在 npms.io 中搜索 ecmascript linter
在该示例中,假设您选择在质量、流行度和维护方面平均值最高的包,最终就得到了 eslint ,分数分别为 97、85 和 100,平均分为 94。
npm CLI
在选择包后,就需要进行安装,这会将我们带到 npm
命令行界面(CLI)。
该 CLI 是一个程序,充当 Node 程序的包管理器。Node 随附该 CLI。
您所知道的 npm
您已经在本课程中多次使用了 npm
。在第 4 单元中,您使用 npm
安装了类似 nodemon
这样的包:
npm install -g nodemon
您还使用 npm
运行了 server.js
(通过 npm start
),运行了功能测试(通过 npm test
),甚至还从 package.json 运行了自定义脚本(通过 npm run load-test
和 npm run start-dev
)。
现在,我们将更仔细地看一下 npm 的功能及其用途。
使用 npm 安装本地包
在第 6 单元中,您使用 npm
安装了 sqlite 3 模块,该模块在购物清单应用程序的 package.json
文件中被指定为依赖项:
清单 1. /Node.js/Course/Unit-6/package.json
{ "name": "shopping-list", "version": "1.0.0", "description": "Shopping List", . . . "homepage": "https://github.com/jstevenperry/IBM-Code#readme", "dependencies": { "sqlite3": "^4.0.1" } }
当 npm
没有参数时,它会安装 package.json
内 dependencies
对象中列出的所有模块。(您将在第 8 单元中了解有关 package.json
的更多信息。)
安装一组新包
我们将 npm install
与不同于第 6 单元中所用的 package.json
一起使用。这将安装一组新包和依赖项。
首先,导航到我的 GitHub 存储库 中的 Node.js/Course/Unit-7 目录,在此会看到以下 package.json
。须注意,该文件包含用于运行 eslint
JavaScript linter 的 pretest 脚本。
清单 2. 带有 eslint 依赖项的 package.json
{ "name": "Unit-7", "version": "1.0.0", "description": "Sample code for Unit 7", "main": "logger.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "pretest": "eslint --ignore-path ../../.gitignore ." }, "keywords": [], "author": "J Steven Perry", "license": "Apache-2.0", "repository": { "type": "git", "url": "git+https://github.com/jstevenperry/IBM-Code" }, "devDependencies": { "babel-eslint": "^8.2.5", "eslint": "^5.1.0", "eslint-config-strongloop": "^2.1.0" } }
如果运行 npm install
,输出将类似如下:
$ npm install added 164 packages from 190 contributors and audited 333 packages in 3.368s found 0 vulnerabilities $
获取有关已安装软件的信息
要查看所安装的 eslint
的版本,可运行 npm list eslint 命令
:
$ npm list eslint Unit-7@1.0.0 /Users/sperry/home/development/projects/IBM-Code/Node.js/Course/Unit-7 └── eslint@5.1.0 $
要查看 node_modules 中的 完整依赖项树 ,可在不指定任何模块的情况下运行 npm list。输出看起来类似如下(由于非常冗长,此处已有所省略):
$ npm list Unit-7@1.0.0 /Users/sperry/home/development/projects/IBM-Code/Node.js/Course/Unit-7 ├─┬ babel-eslint@8.2.5 │ ├─┬ @babel/code-frame@7.0.0-beta.44 │ │ └─┬ @babel/highlight@7.0.0-beta.44 │ │ ├── chalk@2.4.1 deduped │ │ ├── esutils@2.0.2 deduped │ │ └── js-tokens@3.0.2 deduped . . │ │ └── estraverse@4.2.0 │ └── eslint-visitor-keys@1.0.0 ├─┬ eslint@5.1.0 │ ├─┬ ajv@6.5.2 │ │ ├── fast-deep-equal@2.0.1 │ │ ├── fast-json-stable-stringify@2.0.0 │ │ ├── json-schema-traverse@0.4.1 │ │ └─┬ uri-js@4.2.2 │ │ └── punycode@2.1.1 │ ├─┬ babel-code-frame@6.26.0 . . │ │ ├── lodash@4.17.10 deduped │ │ ├─┬ slice-ansi@1.0.0 │ │ │ └── is-fullwidth-code-point@2.0.0 deduped │ │ └── string-width@2.1.1 deduped │ └── text-table@0.2.0 └── eslint-config-strongloop@2.1.0 $
在安装 eslint
后,您可以使用针对 logger.js
的 strongloop 编码样式查明所生成的错误消息类型。
要运行 eslint
,可运行上述清单 2 中的 pretest
脚本,这次使用 npm run pretest
命令:
$ npm run pretest > Unit-7@1.0.0 pretest /Users/sperry/home/development/projects/IBM-Code/Node.js/Course/Unit-7 > eslint --ignore-path ../../.gitignore . /Users/sperry/home/development/projects/IBM-Code/Node.js/Course/Unit-7/logger.js 91:10 error 'setMessageOnlyOutput' is defined but never used no-unused-vars 92:3 error 'messageOnlyOutput' is not defined no-undef ✖ 2 problems (2 errors, 0 warnings) npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! Unit-7@1.0.0 pretest: `eslint --ignore-path ../../.gitignore .` npm ERR! Exit status 1 npm ERR! npm ERR! Failed at the Unit-7@1.0.0 pretest script. npm ERR! This is probably not a problem with npm. There is likely additional logging output above. npm ERR! A complete log of this run can be found in: npm ERR! /Users/sperry/.npm/_logs/2018-07-11T21_13_15_041Z-debug.log $
第一次运行时,linter 发现多个问题的情况并不少见。我实际上清理了 logger.js
来捕获上面的输出。
此外,您还可以配置 strongloop config 和 eslint 规则 。您可以在 Unit-7 源代码的 .eslintrc.json
文件中看到这一点,我在此覆盖了 max-len 规则(80 个字符对我来说似乎很保守)。
使用 npm 安装全局包
就像本地包一样,您已经有了一些关于全局包的实践。在第 4 单元中,您安装了全局包 nodemon
。正如我在那里提到的,全局安装会将包添加到 PATH ,因此您可以从计算机上的任何位置运行该包,这对于像 nodemon
这样的 CLI 包特别有用。
用于安装全局包的命令是 npm install -g PACKAGE_NAME
,其中 PACKAGE_NAME
是包的名称,如 nodemon
。
本地安装与全局安装
npm 的开发者对于 何时全局安装包以及何时不全局安装包有一个经验法 :
- 如果包是您需要从计算机上的任何位置运行的命令行工具,那么全局安装该包。
- 如果包是应用程序依赖项,那么 本地安装该包 。
npm 实用程序
npm
不仅仅可用于实现简单安装。 我最喜欢的两个用于 npm
CLI 的实用程序是 npm prune
和 npm doctor
。
npm prune
如果您像我一样,在开发过程中进行实验,在落实最终解决方案之前尝试多个选项,那么不幸的是,这可能会导致 无关的依赖项 ,这些是您不会使用的安装包。
例如,假设您要尝试 fluid-eslint
,因而安装此项:
$ npm install fluid-eslintnpm 注册表中的每个包都受制 + fluid-eslint@2.10.2 added 72 packages from 91 contributors and audited 795 packages in 4.877s found 0 vulnerabilities $ npm list fluid-eslint Unit-7@1.0.0 /Users/sperry/home/development/projects/IBM-Code/Node.js/Course/Unit-7 └── fluid-eslint@2.10.2 $n
在某一时刻,您决定不再使用 fluid-eslint
。将其从 package.json
中删除,但从 package.json
中删除包并不会更改 node_modules 的内容。 fluid-eslint
及其依赖项仍位于 node_modules 中。
未在 package.json
中列为依赖项并且不是另一个包依赖项的已安装顶级包会被视为无关的包。您需要一种可删除无关依赖项的方法,此时 npm prune
即可派上用场。
删除无关依赖项
要识别无关包,可运行 npm list
。所有无关的包都将列在依赖项树的底部,并附带一条错误消息:
$ npm list Unit-7@1.0.0 /Users/sperry/home/development/projects/IBM-Code/Node.js/Course/Unit-7 ├─┬ babel-eslint@8.2.5 │ ├─┬ @babel/code-frame@7.0.0-beta.44 │ │ └─┬ @babel/highlight@7.0.0-beta.44 │ │ ├── chalk@2.4.1 deduped │ │ ├── esutils@2.0.2 deduped │ │ └── js-tokens@3.0.2 deduped │ ├─┬ @babel/traverse@7.0.0-beta.44 . . │ │ ├─┬ slice-ansi@1.0.0 │ │ │ └── is-fullwidth-code-point@2.0.0 deduped │ │ └── string-width@2.1.1 deduped │ └── text-table@0.2.0 ├── eslint-config-strongloop@2.1.0 └── fluid-eslint@2.10.2 extraneous npm ERR! extraneous: fluid-eslint@2.10.2 /Users/sperry/home/development/projects/IBM-Code/Node.js/Course/Unit-7/node_modules/fluid-eslint $
须注意, fluid-eslint
被列为 extraneous
。
现在,您可以使用 npm prune
CLI 实用程序从 node_modules 中删除 fluid-eslint
及其依赖项:
$ npm prune removed 72 packages and audited 333 packages in 1.59s found 0 vulnerabilities $
如果您使用 npm list fluid-eslint
运行 npm install
,那么将会看到所有痕迹都已消失:
$ npm install audited 333 packages in 1.434s found 0 vulnerabilities Ix:~/home/development/projects/IBM-Code/Node.js/Course/Unit-7 sperry$ npm list fluid-eslint Unit-7@1.0.0 /Users/sperry/home/development/projects/IBM-Code/Node.js/Course/Unit-7 └── (empty) $
npm doctor
npm doctor
是一个方便的实用工具,可确保您的 npm 环境正常运行。其输出如下所示:
$ npm doctor Check Value Recommendation npm ping OK npm -v v6.1.0 node -v v10.6.0 npm config get registry https://registry.npmjs.org/ which git /usr/local/bin/git Perms check on cached files ok Perms check on global node_modules ok Perms check on local node_modules ok Verify cache contents verified 5660 tarballs $
它会运行许多检查,包括通过 npm ping
确保您的计算机可以连接到 npm 注册表(位于 registry.npmjs.org),运行 node
和 npm
的版本检查以及 git
程序的路径等等。
有关 npm doctor 的更多信息,可查看其 文档页面 。
有关 npm
的更多信息
npm
的完整指南超出了本课程的范围,尤其是因为这些信息已经存在于 npm 文档 中。如果您要了解更多信息,那么务必查看 npm
文档。在本课程的其余部分中,您将会使用 npm,所以我鼓励您熟悉这方面的内容。
npm
的备选项
虽然 npm
是最早的 Node.js 包管理器(可以追溯到 2010 年 1 月发行的 V0.0.1 ),但它不是唯一的包管理器。在本部分中,我将展示一些您应该了解的内容,先从以下可能最受欢迎的 npm
替换项开始:Yarn。
Yarn
Yarn 是用于 Node 的包管理器,与 npm CLI 一样使用一个 npm 注册表。它 由 Facebook 开发 ,并于 2016 年 10 月发布。
Yarn 在 npm 上提供了许多改进,包括:
Yarn 使用 一个 npm 注册表?
我认为 Yarn 使用 一个 npm 注册表,是因为在撰写本文时, registry.yarnpkg.com
实际上是 registry.npmjs.org 的反向代理 ,这多半出于性能原因。虽然存在一个建议弃用 registry.yarnpkg.com 的 yarnpkg GitHub 问题 ,但使用中的注册表对大多数 Node 开发者而言都应该是不可见的。
- 脱机访问 :Yarn 允许您访问已下载的包,而
npm
CLI 需要 Internet 访问权限才能运行npm install
(除非您使用npm pack
或类似offline-npm
的附加组件)。 - 许可检查 :Yarn 为依赖项提供内置许可检查,而
npm
需要类似license-checker
的附加组件。
安装 Yarn
您可以使用以下命令从 npm 注册表将 Yarn 安装为全局包: npm install -g yarn
。Yarn 就像 npm
一样使用 package.json
。要安装包,只需使用 yarn install
而不是 npm install
。
cd IBM-Code/Node.js/Course/Unit-7 rm -Rf node_modules yarn install
您应该会看到类似如下的输出:
Ix:~/src/projects sperry$ cd IBM-Code/Node.js/Course/Unit-7/ Ix:~/src/projects/IBM-Code/Node.js/Course/Unit-7 sperry$ rm -Rf node_modules/ Ix:~/src/projects/IBM-Code/Node.js/Course/Unit-7 sperry$ yarn install yarn install v1.7.0 [1/4] Resolving packages... [2/4] Fetching packages... [3/4] Linking dependencies... [4/4] Building fresh packages... :sparkles: Done in 2.32s. Ix:~/src/projects/IBM-Code/Node.js/Course/Unit-7 sperry$
然后,您可以运行 yarn pretest
,就像运行 npm run pretest
一样( Yarn 会判定 pretest
是一个脚本,您因而可跳过 run
子命令):
Ix:~/src/projects/IBM-Code/Node.js/Course/Unit-7 sperry$ yarn pretest yarn run v1.7.0 $ eslint --ignore-path ../../.gitignore . /Users/sperry/home/development/projects/IBM-Code/Node.js/Course/Unit-7/logger.js 91:10 error 'setMessageOnlyOutput' is defined but never used no-unused-vars 92:3 error 'messageOnlyOutput' is not defined no-undef ✖ 2 problems (2 errors, 0 warnings) error Command failed with exit code 1. info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
须注意,您从 eslint
获得的输出与从 npm
获得的输出相同。
Yarn 可为您解开谜团
与 npm 一样, Yarn 提供了许多非常方便的实用程序。 why
是我最喜欢的实用程序之一。
在仔细查看 package.json 或 node_modules 目录时,您可能想知道为何要使用给定包。在 Yarn 中,您不必疑惑。例如,假设您在 node_modules 中看到一个名为 acorn
的包:
Ix:~/src/projects/IBM-Code/Node.js/Course/Unit-7/node_modules sperry$ yarn why acorn yarn why v1.7.0 [1/4] Why do we have the module "acorn"...? [2/4] Initialising dependency graph... [3/4] Finding dependency... [4/4] Calculating file sizes... => Found "acorn@5.7.1" info Reasons this module exists - "eslint#espree" depends on it - Hoisted from "eslint#espree#acorn" - Hoisted from "eslint#espree#acorn-jsx#acorn" info Disk size without dependencies: "68MB" info Disk size with unique dependencies: "68MB" info Disk size with transitive dependencies: "68MB" info Number of shared dependencies: 0 :sparkles: Done in 0.19s.
看起来 acorn-jsx
需要 acorn
包,该包由 espree
使用,而 espree
则由 eslint
使用。
完整的依赖路径就是以下行中的 eslint
> espree
> acorn-jsx
> acorn
:
- Hoisted from "eslint#espree#acorn-jsx#acorn"
它甚至会告诉您占用了多少磁盘空间,简直太酷了!
更多适用于 Node 的包管理器
Node 生态系统包含其他包管理器,但大多数都不是 npm
的嵌入式替换项,而是提供在 npm
之外运行的某些功能。
- Webpack :一个模块捆绑程序,主要用于浏览器。
- Bower :
npm
的准嵌入式替换项,主要用于浏览器。(可参阅: How to migrate away from Bower )。 - RequireJS :主要是 Node 模块的
require()
替换项。 - pnpm :
npm
的完全嵌入式替换项(如 Yarn)。
npm 网站
在需要有关 Node 的帮助或其他信息时,可使用 npm 网站 。您可以通过它来访问 Node 文档,也可以作为开发者参与其中的 Node.js 项目。
获取帮助
npm 网站提供:
参与其中
假设您创建了一个很棒的包,希望通过 npm 注册表与全世界分享。现在该做什么呢?
要在 registry.npmjs.org 中发布 npm 包,就需要 设置一个帐户 。
在验证了您的电子邮件地址后,就可以在 npm 注册表中共享您的新包。您需要遵循特定的 标准和程序 。
登录后,首页会有一些有趣的指标:
图 4. npm 首页
在撰写本文时,首页列出了超过 80 万个用于 Node 的包!
结束语
在本单元中,您了解到 npm 涉及三个方面:
npm
可查看参考资源,了解有关 npm 生态系统、 npm
CLI 和 npm 网站 的更多信息。
该学习路径将继续进入第 8 单元,您将深入了解如何管理 Node 中的依赖项。
测试您的掌握情况
判断题
-
npm
是用来与 npm 注册表交互的最早的 CLI。 -
npm
的嵌入式替换项表示您只能将它用于require()
和特定的npm
函数。 - 除非在
package.json
的dependencies
部分中指定,否则无法安装本地包。
选择最佳答案
- 以下哪一项是
npm
的嵌入式替换项?
A. Zeke
B. tower
C. flake
D. Yarn
E. 以上皆是
- 以下哪一个组合命令将会显示 PACKAGE_NAME 的当前安装版本(假设在 package.json 中指定了 MODULE_NAME )?
A. npm install && npm --curver MODULE_NAME
B. npm install && npm list MODULE_NAME
C. yarn install && yarn list MODULE_NAME
D. npm install && npm MODULE_NAME --version
E. A 和 D
F. B 和 C
G. 以上都不是
填空
- npm 生态系统包含三个组件: npm ___________________ 、
npm
__________________ 和 npm ___________________ 。 - 提供使用
npm
全局安装 Yarn 时用到的命令:npm
_____________________ 。 - 要从 Node 应用程序的 node_modules 目录中删除无关的包,可使用
npm
_____________ 命令。
查看答案
判断题答案
- 答案: 对 :虽然还有其他 CLI 客户端,但
npm
是在 2010 年 1 月发布的。 - 答案: 错 :
npm
的嵌入式替换项是一个功能类似于npm
CLI 的程序。例如,代替使用npm install -g nodemon
,您可以通过yarn global add nodemon
来全局安装nodemon
。 - 答案: 错 :虽然不推荐,但您可以在没
package.json
文件的情况下安装本地依赖项。可使用以下命令:npm install PACKAGE_NAME
,其中 PACKAGE_NAME 是要安装的包的名称。
选择题的答案
- 答案: Yarn 是所列名称中唯一的
npm
嵌入式替换项。 - 答案: F. B 和 C :一旦通过
npm
或 Yarn 安装了包,list
子命令就适用于任何一个 CLI 。须注意,不应进行混搭;换句话说,不要使用一种 工具 进行安装,而使用另一种工具执行list
。
填空题的答案
- 答案:registry、CLI、网站
- 答案: install -g yarn (or i -g yarn) ,完整命令:
npm install -g yarn
- 答案: prune
npm
备用项
- Yarn :
npm
的嵌入式替换项。 - pnpm :
npm
的另一个嵌入式替换项。 - Webpack :一个模块捆绑程序,主要用于浏览器。
- Bower :
npm
的准嵌入式替换项。 - RequireJS :主要是 Node 模块的
require()
替换项。
参考资源
本文翻译自: Learn Node.js, Unit 7: Node package manager (2018-12-31)
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 学习 Node.js,第 9 单元:单元测试
- 学习单元测试,告别祈祷式编程
- 学习 Node.js,第 1 单元:Node.js 学习路径概述
- 学习 Node.js,第 12 单元:MongoDB
- Golang学习——基于Gin框架进行httptest单元测试
- Flutter 学习之路 - 测试(单元测试,Widget 测试,集成测试)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
一站式学习C编程
宋劲杉 / 电子工业出版社 / 2011-3 / 59.00元
《一站式学习c编程》有两条线索,一条线索是以linux平台为载体全面深入地介绍c语言的语法和程序的工作原理,另一条线索是介绍程序设计的基本思想和开发调试方法。本书分为两部分:第一部分讲解编程语言和程序设计的基本思想方法,让读者从概念上认识c语言;第二部分结合操作系统和体系结构的知识讲解程序的工作原理,让读者从本质上认识c语言。 《一站式学习c编程》适合做零基础的初学者学习c语言的第一本教材,......一起来看看 《一站式学习C编程》 这本书的介绍吧!