Как соврать программе о `process.platform`? - PullRequest
0 голосов
/ 26 января 2019

Существует CLI, который работает на узле и может быть выполнен с помощью command в командной строке. В своем коде некоторые функции отключены для пользователей Windows if (process.platform === 'win32') { process.exit(1); }. Теперь я хочу отключить эту проверку и разрешить пользователям Windows использовать «скрытые» функции (обычно требуемое программное обеспечение не установлено в Windows, но у меня есть специальная настройка, где оно есть).

Есть ли способ лгать этому CLI и моделировать, что он работает, например, Linux или macOS?

Конечно, я мог бы разветвить интерфейс командной строки, снять проверку и работать со своей собственной версией - но для этого потребуется повторять этот процесс для каждого выпуска. Поскольку эта функциональность также должна быть доступна для других пользователей, мне пришлось бы публиковать разветвленный и модифицированный CLI, который может быть частым источником путаницы для его пользователей (как насчет номеров версий? Я использую тот же command?) - 99,9 % кода останется нетронутым.

Могу ли я написать свой собственный CLI, который что-то делает, чтобы «подделать» окружение, затем выполняет установленный, оригинальный CLI и впоследствии очищает?


Я создал пример пакета, который работает идентично CLI, но выполняет только ту часть, которую я исследую:

Установка через npm i -g nodejs-cli-nowin.

1 Ответ

0 голосов
/ 26 января 2019

По сути, пакет-обертка должен использоваться для предоставления точки входа вместо оригинальной упаковки.process.platform должно быть смоделировано с новым значением до запуска оригинального пакета.

wrapper-package / 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');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...