通过(全局)shell脚本启动节点时如何禁用警告
Posted
技术标签:
【中文标题】通过(全局)shell脚本启动节点时如何禁用警告【英文标题】:How to disable warnings when node is launched via a (global) shell script 【发布时间】:2019-09-10 16:40:51 【问题描述】:我正在使用 node 构建一个 CLI 工具,并希望使用 fs.promise
API。但是,当应用程序启动时,总是有一个ExperimentalWarning
,这非常烦人,并且会混淆交互提示。如何禁用此警告/所有警告?
我正在 Windows 10 上使用最新的 node v10 lts 版本对此进行测试。
为了在全局范围内使用 CLI 工具,我已将此添加到我的 package.json
文件中:
//...
"preferGlobal": true,
"bin": "myapp" : "./index.js"
//...
并运行npm link
链接./index.js
脚本。然后我可以简单地使用myapp
在全球范围内运行该应用程序。
经过一些研究,我注意到通常有两种方法可以禁用警告:
-
设置环境变量
NODE_NO_WARNINGS=1
用node --no-warnings ./index.js
调用脚本
虽然我可以使用上述 2 种方法禁用警告,但在直接运行 myapp
命令时似乎无法做到这一点。
我在入口脚本./index.js
中放置的shebang是:
#!/usr/bin/env node
// my code...
我还阅读了有关修改 shebang 的其他讨论,但还没有找到一种通用/跨平台的方法来执行此操作 - 将参数传递给节点本身,或者设置 env 变量。
如果我发布这个 npm 包,如果有办法确保提前禁用这个单个包的警告,而不是让每个用户自己调整他们的环境,那就太好了。是否有任何隐藏的 npm package.json
配置允许这样做?
任何帮助将不胜感激!
【问题讨论】:
【参考方案1】:我现在使用启动器脚本来生成child_process
来解决这个限制。丑陋,但它适用于 npm link
、全局安装等等。
#!/usr/bin/env node
const spawnSync = require("child_process");
const resolve = require("path");
// Say our original entrance script is `app.js`
const cmd = "node --no-warnings " + resolve(__dirname, "app.js");
spawnSync(cmd, stdio: "inherit", shell: true );
由于它有点像 hack,我下次不会使用这种方法,而是手动将原始 API 包装在一个 Promise 中,坚持使用util.promisify
,或者使用阻塞/同步版本的API。
【讨论】:
【参考方案2】:这是我用来运行带有命令行标志的节点的内容:
#!/bin/sh
_=0// "exec" "/usr/bin/env" "node" "--experimental-repl-await" "$0" "$@"
// Your normal javascript here
第一行告诉 shell 使用 /bin/sh 来运行脚本。第二行有点神奇。对于 shell,它是一个变量赋值 _=0//
,后跟 "exec" ...
。
Node 将其视为变量赋值,后跟注释 - 因此,除了将 0 分配给 _ 的副作用之外,它几乎是一个 nop。
结果是,当 shell 到达第 2 行时,它将使用您需要的任何命令行选项执行节点(通过 env)。
【讨论】:
【参考方案3】:我这样配置我的测试脚本:
"scripts":
"test": "tsc && cross-env NODE_OPTIONS=--experimental-vm-modules NODE_NO_WARNINGS=1 jest"
,
注意NODE_NO_WARNINGS=1
部分。它禁用了我从设置 NODE_OPTIONS=--experimental-vm-modules
得到的警告
【讨论】:
以上是关于通过(全局)shell脚本启动节点时如何禁用警告的主要内容,如果未能解决你的问题,请参考以下文章
Docker 容器需要很长时间才能通过 shell 脚本启动
如何在传递 ShellCheck 时通过环境变量将 glob 传递给 shell 脚本