Nota: questo approccio modifica il tuopackage.json
al volo, usalo se non hai alternative.
Ho dovuto passare argomenti della riga di comando ai miei script che erano qualcosa del tipo:
"scripts": {
"start": "npm run build && npm run watch",
"watch": "concurrently \"npm run watch-ts\" \"npm run watch-node\"",
...
}
Quindi, questo significa che inizio la mia app con npm run start
.
Ora, se voglio passare alcuni argomenti, inizierei forse:
npm run start -- --config=someConfig
Quello che fa è: npm run build && npm run watch -- --config=someConfig
. Il problema è che aggiunge sempre gli argomenti alla fine dello script. Questo significa che tutti gli script concatenati non ottengono questi argomenti (Args forse o potrebbe non essere richiesto da tutti, ma questa è una storia diversa). Inoltre, quando vengono chiamati gli script collegati, tali script non riceveranno gli argomenti passati. cioè lo watch
script non otterrà gli argomenti passati.
L'utilizzo di produzione della mia app è come .exe
, quindi passare gli argomenti in exe funziona bene ma se vuoi farlo durante lo sviluppo, diventa problematico.
Non sono riuscito a trovare un modo adeguato per raggiungere questo obiettivo, quindi questo è quello che ho provato.
Ho creato un file javascript: start-script.js
a livello padre dell'applicazione, ho un "default.package.json" e invece di mantenere "package.json", mantengo "default.package.json". Lo scopo di start-script.json
è leggere default.package.json
, estrarre scripts
e cercare, npm run scriptname
quindi aggiungere gli argomenti passati a questi script. Successivamente, ne creerà uno nuovo package.json
e copierà i dati da default.package.json con script modificati e quindi chiamerà 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);
}
Ora, invece di farlo npm run start
, lo faccionode start-script.js --c=somethis --r=somethingElse
La corsa iniziale sembra a posto, ma non è stata testata accuratamente. Usalo, se ti piace per lo sviluppo di app.
yargs
; tutti i parametri dopo il--
possono essere analizzati perfettamente nel tuo script.