Примітка. Цей підхід змінює ваш режим 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
; всі параметри після--
кані можна ідеально проаналізувати у вашому сценарії.