如何 运行 node.js cli with experimental-specifier-resolution=node?
How to run node.js cli with experimental-specifier-resolution=node?
我们的团队构建了一个用于维护的小型 CLI。 package.json 指定了 bin
属性 的路径,一切正常; "bin": { "eddy": "./dist/src/cli/entry.js"}
自动完成是通过使用 yargs@17.0.1
实现的。 但是 我们最近将项目转换为使用 es6 模块,因为迁移到 Sveltekit,即 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 - 以便我们可以继续使用 shorthand eddy
并利用自动完成功能?
这里有两个可能的解决方案。
解决方案 1
您的 entry.js
文件应该以像 #!/usr/bin/env node
这样的 shebang 开头。您不能在此处直接指定标志,但是,如果您可以直接在 shebang 中提供节点的绝对路径,则可以指定标志。
假设您在 /usr/bin/node
中安装了节点,您可以在 entry.js
中编写 shebang,例如:
#!/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.js
使用带有所需标志的 node
。命令中的 "$@"
将替换为您传递给 eddy
.
的任何参数
所以 eddy help
将转换为 /usr/bin/env node --experimental-specifier-resolution=node ./entry.js help
只需将脚本添加到您的 package.json:
假设 index.js 是您的入口点并且 package.json 在同一目录中
{
"scripts": {
"start": "node --experimental-specifier-resolution=node index.js"
}
}
然后您可以 运行 在您的主机上:
npm start
我们的团队构建了一个用于维护的小型 CLI。 package.json 指定了 bin
属性 的路径,一切正常; "bin": { "eddy": "./dist/src/cli/entry.js"}
自动完成是通过使用 yargs@17.0.1
实现的。 但是 我们最近将项目转换为使用 es6 模块,因为迁移到 Sveltekit,即 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 - 以便我们可以继续使用 shorthand eddy
并利用自动完成功能?
这里有两个可能的解决方案。
解决方案 1
您的 entry.js
文件应该以像 #!/usr/bin/env node
这样的 shebang 开头。您不能在此处直接指定标志,但是,如果您可以直接在 shebang 中提供节点的绝对路径,则可以指定标志。
假设您在 /usr/bin/node
中安装了节点,您可以在 entry.js
中编写 shebang,例如:
#!/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.js
使用带有所需标志的 node
。命令中的 "$@"
将替换为您传递给 eddy
.
所以 eddy help
将转换为 /usr/bin/env node --experimental-specifier-resolution=node ./entry.js help
只需将脚本添加到您的 package.json:
假设 index.js 是您的入口点并且 package.json 在同一目录中
{
"scripts": {
"start": "node --experimental-specifier-resolution=node index.js"
}
}
然后您可以 运行 在您的主机上:
npm start