首页 > 解决方案 > 如何使用experimental-specifier-resolution=node 运行node.js cli?

问题描述

我们的团队构建了一个用于维护的小型 CLI。package.json 为该bin属性指定了一个路径,一切正常;"bin": { "eddy": "./dist/src/cli/entry.js"}

自动完成是通过使用来实现的yargs@17.0.1然而,由于迁移到 Sveltekit,我们最近将项目转换为使用 es6 模块,即 package.json 现在包含type: module. 正因为如此,CLI 现在只有在我们运行时才有效:

什么有效

node --experimental-specifier-resolution=node ./dist/src/cli/entry.js help

但是,如果我们在没有标志的情况下运行它,我们会得到一个错误“找不到模块”:

Error [ERR_MODULE_NOT_FOUND]: Cannot find module...

所以问题是

我们能否以某种方式“总是”将 ' 添加experimental-specifier-resolution=node到 CLI - 这样我们就可以继续使用速记eddy,并利用自动完成功能?

标签: node.jsyargs

解决方案


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

解决方案 1

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

假设你已经安装了节点/usr/bin/node,你可以像这样写 shebang entry.js

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

which node用于查找绝对路径)

但是,这不是一个非常便携的解决方案。您不能总是假设每个人都将节点安装在同一路径中。还有一些可能使用 nvm 来管理版本,并且可以在不同的路径中有多个版本。这就是我们/usr/bin/env首先使用查找所需节点安装的原因。这导致了第二种解决方案。

解决方案 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,它将使用所需的标志运行entry.jsusing 。node命令中的"$@"将被您传递给的任何参数替换eddy

所以eddy help将翻译为/usr/bin/env node --experimental-specifier-resolution=node ./entry.js help


推荐阅读