Remarque: Cette approche modifie votre package.json
à la volée, utilisez-la si vous n'avez pas d'alternative.
J'ai dû passer des arguments de ligne de commande à mes scripts qui ressemblaient à:
"scripts": {
"start": "npm run build && npm run watch",
"watch": "concurrently \"npm run watch-ts\" \"npm run watch-node\"",
...
}
Donc, cela signifie que je démarre mon application avec npm run start
.
Maintenant, si je veux passer quelques arguments, je commencerais par peut-être:
npm run start -- --config=someConfig
Ce que cela fait est: npm run build && npm run watch -- --config=someConfig
. Le problème, c'est qu'il ajoute toujours les arguments à la fin du script. Cela signifie que tous les scripts chaînés n'obtiennent pas ces arguments (Args peut ou non être requis par tous, mais c'est une autre histoire.). De plus, lorsque les scripts liés sont appelés, ces scripts n'obtiendront pas les arguments passés. ie le watch
script n'obtiendra pas les arguments passés.
L'utilisation de la production de mon application est en tant que .exe
, donc passer les arguments dans l'exe fonctionne bien mais si vous voulez le faire pendant le développement, cela devient problématique.
Je n'ai pas trouvé de moyen approprié pour y parvenir, c'est donc ce que j'ai essayé.
J'ai créé un fichier javascript: start-script.js
au niveau parent de l'application, j'ai un "default.package.json" et au lieu de maintenir "package.json", je maintiens "default.package.json". Le but de start-script.json
est de lire default.package.json
, d'extraire scripts
et de rechercher npm run scriptname
puis d'ajouter les arguments passés à ces scripts. Après cela, il en créera un nouveau package.json
et copiera les données de default.package.json avec les scripts modifiés, puis appellera 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);
}
Maintenant, au lieu de faire npm run start
, je faisnode start-script.js --c=somethis --r=somethingElse
L'exécution initiale semble bonne, mais n'a pas été testée de manière approfondie. Utilisez-le si vous le souhaitez pour le développement d'applications.
yargs
; tous les paramètres après le--
peuvent être parfaitement analysés dans votre script.