node.js - 如何对“process.platform”撒谎?
问题描述
有一个在 Node 上运行的 CLI,可以通过command
命令行执行。在其代码中,Windows 用户禁用了某些功能if (process.platform === 'win32') { process.exit(1); }
。现在我想禁用此检查,并允许 Windows 用户使用“隐藏”功能(通常所需的软件没有安装在 Windows 上,但我有一个特殊的设置)。
有什么方法可以欺骗这个 CLI 并模拟它在例如 Linux 或 macOS 上运行吗?
当然,我可以分叉 CLI,删除检查并使用我自己的版本 - 但这需要为每个版本重复此过程。由于此功能也应该可供其他用户使用,我将不得不发布分叉和修改后的 CLI,这可能是其用户经常混淆的原因(版本号呢?我使用相同的command
吗?) - 99.9%代码将保持不变。
我是否可以编写自己的 CLI,做一些“伪造”环境的操作,然后执行已安装的原始 CLI,然后进行清理?
我创建了一个与 CLI 相同的示例包,但只执行我正在调查的部分:
通过安装npm i -g nodejs-cli-nowin
。
解决方案
基本上,应该使用 wrapper 包而不是原始包来提供入口点。process.platform
应该在原始包运行之前用新值模拟。
包装器包/index.js
Object.defineProperty(process, 'platform', { value: 'linux' });
require('original-package/bin/entry-point.js');
如果原始包生成子进程,这不会影响子进程。
这并不能保证该包将按预期在模拟平台上工作,很有可能它不会。即使包本身工作正常,这也可能导致依赖于process.platform
.
为了process.platform
只影响特定模块,platform
全局应该被局部变量遮蔽。为此,应修改模块包装函数:
const Module = require('module')
const escapedPatchedModulePath = require.resolve('original-package/module-to-patch.js')
.replace(/\\/g, '\\\\');
Module.wrapper[0] += `
const isPatchedModule = __filename === "${escapedPatchedModulePath}";
let process = isPatchedModule
? Object.create(global.process, { platform: { value: 'linux' } })
: global.process;
`;
require('original-package/bin/entry-point.js');
推荐阅读
- node.js - Typegoose + nestjs + mongodb:索引未使用@index 装饰器创建
- java - 直接从 Java 创建数据库和表
- python - root.after() 循环在一个分配的时间内循环两次
- function - 为什么这个运动功能不能正常工作?(LUA/Corona SDK)
- javascript - 如何使用 Vanilla Javascript 在另一个 html 文件中包含一个 html 文件?
- c - 了解数组中的增量 (v6++)[4] = v9;
- macos - 关闭窗口时未调用 macOS/SwiftUI onDisappear
- google-sheets - 谷歌表格条件格式基于单元格直接 NEXT 到,跨整行
- c# - 拖动以统一移动并按住触摸以保持相同方向移动
- mysql - AWS MySQL RDS 在拥有所有权限时无法创建新的数据库用户