Cada vez que ejecuto la siguiente función, espero que genere las diferentes rutas incrustadas en mi archivo composer.json y luego realice esto de forma recursiva para cada paquete. Sin embargo, me da el mismo resultado una y otra vez. Por favor, ¿qué me estoy perdiendo aquí?
const packageComposer = async (node) => { node = node ? __dirname : node; let composer = fs.readFileSync(node + '/composer.json', 'utf8'); let dependencies = Object.keys(JSON.parse(composer).require); console.log(node + '/composer.json'); dependencies.forEach(key => { let dependency = key.split('/'); let dir = node + '/vendor/' + dependency[0] + '/' + dependency[1]; if (fs.existsSync(dir)) { packageComposer(dir); } }); }El archivo Composer.json se ve así:
{ "require": { "php": ">=7.2", "alek13/slack": "^2.1", "composer/installers": "^1.7", "htmlburger/carbon-fields": "^3.3" } }Salida de la consola:
/Users/user/Desktop/github/plugin-folder/composer.json /Users/user/Desktop/github/plugin-folder/composer.json /Users/user/Desktop/github/plugin-folder/composer.json /Users/user/Desktop/github/plugin-folder/composer.json /Users/user/Desktop/github/plugin-folder/composer.json /Users/user/Desktop/github/plugin-folder/composer.json /Users/user/Desktop/github/plugin-folder/composer.json /Users/user/Desktop/github/plugin-folder/composer.json /Users/user/Desktop/github/plugin-folder/composer.json /Users/user/Desktop/github/plugin-folder/composer.json /Users/user/Desktop/github/plugin-folder/composer.json /Users/user/Desktop/github/plugin-folder/composer.json RangeError: Maximum call stack size exceeded Exception in PromiseRejectCallback: /Users/user/Desktop/github/plugin-folder/gulpfile.js:59 }Me preguntaba por qué la salida de su consola nunca muestra una ruta con /vendor porque su lógica recursiva tiene la intención de crear una ruta que tenga /vendor . Entonces, me di cuenta, eso es debido a esta lógica:
node = node ? __dirname : node; está al revés y siempre seleccionará __dirname cuando pase un valor para node . Entonces, cada llamada recursiva termina usando el mismo valor para node y, por lo tanto, un ciclo infinito que eventualmente desborda la pila.
En cambio, quieres esto:
node = node ? node : __dirname;La descripción de MDN para el operador ternario es esta:
condition ? exprIfTrue : exprIfFalseOtra forma de hacer esto es usar parámetros predeterminados y dejar que el motor JS proporcione un valor cuando no se pasa nada y escribir de esta manera:
const packageComposer = async (node = __dirname) => { ... };Para cualquier depuración adicional, podría sugerir esta versión limpia con registro que le permite seguir a dónde va:
function packageComposer(node = __dirname) { // read and parse composer.json using require() const filename = path.join(node, 'composer.json'); console.log(`About to read ${filename}`); let composer = require(filename); const dependencies = Object.keys(composer.require); console.log("Found dependencies", dependencies); for (const key of dependencies) { const pieces = key.split("/"); const dir = path.join(node, 'vendor', dependency[0], dependency[1]); if (fs.existsSync(dir)) { console.log(`Calling packageComposer(${dir}) recursively`); packageComposer(dir); } } } Como dije en mis comentarios, un par de cosas parecen extrañas aquí. Hace key.split("/") para obtener las piezas de una clave como "alek13/slack" , luego las vuelve a unir inmediatamente para reconstruir "alek13/slack" nuevamente. No estoy seguro de por qué está haciendo eso o qué espera que suceda cuando las claves no se pueden dividir y tiene una clave como "php" que no contiene un "/" .