pnpm 是如何避免项目潜在 BUG 的?

原文链接:pnpm’s strictness helps to avoid silly bugs[1],2017.03.14,by Zoltan Kochan

pnpm 是如何避免项目潜在 BUG 的?

pnpm 是 Node.js 的包管理器,我已经写了一篇文章《为什么我们应该使用 pnpm》[2]介绍了。这篇文章,我想演示一下如何使用 pnpm 避免一些潜在的 BUG 的出现。

当使用 npm 时,你可以访问那些没有在项目package.json 文件中引用的包,这是因为 npm 创建了一个扁平化的 node_modules 文件夹结构。

让我通过一个例子来解释这个问题。

  • 创建一个空项目:mkdir project && npm init -y
  • 运行 npm install express --save
  • 进入刚刚创建的 node_modules 文件夹
  • 运行 ls -1 命令

会得到类似下面的输出:

accepts
array-flatten
content-disposition
content-type
cookie
cookie-signature
debug
depd
destroy
ee-first
encodeurl
escape-html
etag
express
finalhandler
forwarded
fresh
http-errors
inherits
ipaddr.js
media-typer
merge-descriptors
methods
mime
mime-db
mime-types
ms
negotiator
on-finished
parseurl
path-to-regexp
proxy-addr
qs
range-parser
send
serve-static
setprototypeof
statuses
type-is
unpipe
utils-merge
vary

大家也能看到,即使你只安装了 expressnode_modules文件夹中仍然有很多其他的包可以用。Node.js 并不关心 package.json 文件中有什么内容,你可以访问 node_modules 根目录下所有的包。所以,你甚至在不需要显式地安装这些包的情况下,就能使用它们。

假设你需要在项目中使用 debug 模块。你可以在项目中直接引用,即便你忘记把它加到 package.json文件中,项目依然能够正常工作。然后,你提交更改并发布到生产环境,生产环境中也能正常运行。但是,随着时间的推移,比如过了几周或几个月后,会有两种情况发生:

  1. debug 发布一个大版本,有新的 API。你的代码是基于 debug@1 写的,它需要一些更新才能与 debug@2 配合使用。只要 express 使用 debug@1,你就是安全的,因为 debug@1 被安装在 node_modules 根目录下。然而,express 可以随时更新 debug 依赖包的版本号,修复所有使用 debug 的地方并发布一个补丁版本之后(补丁是因为 express 本身没有任何破坏性更改)。在下次你执行 npm install 时,express 版本被更新,debug@2 被安装到 node_modules 根目录。那么项目将有问题了,即使你没有做任何更改!
  2. 另一种可能性是 express 不再使用 debug 了,从依赖项中移除并发布一个新版本。当你更新 express时,由于 debug 不再 node_modules 中了,代码也会出错

现在想象一下,你的项目不是一个 Web 程序,而是一个被许多其他人使用的软件包。如果你没有将代码中使用的软件包写在 package.json 中,那么你的软件包就像是一颗「定时炸弹」。还记得 left-pad[3] 事件吗?我可以想象未来可能会发生类似的灾难,由于忘记了依赖关系的原因。

pnpm 如何帮助避免这类错误?

与 npm 不同,pnpm 不会尝试将所有内容移动到 node_modules 的根目录下。如果你删除了上一个案例中由 npm 创建的 node_modules 文件夹,并运行 pnpm install express 命令,ls -1 之后只会在 node_modules 文件夹中打印出一个符号链接:express,没有 debug

下一次运行时,你的应用程序会立刻失败,因为它无法找到 debug 模块,这才是正确的方式!要修复项目,就需运行 pnpm install debug 命令,并且 debug 模块将被添加到 package.json 文件中(即使未传递 --save 参数,默认情况下 pnpm 会将包保存到 package.json)。有了在 package.json 中定义的 debug 模块,你可以确保它始终会被安装在 node_modules 目录下,并且能按预期与代码一块正常工作。

许多问题都是由于某些包/工具无法正常工作导致的。这些问题主要是因为这些包/工具缺少依赖项信息。甚至有些开发人员认为,在 package.json 中不包含依赖项是可以接受的,因为“npm/yarn 上是可以正常工作的”。但实际并非如此!可能今天能正常工作,明天就说不好了。

你可能不使用 pnpm,但请发布有效的软件包。如果你不使用 pnpm,请使用像 dependency-check[4] 之类的工具,在软件包发布到远程仓库前(registry)验证其依赖关系。

启用 pnpm 的 global-style 安装方式

在发布这篇文章一个月后,我发现使用 npm 也可以避免这种类型的错误!虽然这不是默认行为,但是 npm 可以以不同的布局方式安装 node_modules,其中

只有直接依赖项会显示在 node_modules 中,而它们所依赖的一切都会被展开放置在各自的 node_modules 文件夹中。

要实现这一点,只需使用 –global-style[5] 选项运行 npm 或通过 npm c set global-style true 更改其配置值。

译注:--global-style 选项已过期,代之以 --install-strategy=shallow 选项

想尝试一下 pnpm 吗?

只需通过 npm 安装 pnpm:npm install -g pnpm。并且每当你想要安装某个东西时,请使用它代替npm:pnpm i foo

此外,你可以在 pnpm 的 GitHub 仓库[6]pnpm.js.org[7] 上阅读更多信息。还可以在 Twitter 上关注 pnpm[8],或者在 pnpm Gitter 聊天室[9]寻求帮助。

参考资料

[1]

pnpm’s strictness helps to avoid silly bugs: https://www.kochan.io/nodejs/pnpms-strictness-helps-to-avoid-silly-bugs.html

[2]

《为什么我们应该使用 pnpm》: https://www.yuque.com/zhangbao/blog/why-should-we-use-pnpm

[3]

left-pad: https://www.theregister.com/2016/03/23/npm_left_pad_chaos/

[4]

dependency-check: https://www.npmjs.com/package/dependency-check

[5]

–global-style: https://docs.npmjs.com/cli/v9/using-npm/config#global-style

[6]

pnpm 的 GitHub 仓库: https://github.com/pnpm/pnpm

[7]

pnpm.js.org: https://pnpm.js.org/

[8]

在 Twitter 上关注 pnpm: https://twitter.com/pnpmjs

[9]

pnpm Gitter 聊天室: https://gitter.im/pnpm/pnpm


原文始发于微信公众号(写代码的宝哥):pnpm 是如何避免项目潜在 BUG 的?

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/243934.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!