[英]How to run node.js cli with experimental-specifier-resolution=node?
Our team has built a small CLI used for maintenance.我们的团队构建了一个用于维护的小型 CLI。 The package.json specifies a path for with the
bin
property, and everything works great; package.json 指定了带有
bin
属性的路径,一切正常; "bin": { "eddy": "./dist/src/cli/entry.js"}
Autocompletion is achived by using yargs@17.0.1
.自动完成是通过使用
yargs@17.0.1
的。 However we recently converted the project to use es6 modules, because of a migration to Sveltekit, ie the package.json now contains type: module
.然而,我们最近将项目转换为使用 es6 模块,因为迁移到 Sveltekit,即 package.json 现在包含
type: module
。 Because of this, the CLI now only works if we run with:因此,CLI 现在仅在我们运行时才有效:
what works什么有效
node --experimental-specifier-resolution=node ./dist/src/cli/entry.js help
However, if we run this without the flag, we get an error "module not found":但是,如果我们在没有标志的情况下运行它,我们会收到错误“找不到模块”:
Error [ERR_MODULE_NOT_FOUND]: Cannot find module...
So the question is所以问题是
Can we somehow "always" add the experimental-specifier-resolution=node
to the CLI - so we can continue to use the shorthand eddy
, and utilize auto completion?我们能否以某种方式“始终”将
experimental-specifier-resolution=node
添加到 CLI - 这样我们就可以继续使用速记eddy
并利用自动完成?
There are two probable solutions here.这里有两种可能的解决方案。
Your entry.js
file should start with a shebang like #!/usr/bin/env node
.您的
entry.js
文件应该以类似#!/usr/bin/env node
的shebang开头。 You cannot specify the flag directly here, however, if you could provide the absolute path to node directly in the shebang, you can specify the flag.您不能在这里直接指定标志,但是,如果您可以在shebang 中直接提供节点的绝对路径,则可以指定标志。
Assuming you have node installed in /usr/bin/node
, you can write the shebang in entry.js
like:假设您在
/usr/bin/node
node 中安装了/usr/bin/node
,您可以在entry.js
编写 shebang 如下:
#!/usr/bin/node --experimental-specifier-resolution=node
(Use which node
to find the absolute path) (使用
which node
查找绝对路径)
However, this is not a very portable solution.然而,这不是一个非常便携的解决方案。 You cannot always assume everyone has node installed in the same path.
您不能总是假设每个人都在同一路径中安装了节点。 Also some may use nvm to manage versions and can have multiple version in different path.
还有一些可能使用 nvm 来管理版本,并且可以在不同的路径中有多个版本。 This is the reason why we use
/usr/bin/env
to find the required node installation in the first place.这就是我们首先使用
/usr/bin/env
来查找所需节点安装的原因。 This leads to the second solution.这导致了第二种解决方案。
You can create a shell script that would intern call the cli entry point with the required flags.您可以创建一个 shell 脚本,以使用所需的标志来调用 cli 入口点。 This shell script can be specified in the
package.json
bin
section.这个 shell 脚本可以在
package.json
bin
部分中指定。
The shell script ( entry.sh
) should look like: shell 脚本 (
entry.sh
) 应如下所示:
#!/usr/bin/env bash
/usr/bin/env node --experimental-specifier-resolution=node ./entry.js "$@"
Then, in your package.json
, replace bin with:然后,在您的
package.json
,将 bin 替换为:
"bin": { "eddy": "./dist/src/cli/entry.sh"}
So when you run eddy
, it will run the entry.js
using node
with the required flag.因此,当您运行
eddy
,它将使用带有所需标志的node
运行entry.js
。 The "$@"
in the command will be replaced by any arguments that you pass to eddy
.命令中的
"$@"
将被您传递给eddy
任何参数替换。
So eddy help
will translate to /usr/bin/env node --experimental-specifier-resolution=node ./entry.js help
所以
eddy help
将转换为/usr/bin/env node --experimental-specifier-resolution=node ./entry.js help
Ensure that your CLI's tsconfig.json
is configured with these compiler options .确保您的 CLI 的
tsconfig.json
配置了这些编译器选项。 You may refer to Rapid React , a CLI I wrote in TypeScript with ES6 syntax .你可以参考Rapid React ,这是我用 ES6 语法用TypeScript编写的CLI 。
{
"compilerOptions": {
"target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
"resolveJsonModule": true, /* Allows for importing, extracting types from and generating .json files */
"declaration": false, /* Generates corresponding '.d.ts' file. */
"downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
"strict": true, /* Enable all strict type-checking options. */
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
"skipLibCheck": true, /* Skip type checking of declaration files. */
}
}
You may also refer to bin
property in this package.json which allows to run the CLI by just running rapid-react command in the terminal.您还可以参考这个package.json 中的
bin
属性,它允许通过在终端中运行快速反应命令来运行 CLI。
{
"name": "rapid-react",
"version": "...",
"description": "A light weight interactive CLI Automation Tool 🛠️ for rapid scaffolding of React apps with Create React App under the hood. ⚛️",
"main": "lib/index.js",
"scripts": {
"start": "npx nodemon --no-stdin --watch 'src/**/*.ts' --exec npx ts-node src/index.ts",
"test": "...",
"lint": "...",
"build": "...",
"prebuild": "..."
},
"files": [
"lib"
],
"repository": {
"type": "git",
"url": "https://github.com/vinaysharma14/rapid-react.git"
},
"author": "Vinay Sharma <vinaysharma7811@gmail.com> (https://www.linkedin.com/in/vinaysharma-/)",
"license": "MIT",
"bin": {
"rapid-react": "lib/index.js"
},
"keywords": [
"..."
],
"bugs": {
"url": "..."
},
"homepage": "...",
"dependencies": {
"...": "...",
},
"devDependencies": {
"...": "...",
"ts-node": "^9.0.0",
"typescript": "^4.1.2"
}
}
Just add a script to your package.json:只需在 package.json 中添加一个脚本:
Assuming index.js is your entry point and package.json is in the same directory假设 index.js 是你的入口点并且 package.json 在同一个目录中
{
"scripts": {
"start": "node --experimental-specifier-resolution=node index.js"
}
}
Then you can just run on your console:然后你可以在你的控制台上运行:
npm start
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.