如何使用 experimental-specifier-resolution=node 运行 Node.js 命令行界面?

14
Our团队已经构建了一个用于维护的小型CLI。package.json指定了一个路径,其中包括bin属性,一切运行良好。 "bin": { "eddy": "./dist/src/cli/entry.js"}使用yargs@17.0.1实现自动完成。 但是,最近由于迁移到Sveltekit,我们将该项目转换为使用es6模块,即现在的package.json包含type: module。因此,只有在以下情况下运行时,CLI才能正常工作: what works
node --experimental-specifier-resolution=node ./dist/src/cli/entry.js help

然而,如果我们在没有标志的情况下运行此命令,会出现“模块未找到”的错误:

Error [ERR_MODULE_NOT_FOUND]: Cannot find module...

问题是

我们是否可以在 CLI 中“始终”添加experimental-specifier-resolution=node,以便我们可以继续使用快捷方式eddy并利用自动完成功能?


如果你的CLI是用TypeScript编写的,我可以分享解决方案。还有几个细节需要帮助吗?你能用npm start运行CLI吗? - Vinay Sharma
嗨@VinaySharma - 是的,CLI是用Typescript编写的,是单一存储库的一部分。我们不使用npm start运行CLi,而是使用node --experimental-specifier-resolution=node ./dist/src/cli/entry.js help - DauleDK
2个回答

12

这里有两种可能的解决方案。

解决方案 1

您的 entry.js 文件应该以 shebang 开始,例如 #!/usr/bin/env node。您不能在此直接指定标志,但如果您可以在 shebang 中直接提供 node 的绝对路径,就可以指定标志。

假设您已经在 /usr/bin/node 中安装了 node,您可以在 entry.js 中编写 shebang 如下:

#!/usr/bin/node --experimental-specifier-resolution=node

(使用 which node 查找绝对路径)

然而,这不是一个非常便携的解决方案。您不能总是假设每个人都在相同的路径下安装了node。另外,有些人可能会使用nvm来管理版本,并且可以在不同路径中拥有多个版本。这就是为什么我们首先使用/usr/bin/env来找到所需的node安装的原因。这导致第二个解决方案。

解决方案2

您可以创建一个shell脚本,该脚本将使用所需的标志调用cli入口点。此shell脚本可以在 package.json bin 部分中指定。

shell脚本( entry.sh )应如下所示:

#!/usr/bin/env bash
/usr/bin/env node --experimental-specifier-resolution=node ./entry.js "$@"

然后,在您的package.json中,将bin替换为:

"bin": { "eddy": "./dist/src/cli/entry.sh"}

因此,当你运行eddy时,它将使用所需的标志使用node运行entry.js。命令中的"$@"将被替换为你传递给eddy的任何参数。

因此,eddy help将被翻译为/usr/bin/env node --experimental-specifier-resolution=node ./entry.js help


如何将 entry.sh 文件包含进 tsc 构建输出中?(目前它没有被包含进去) - DauleDK
你可以使用Gulp或Grunt自动将文件复制到dist目录中,就像处理静态资源(如图像)一样。 - Vivek
2
如果你想要设置一个 TypeScript 项目,这会是个噩梦。感谢您的帮助。 - Daniel Kaplan
2
@Vivek 你确定不能将标志作为哈希bang的一部分传递吗?对我来说似乎可以。我已经成功地使用它来执行具有ESM和TS支持的Node here。我只在MacOS上测试过...解决方案2无法正常工作,因为./entry.js是从CWD而不是bash脚本的文件位置解析的。在我的情况下,这是有问题的,因为像OP一样,我将其作为NPM包bin脚本执行。CWD将是执行命令的项目根目录。 - Thijs Koerselman
@ThijsKoerselman:shebang 如何处理参数是特定于操作系统的,似乎没有标准化。它可能适用于 MacOS(我没有尝试过),但我可以确认这在最近的 Ubuntu 版本上不起作用。这篇文章可能会有所帮助:https://lists.gnu.org/archive/html/bug-sh-utils/2002-04/msg00020.html - Vivek
显示剩余5条评论

-2
只需在您的 package.json 中添加一个脚本:
假设 index.js 是您的入口点,而 package.json 与其位于同一目录中。
{
  "scripts": {
    "start": "node --experimental-specifier-resolution=node index.js"
  }
}

然后你可以在控制台上运行:

npm start

2
这不是使用 package.json 的 bin 字段。 - Thijs Koerselman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接