如何在通过(全局)shell 脚本启动节点时禁用警告

问题描述 投票:0回答:6

我正在使用 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
在全球范围内运行该应用程序。

经过一些研究,我注意到通常有两种方法可以禁用警告:

  1. 设置环境变量
    NODE_NO_WARNINGS=1
  2. 使用
    node --no-warnings ./index.js
  3. 调用脚本

虽然我可以使用上述两种方法禁用警告,但在直接运行

myapp
命令时似乎无法做到这一点。

我在入口脚本

./index.js
中放置的shebang是:

#!/usr/bin/env node


// my code...

我还阅读了有关修改 shebang 的其他讨论,但尚未找到通用/跨平台的方法来执行此操作 - 将参数传递给节点本身,或设置 env 变量。

如果我发布这个 npm 包,如果有一种方法可以确保提前禁用这个单个包的警告,而不是让每个用户自己调整他们的环境,那就太好了。是否有任何隐藏的 npm

package.json
配置允许这样做?

任何帮助将不胜感激!

node.js npm fs
6个回答
23
投票

我现在使用启动器脚本来生成

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 });

因为这有点像黑客,所以下次我不会使用此方法,而是手动将原始 API 包装在 Promise 中,坚持

util.promisify
,或使用 API 的阻塞/同步版本。


21
投票

我像这样配置了我的测试脚本:

 "scripts": {
    "test": "tsc && cross-env NODE_OPTIONS=--experimental-vm-modules NODE_NO_WARNINGS=1 jest"
  },

注意

NODE_NO_WARNINGS=1
部分。它禁用了我从设置中收到的警告
NODE_OPTIONS=--experimental-vm-modules

更新

还应该注意的是,您不需要在测试中针对打字稿代码。事实上,您可以使用 commonjs 在 JavaScript 中编写测试,并将目标指向包含构建输出的 dist 文件夹。


10
投票

新答案:您还可以捕获脚本中发出的警告,并选择阻止记录哪些警告

const originalEmit = process.emit;
process.emit = function (name, data, ...args) {
  if (
    name === `warning` &&
    typeof data === `object` &&
    data.name === `ExperimentalWarning` 
    //if you want to only stop certain messages, test for the message here:
    //&& data.message.includes(`Fetch API`)
  ) {
    return false;
  }
  return originalEmit.apply(process, arguments);
};

灵感来自这个纱线补丁


6
投票

这是我用来使用命令行标志运行节点的方法:

#!/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)。


5
投票

我需要抑制:

实验警告:导入 JSON 模块是一项实验性功能 并且可能随时改变

这对我在 Windows、Node.js 18.x 上有效:

#!/usr/bin/env node --no-warnings

安装后

--no-warnings
添加到bin脚本内的
node
调用
.cmd
.ps

我猜这对 Linux 不起作用。我没能找到通用的解决方案

相关讨论:


0
投票

您可以随时删除正在运行的

warning
上的
process
监听器:

process.removeAllListeners('warning');

您还可以重新创建一个侦听器 (

process.on('warning', warning => ...)
),它可以捕获这些警告,并让您的进程有机会执行一些自定义行为(可能会忽略某些行为,显示其他行为......)。

© www.soinside.com 2019 - 2024. All rights reserved.