Sur mes projets AdonisJS, lancer le serveur ne suffit plus toujours. Sur l'un d'eux, j'ai aussi un worker pour traiter les jobs en arrière-plan. Je finissais par ouvrir un deuxième terminal, lancer la commande, puis oublier de le faire au démarrage suivant.
J'ai ajouté un bin/dev pour démarrer les deux ensemble. Depuis la racine du projet, je lance :
./bin/devDéclarer les processus
À la racine du projet, un fichier nommé concurrently contient les commandes à exécuter :
server: node ace serve --hmr
queue: node ace queue:work --hmr --all-queuesLe serveur et le worker tournent chacun dans leur processus, avec le rechargement activé. Les noms server et queue permettent de repérer d'où viennent les logs.
Ce fichier reste propre au projet. Si j'ai besoin d'un autre processus, j'ajoute une ligne.
Le script bin/dev
Pour lancer tout ça, j'utilise concurrently. Voici le script que j'utilise :
#!/usr/bin/env sh
set -e
cd "$(dirname "$0")/.."
export NODE_ENV="${NODE_ENV:-development}"
PROCFILE="concurrently"
if [ ! -f "$PROCFILE" ]; then
echo "bin/dev: '$PROCFILE' file not found at the project root." >&2
exit 1
fi
names=""
while IFS= read -r line || [ -n "$line" ]; do
case "$line" in
'' | \#*) continue ;;
esac
name=$(printf '%s' "$line" | sed -n 's/^\([A-Za-z0-9_-]\{1,\}\):[[:space:]]\{1,\}.*$/\1/p')
if [ -n "$name" ]; then
cmd=$(printf '%s' "$line" | sed 's/^[A-Za-z0-9_-]\{1,\}:[[:space:]]\{1,\}//')
else
cmd="$line"
name="proc$(( $# + 1 ))"
fi
names="${names:+$names,}$name"
set -- "$@" "$cmd"
done < "$PROCFILE"
if [ "$#" -eq 0 ]; then
echo "bin/dev: no command declared in '$PROCFILE'." >&2
exit 1
fi
exec npx --yes concurrently@10 \
--kill-others \
--prefix "[{name}]" \
--names "$names" \
--prefix-colors "auto" \
--handle-input \
"$@"Le script se place à la racine du projet, lit les commandes et les transmet à concurrently. Il accepte aussi les lignes sans nom et ignore les lignes vides ou les commentaires commençant par #.
NODE_ENV prend la valeur development si elle n'est pas déjà définie. Une valeur fournie dans le terminal reste donc prioritaire.
Avec --kill-others, si un processus s'arrête, les autres sont arrêtés aussi. Et quand je termine ma session avec Ctrl+C, je coupe le serveur et le worker ensemble.
L'utiliser dans un projet
Une fois les deux fichiers créés, il faut rendre le script exécutable :
chmod +x bin/devJ'installe concurrently en dépendance de développement :
npm install --save-dev concurrently@10Le script passe par npx, qui utilise le package installé localement. S'il est absent, --yes autorise son téléchargement sans confirmation.
Pour garder l'habitude de taper npm run dev, on peut aussi modifier le script dans package.json :
{
"scripts": {
"dev": "./bin/dev"
}
}Dans ce cas, je garde bien node ace serve --hmr dans le fichier concurrently. Y mettre npm run dev ferait tourner le lanceur en boucle.
Ça reste un petit script, mais je n'ai plus à me rappeler les commandes de chaque projet avant de commencer à travailler.