使用你的脚手架还需要全局安装吗,是时候更新了,来看看 npx 怎么玩吧🫣🫣🫣

由于我自己一直在维护着一个脚手架,也看到了很多脚手架的教程,但是基本都存在一个问题,都是需要执行 -g 这个命令来全局安装再进行使用的。

先不说包的大小如何,我使用这个脚手架,就是单纯用来安装一个项目的,就要我全局安装,是否有些不妥,还有另外一个情况,如果我也安装有另外一个脚手架,两个脚手架的命令重复了呢,那么这种情况下你应该如何解决。

那么接下来我们就来通过一个 demo 来讲解一下我们应该如何避免全局安装才能使用脚手架的情况。

完整代码示例可以看我的仓库代码,如果你感兴趣,你也可以加入进来

create-neat

shebang 命令

开发脚手架的话,那么必然少不了这个命令 #!/usr/bin/env node 行代码是一个特殊的指令,被称为 shebang。在 Unix 和类 Unix 系统中,这一指令用于指定脚本的解释程序。

作用是告诉系统使用 env 命令来查找 node 并用其来执行脚本。这是一种跨平台的方法,能确保无论 node 安装在何处,脚本都能被正确执行。

接下来我们来了解一下这条指令的组成部分:

  1. #!:这是 shebang 的标记,用于告诉操作系统该行后面的路径是用来执行文件的解释器。

  2. /usr/bin/env:这是 env 命令的路径。env 是一个用于运行指定命令的程序,同时将当前环境传递给该命令。使用/usr/bin/env 而不是直接指向解释器(例如/usr/bin/node)的路径,可以使脚本更加灵活,因为它不依赖于解释器的固定安装位置。

  3. node:这指示 env 命令查找环境中可用的 node 解释器,并使用它来执行脚本。

当你在脚本文件的第一行添加 #!/usr/bin/env node,并给予该文件执行权限(例如,通过运行 chmod +x index.js 命令),你就可以直接从命令行运行该脚本,而无需在命令前显式指定 node 命令,例如:

./index.js

使用你的脚手架还需要全局安装吗,是时候更新了,来看看 npx 怎么玩吧🫣🫣🫣

最终文件就成功地被我们执行了,而不是像我们往常一样要执行这样的命令:

node index.js

这样做的好处是提高了脚本的可移植性和灵活性,特别是在处理不同环境和系统配置的情况下。

package.json 文件中的 bin 字段

package.json 文件中的 bin 字段是用于指定一个或多个可执行文件的映射。当你的 npm 包安装为全局包时(使用 npm install -g),这些指定的可执行文件会被链接到系统路径中,使得用户可以直接通过命令行调用它们,而不需要指定文件的完整路径。这对于创建 CLI(命令行接口)工具特别有用。

bin 字段可以是一个字符串或一个对象:

  1. 如果只有一个可执行文件,可以直接将 bin 设置为该文件的路径字符串。

  2. 如果包含多个可执行文件,bin 则应该是一个对象,键是希望用户在命令行中使用的命令名,值是文件的相对路径。

{
  "name": "moments",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "bin": {
    "moments": "./index.js"
  }
}

在之前的代码中,我们在 package.json 文件中添加一个对象,其中 m 的值是 ./index.js 的路径,接下来我们应该模仿全局安装的场景了:

npm link

通过 link 将文件 link 到全局环境下, 这就模拟了我们平常使用 -g 命令来安装脚手架的情况下。

使用你的脚手架还需要全局安装吗,是时候更新了,来看看 npx 怎么玩吧🫣🫣🫣

这个时候,我们无聊在终端的哪个位置都能执行 moments 这个命令来执行 index.js 这个文件了。

npx 和 bin 的关系

npx 与 package.json 文件中的 bin 字段有着密切的关联,主要体现在 npx 能够让你轻松地执行 npm 包中定义的可执行文件,无论这些包是全局安装的、局部安装的还是甚至未被安装。

当你在一个项目中局部安装一个 npm 包,并且这个包在其 package.json 的 bin 字段中定义了一个或多个可执行文件,这些可执行文件会被链接到当前项目的 ./node_modules/.bin/ 目录下。正常情况下,如果你想要执行这些命令,你需要提供完整的路径(例如,./node_modules/.bin/some-command)。但是,npx 允许你直接通过命令名执行这些文件,即使它们仅在项目的 node_modules 目录中可用。

使用你的脚手架还需要全局安装吗,是时候更新了,来看看 npx 怎么玩吧🫣🫣🫣

这些当我们执行 npx xxx 都是可以运行的,例如当我们执行 npx rollup:

使用你的脚手架还需要全局安装吗,是时候更新了,来看看 npx 怎么玩吧🫣🫣🫣

npx 的另一个关键特性是它允许你执行未被全局安装或局部安装的 npm 包中的命令。npx 会在需要时临时安装这些包并执行其中的命令。这种能力部分依赖于 npm 包的 bin 字段,因为 npx 需要知道哪个文件是可执行的。

例如我们要使用大名鼎鼎的 create-neat 这个脚手架(为什么说大名鼎鼎呢,因为是我开发的,我也天天使用,那么它必然是大名鼎鼎啊)它在其 package.json 的 bin 字段中指定了一个可执行文件。通常,你可能会全局安装这个包(npm install -g create-neat)以便使用它提供的命令。但是,npx 允许你直接执行:

npx create-neat moment

在这个例子中,npx 会检查 create-neat 是否在本地安装。如果没有,npx 会临时安装 create-neat,然后使用它的 bin 指定的可执行文件来创建一个新的 React 应用。这个过程避免了需要全局安装包,同时确保了你总是在使用该工具的最新版本。其实这个最新版的也很重要,因为我们全局安装的可能有些存在的 bug,但是 npm 包上发布了最新版本并且修复了这个 bug,如果你没有关注人家包的最新动态,那么这个 bug 就只有你自己来慢慢摸索了。

使用你的脚手架还需要全局安装吗,是时候更新了,来看看 npx 怎么玩吧🫣🫣🫣

因为这个包我在写之前就有用过了,所以也就不需要安装了,我们再换一个,使用 create-next-app 来

使用你的脚手架还需要全局安装吗,是时候更新了,来看看 npx 怎么玩吧🫣🫣🫣

当你使用 npx 来执行一个脚手架命令(或任何 npm 包中的命令)时,如果该包没有在你的系统上安装,npx 会临时安装所需的包到一个临时目录中。执行完成后,npx 确实会自动清理并删除这个临时安装的包。这样的设计使得 npx 非常适合执行一次性的命令,如脚手架初始化项目的命令,而不会在用户的系统上留下任何额外的安装包。

当安装完成的时候,就会根据 create-neat 这个 bin 命令来执行可执行命令:

使用你的脚手架还需要全局安装吗,是时候更新了,来看看 npx 怎么玩吧🫣🫣🫣

请确保 npm 包名和 bin 的命令相同,这样才能开始执行我们的文件。

总结

npx 提供了一种非常便捷的方式来执行 npm 包中的命令,尤其是对于那些你可能只需要偶尔运行一次的命令,而无需永久安装在你的系统中。

除了 npx 之外,其他包管理工具也可以执行同样的操作。

例如 npm,这个前提需要你的包名是 create-xxx 这样的形式的:

npm init neat my-app

我们也可以使用 pnpm 来执行:

pnpm dlx create-neat my-app

使用你的脚手架还需要全局安装吗,是时候更新了,来看看 npx 怎么玩吧🫣🫣🫣

这里,dlx 是 pnpm 提供的一个命令,用于在不永久安装包的情况下执行 npm 包。这与 npx 类似。

我们还可以使用 pnpm create 命令,这为 pnpm 用户提供了一个与 npm init 类似的快速创建新项目的方式。例如:

pnpm create neat my-app

使用你的脚手架还需要全局安装吗,是时候更新了,来看看 npx 怎么玩吧🫣🫣🫣

执行脚手架的方法多着呢,这种方法完全不需要我们全局安装,目前我看到的脚手架,似乎只有 nest-cli 适合全局安装的,因为它可以提供给我们快速创建文件。

最后分享两个我的两个开源项目,它们分别是:

这两个项目都会一直维护的,如果你也喜欢,欢迎 star 🥰🥰🥰

原文链接:https://juejin.cn/post/7342766597243944995 作者:Moment

(0)
上一篇 2024年3月6日 上午10:15
下一篇 2024年3月6日 上午10:26

相关推荐

发表回复

登录后才能评论