【问题标题】:How to run node.js cli with experimental-specifier-resolution=node?如何使用experimental-specifier-resolution=node 运行node.js cli?
【发布时间】:2021-06-24 07:35:44
【问题描述】:

我们的团队构建了一个用于维护的小型 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 - 这样我们就可以继续使用简写 eddy 并利用自动完成功能?

【问题讨论】:

  • 如果您的 CLI 是用 TypeScript 编写的,我可以分享解决方案。你能帮忙提供一些细节吗?您可以使用npm start 运行 CLI 吗?
  • 嗨@VinaySharma - 是的,CLI 是用 Typescript 编写的,是 mono-repo 的一部分。我们不使用 npm start 运行 CLi,而是使用 node --experimental-specifier-resolution=node ./dist/src/cli/entry.js help

标签: node.js yargs


【解决方案1】:

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

解决方案 1

您的entry.js 文件应以#!/usr/bin/env node 之类的shebang 开头。这里不能直接指定flag,但是如果可以直接在shebang中提供node的绝对路径,就可以指定flag。

假设您在/usr/bin/node 中安装了节点,您可以在entry.js 中编写shebang,例如:

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

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

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

解决方案 2

您可以创建一个 shell 脚本,用所需的标志调用 cli 入口点。这个shell脚本可以在package.jsonbin部分指定。

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 构建输出的一部分? (目前不包括在内)
  • 您可以使用 gulp 或 grunt 自动将文件复制到 dist。 (与处理图像等静态资产的方式相同)
  • 好的 - 所以我只是手动复制了文件,重建了所有内容,但仍然找不到模块..
  • 如果你试图建立一个打字稿项目,这是一场噩梦。感谢您的帮助
  • @Vivek 您确定不能将标志作为 hashbang 的一部分传递吗?它似乎对我有用。我已经成功地使用它来执行具有 ESM 和 TS 支持 here 的节点。我只在 MacOS 上对此进行了测试... 解决方案 2 我无法开始工作,因为 ./entry.js 是从 CWD 而非 bash 脚本的文件位置解析的。就我而言,这是有问题的,因为就像 OP 一样,我将其作为 NPM 包 bin 脚本执行。然后,CWD 将成为执行命令的项目根目录。
【解决方案2】:

只需将脚本添加到您的 package.json:
假设 index.js 是您的入口点,而 package.json 位于同一目录中

{
  "scripts": {
    "start": "node --experimental-specifier-resolution=node index.js"
  }
}

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

npm start

【讨论】:

  • 这没有使用 package.json 的 bin 字段
猜你喜欢
  • 2022-01-26
  • 2022-12-28
  • 2016-02-17
  • 2020-02-15
  • 2022-01-19
  • 2019-11-03
  • 2018-12-06
  • 2018-07-18
  • 2018-03-18
相关资源
最近更新 更多