Примечание: этот подход изменяет вашpackage.json
на лету, используйте его, если у вас нет альтернативы.
Мне пришлось передать аргументы командной строки в мои сценарии, которые были что-то вроде:
"scripts": {
"start": "npm run build && npm run watch",
"watch": "concurrently \"npm run watch-ts\" \"npm run watch-node\"",
...
}
Итак, это означает, что я запускаю свое приложение с npm run start
.
Теперь, если я хочу передать некоторые аргументы, я бы начал с:
npm run start -- --config=someConfig
Что это делает: npm run build && npm run watch -- --config=someConfig
. Проблема в том, что он всегда добавляет аргументы в конец скрипта. Это означает, что все цепочечные сценарии не получают эти аргументы (аргументы могут быть или не быть обязательными для всех, но это другая история). Кроме того, при вызове связанных сценариев эти сценарии не будут получать переданные аргументы. то естьwatch
скрипт не получит переданные аргументы.
Производственное использование моего приложения в качестве .exe
, так что передача аргументов в exe работает нормально, но если вы хотите сделать это во время разработки, это становится проблематичным.
Я не мог найти какой-либо правильный способ достичь этого, поэтому я попробовал именно это.
Я создал файл javascript: start-script.js
на родительском уровне приложения у меня есть «default.package.json», и вместо того, чтобы поддерживать «package.json», я поддерживаю «default.package.json». Цель start-script.json
состоит в том, чтобы прочитать default.package.json
, извлечь scripts
и найти и npm run scriptname
затем добавить переданные аргументы к этим сценариям. После этого он создаст новый package.json
и скопирует данные из default.package.json с измененными сценариями, а затем вызовет npm run start
.
const fs = require('fs');
const { spawn } = require('child_process');
// open default.package.json
const defaultPackage = fs.readFileSync('./default.package.json');
try {
const packageOb = JSON.parse(defaultPackage);
// loop over the scripts present in this object, edit them with flags
if ('scripts' in packageOb && process.argv.length > 2) {
const passedFlags = ` -- ${process.argv.slice(2).join(' ')}`;
// assuming the script names have words, : or -, modify the regex if required.
const regexPattern = /(npm run [\w:-]*)/g;
const scriptsWithFlags = Object.entries(packageOb.scripts).reduce((acc, [key, value]) => {
const patternMatches = value.match(regexPattern);
// loop over all the matched strings and attach the desired flags.
if (patternMatches) {
for (let eachMatchedPattern of patternMatches) {
const startIndex = value.indexOf(eachMatchedPattern);
const endIndex = startIndex + eachMatchedPattern.length;
// save the string which doen't fall in this matched pattern range.
value = value.slice(0, startIndex) + eachMatchedPattern + passedFlags + value.slice(endIndex);
}
}
acc[key] = value;
return acc;
}, {});
packageOb.scripts = scriptsWithFlags;
}
const modifiedJSON = JSON.stringify(packageOb, null, 4);
fs.writeFileSync('./package.json', modifiedJSON);
// now run your npm start script
let cmd = 'npm';
// check if this works in your OS
if (process.platform === 'win32') {
cmd = 'npm.cmd'; // https://github.com/nodejs/node/issues/3675
}
spawn(cmd, ['run', 'start'], { stdio: 'inherit' });
} catch(e) {
console.log('Error while parsing default.package.json', e);
}
Теперь вместо того, чтобы делать npm run start
, я делаюnode start-script.js --c=somethis --r=somethingElse
Начальный прогон выглядит хорошо, но не был тщательно протестирован. Используйте его, если вам нравится разработка приложений.
yargs
; все параметры после--
могут быть проанализированы в вашем скрипте.