什么是 npm —— 写给初学者的编程教程

程序源代码

共 4633字,需浏览 10分钟

 · 2020-10-17

本篇文章可以作为 npm(Node.js 最喜欢的伙伴)的一个基本学习指南。

自 2009 年以来,Node.js 一直席卷全球。成千上万个系统基于 Node.js 构建,促使开发者在社区宣称“JavaScript 正在吞噬软件”。

Node 成功的主要因素之一是它广受欢迎的软件包管理器——npm,因为 npm 使 JavaScript 开发人员可以快速方便地共享软件包, 例如 lodash 和 moment

在我撰写这篇文章时,npm 已帮助发布了 130 万个软件包,每周下载量超过 160 亿次!这些数字对于任何软件工具来说都非常厉害。所以,现在让我们讨论一下 npm 到底是什么。

NPM 是什么

npm(“Node 包管理器”)是 JavaScript 运行时 Node.js 的默认程序包管理器。

它也被称为“Ninja Pumpkin Mutants”,“Nonprofit Pizza Makers”,以及许多其他随机名称,你可以在 npm-expansions 上探索这些名称。

npm 由两个主要部分组成:

  • 用于发布和下载程序包的 CLI(命令行界面)工具
  • 托管 JavaScript 程序包的在线存储库

为了更直观地解释,我们可以将存储库 npmjs.com 视为一个物流集散中心,该中心从卖方(npm 包裹的作者)那里接收货物的包裹,并将这些货物分发给买方(npm 包裹的用户)。

为了促进此过程,npmjs.com 物流集散中心雇用了一群勤劳的袋熊(npm CLI),他们将被分配给每个 npmjs.com 用户作为私人助理。因此,dependencies(依赖项)会如下传递给 JavaScript 开发人员:

发布 JS 软件包的过程如下:

让我们看看这只袋熊如何协助想要在项目中使用 JavaScript 包的开发人员。下面我们还将看到它们(npm CLI)如何帮助开源向导将其出色的库推向世界。

package.json

每个 JavaScript 项目(无论是 Node.js 还是浏览器应用程序)都可以被当作 npm 软件包,并且通过 package.json  来描述项目和软件包信息。

我们可以将 package.json  视为快递盒子上的运输信息。

当运行 npm init  初始化 JavaScript/Node.js 项目时,将生成 package.json  文件,文件内的内容(基本元数据)由开发人员提供:

  • name:JavaScript 项目或库的名称。
  • version:项目的版本。通常,在应用程序开发中,由于没有必要对开源库进行版本控制,因此经常忽略这一块。但是,仍可以用它来定义版本。
  • description:项目的描述。
  • license:项目的许可证。

npm scripts

package.json  还支持一个 scripts  属性,可以把它当作在项目本地运行的命令行工具。例如,一个 npm 项目的 scripts部分可能看起来像这样:

{
  "scripts": {
    "build""tsc",
    "format""prettier --write **/*.ts",
    "format-check""prettier --check **/*.ts",
    "lint""eslint src/**/*.ts",
    "pack""ncc build",
    "test""jest",
    "all""npm run build && npm run format && npm run lint && npm run pack && npm test"
  }
}

eslintprettiernccjest  不是安装为全局可执行文件,而是安装在项目本地的  node_modules/.bin/  中。

最新引入的 npx  使我们可以像在全局安装程序一样运行这些 node_modules  项目作用域命令,方法是在其前面加上 npx ...(即npx prettier --write ** / *。ts)。

dependencies vs devDependencies

这两个以键值对象的形式出现,其中 npm 库的名称为键,其语义格式版本为值。大家可以看看 Github 的 TypeScript 操作模板中的示例:

{
  "dependencies": {
    "@actions/core""^1.2.3",
    "@actions/github""^2.1.1"
  },
  "devDependencies": {
    "@types/jest""^25.1.4",
    "@types/node""^13.9.0",
    "@typescript-eslint/parser""^2.22.0",
    "@zeit/ncc""^0.21.1",
    "eslint""^6.8.0",
    "eslint-plugin-github""^3.4.1",
    "eslint-plugin-jest""^23.8.2",
    "jest""^25.1.0",
    "jest-circus""^25.1.0",
    "js-yaml""^3.13.1",
    "prettier""^1.19.1",
    "ts-jest""^25.2.1",
    "typescript""^3.8.3"
  }
}

这些依赖通过带有 --save  或 --save-dev  标志的 npm install  命令安装。它们分别用于生产和开发/测试环境。在下一节中,我们将更深入地研究这些软件包的安装。

同时,理解语义版本前面的符号非常重要(假设你已经阅读 semvermajor.minor.patch  模型):

  • ^:表示最新的次版本,例如,  ^1.0.4  可能会安装主版本系列 1  的最新次版本  1.3.0
  • :表示最新的补丁程序版本,与 ^  类似,  〜1.0.4  可能会安装次版本系列  1.0  的最新次版本1.0.7

所有这些确切的软件包版本都将记录在 package-lock.json  文件中。

package-lock.json

该文件描述了 npm JavaScript 项目中使用的依赖项的确切版本。如果 package.json  是通用的描述性标签,则 package-lock.json  是成分表。

就像我们通常不会读取食品包装袋上的成分表(除非你太无聊或需要知道)一样,package-lock.json  并不会被开发人员一行一行进行读取。

package-lock.json  通常是由 npm install  命令生成的,也可以由我们的 NPM CLI 工具读取,以确保使用 npm ci  复制项目的构建环境。

用户如何使用 NPM

从前面提到的 130 万个发布的软件包中,有 160 亿次下载,可以推断出,大多数 npm 用户都朝这个方向使用 npm。所以,了解如何使用这个强大的工具会很有帮助。

npm install

这是现在我们开发 JavaScript/Node.js 应用程序时最常用的命令。

默认情况下,npm install  将安装带有 ^  版本号的软件包的最新版本。npm 项目上下文中的 npm install  将根据 package.json  规范将软件包下载到项目的 node_modules  文件夹中,从而升级软件包的版本(并重新生成 package-lock.json)。 npm install  可以基于 ^  和  版本匹配。

如果要在全局上下文中安装程序包,可以在机器的任何地方使用它,则可以指定全局标志 -g(例如 live-server)。

npm 使安装 JavaScript 软件包非常容易,以至于经常错误地使用此命令。导致一些程序员对 npm 开这样的玩笑:

但是,npm 包太大、太深这样的问题可以通过 --production  标志来拯救!在上一节中,我们讨论了分别用于生产和开发/测试环境的 dependencies  和 devDependencies  。这个 --production  标志是如何在 node_modules  中进行区别的。

通过将此标志附加到 npm install  命令,我们将仅从 dependencies  安装软件包,从而将 node_modules  的大小大大减小到应用程序正常运行所必需的大小。——不应该将 devDependencies  引入生产环境!

npm ci

因此,如果 npm install --production  对于生产环境是最佳选项,那么是否必须有一个对本地环境,测试环境最合适的选项?

答案是 npm ci

就像如果 package_lock.json  尚不存在于项目中一样,无论何时调用 npm install  都会生成它,npm ci  会消耗该文件来下载项目所依赖的每个软件包的确切版本。

这样,无论是用于本地开发的笔记本电脑还是 Github Actions 等 CI(持续集成)构建环境,我们都可以确保项目上下文在不同机器上保持完全相同。

npm audit

随着越来越多的软件包发布,并且易于安装,因此 npm 软件包容易受到恶意作者的恶意攻击,例如这些

意识到生态系统存在问题,npm.js 组织提出了 npm audit  的主意。他们维护了一个安全漏洞列表,开发人员可以使用 npm audit  命令来审核项目中的依赖项。

npm audit  为开发人员提供了有关漏洞以及是否有要修复的版本的信息,例如:

如果补救措施在下一个不间断的版本升级中可用,则可以使用 npm audit fix 来自动升级受影响的依赖项的版本。

作者如何使用 NPM

我们已经了解了作为用户,如何通过 NPM CLI 有效得使用 NPM,但是作为作者又如何使用呢?

npm publish

将软件包发送到 npmjs.com 非常容易,因为我们只需要运行 npm publish  。棘手的部分(并非专门针对 npm 软件包作者)是确定软件包的版本。

根据 semver.org 的经验法则:

  1. 当你进行不兼容的 API 更改时使用 MAJOR 版本
  2. 以向后兼容的方式添加功能时使用 MINOR 版本
  3. 进行向后兼容的 bug 修复时使用 PATCH 版本

在发布软件包时,遵循上述规则尤为重要,可以确保你不会破坏任何人的代码,因为 npm 中匹配的默认版本是^(也就是下一个次版本)。

❤️ npm ❤️ JavaScript ❤️ Node.js ❤️

了解了以上知识,我们就可以开始有效地使用 npm 并指挥可爱的袋熊大军啦!



扫码关注公众号,订阅更多精彩内容。



你点的每个赞,我都认真当成了喜欢
浏览 50
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报