| 📦 Turbo JS 91999d1 k33g 11h ago | 1 | # Lancer des commandes Node depuis l'éditeur |
| 2 | |
| 3 | Ce guide montre comment installer, formater, linter, tester et exécuter votre projet sans quitter Turbo JS. Il suppose que l'éditeur est installé et que vous avez un répertoire contenant un `package.json`. |
| 4 | |
| 5 | ## Obtenir un fichier de départ |
| 6 | |
| 7 | Lancez l'éditeur **depuis le répertoire qui contient `package.json`**, puis choisissez **JavaScript ▸ Create tools file** (`Alt-J`, puis `C`). |
| 8 | |
| 9 | Cela écrit `.turbo-js/tools.toml` avec les commandes qu'un projet Node lance le plus, et l'ouvre. Les trois premières : |
| 10 | |
| 11 | ```toml |
| 12 | [[tool]] |
| 13 | name = "~I~nstall" |
| 14 | command = "npm install" |
| 15 | output = "popup" |
| 16 | |
| 17 | [[tool]] |
| 18 | name = "~F~ormat" |
| 19 | command = "npx prettier --write ." |
| 20 | output = "popup" |
| 21 | |
| 22 | [[tool]] |
| 23 | name = "~L~int" |
| 24 | command = "npx eslint ." |
| 25 | output = "popup" |
| 26 | ``` |
| 27 | |
| 28 | Chaque `[[tool]]` devient une ligne du menu **JavaScript**, dans l'ordre d'apparition — sauf s'il nomme un `menu` à lui, ce qu'une section plus bas couvre. Le fichier est lu à chaque ouverture du menu, une modification prend donc effet immédiatement. |
| 29 | |
| 30 | ## En lancer une |
| 31 | |
| 32 | `Alt-J`, puis la lettre entre les tildes — `I` pour installer, `T` pour tester. |
| 33 | |
| 34 | **Test** ouvre aussitôt un **popup**, qui se remplit pendant que la commande tourne. Son titre porte la commande et, une fois finie, comment cela s'est passé : |
| 35 | |
| 36 | ``` |
| 37 | ┌──────────────── node --test — ok ─────────────────┐ |
| 38 | │ ✔ greets by name (1.204ms) │ |
| 39 | │ ℹ tests 1 │ |
| 40 | │ ℹ suites 0 │ |
| 41 | │ ℹ pass 1 │ |
| 42 | │ ℹ fail 0 │ |
| 43 | │ │ |
| 44 | │ [ Close ] │ |
| 45 | └────────────────────────────────────────────────────┘ |
| 46 | ``` |
| 47 | |
| 48 | | Touche | Effet | |
| 49 | | --- | --- | |
| 50 | | `↑` `↓` `PgUp` `PgDn` `Home` `End` | Parcourir la sortie | |
| 51 | | `Échap` | Le fermer — et **arrêter la commande** si elle tourne encore | |
| 52 | | `Entrée` | Le fermer | |
| 53 | |
| 54 | Une commande qui a réussi en silence — `npx prettier --write .` sur un projet déjà formaté — affiche `(no output)` plutôt qu'une boîte vide, pour qu'on la distingue d'une commande qui n'a pas démarré. |
| 55 | |
| 56 | **Run** demande d'abord, parce qu'un projet Node n'a pas de point d'entrée unique que l'éditeur pourrait connaître : |
| 57 | |
| 58 | ``` |
| 59 | ┌──────────────── Run ────────────────┐ |
| 60 | │ script, e.g. main.js │ |
| 61 | │ [ ] │ |
| 62 | └─────────────────────────────────────┘ |
| 63 | ``` |
| 64 | |
| 65 | Tapez `main.js` et appuyez sur `Entrée`. Une fenêtre de terminal s'ouvre et le script s'y exécute ; quand il finit la fenêtre reste, montrant ce qu'il a imprimé. Appuyez sur `Ctrl-W` pour la fermer. Relancez-le et la boîte se souvient du nom pour le reste de la session. |
| 66 | |
| 67 | ## Le reste du menu |
| 68 | |
| 69 | | Entrée | Ce qu'elle lance | Où | |
| 70 | | --- | --- | --- | |
| 71 | | **Install** | `npm install` — les dépendances que nomme `package.json`, dans `node_modules/` | un popup | |
| 72 | | **Format** | `npx prettier --write .` — Prettier sur tout le projet | un popup ; les fichiers ouverts sont relus ensuite | |
| 73 | | **Lint** | `npx eslint .` — ESLint sur tout le projet | un popup ; ESLint 9 a besoin d'un `eslint.config.js` | |
| 74 | | **Test** | `node --test` — le lanceur de Node lui-même sur chaque `*.test.js`, `*.spec.js` et `test/**/*.js` | un popup | |
| 75 | | **Run** | `node <script>` — le script que vous nommez | un terminal, parce qu'un script peut lire le clavier | |
| 76 | | **Start** | `npm start` — ce que dit le script `start` de `package.json` | un terminal, parce que c'est d'ordinaire un serveur | |
| 77 | |
| 78 | `npx` lance le Prettier et l'ESLint du projet lui-même quand `package.json` en dépend, et sinon les télécharge dans le cache de npm la première fois — c'est pourquoi le premier **Format** sur une machine prend quelques secondes et le second non. |
| 79 | |
| 80 | `npm install` peut prendre du temps. Le popup est modal, pendant qu'il tourne vous ne pouvez taper nulle part ailleurs ; `Échap` le ferme et arrête l'installation. |
| 81 | |
| 82 | ## Choisir où va la sortie |
| 83 | |
| 84 | Réglez `output` sur un outil : |
| 85 | |
| 86 | | `output` | Ce que vous obtenez | |
| 87 | | --- | --- | |
| 88 | | `popup` | Un dialogue qui se remplit pendant l'exécution. Le défaut. | |
| 89 | | `terminal` | Une fenêtre de terminal : les couleurs, `Ctrl-C`, et le clavier atteint le programme | |
| 90 | | `editor` | Une fenêtre d'édition une fois fini, pour fouiller avec `Ctrl-F` | |
| 91 | |
| 92 | `Run` et `Start` sont en `terminal` dans le fichier de départ, et ils sont l'exemple de la raison d'être de la clé : un popup ne peut pas répondre à un script qui lit `process.stdin`, et ne peut pas être interrompu par `Ctrl-C` pendant qu'un serveur écoute. |
| 93 | |
| 94 | Prenez `editor` quand la sortie est quelque chose à parcourir — l'arbre que `npm ls` imprime, ou un long rapport de tests que vous voulez fouiller. |
| 95 | |
| 96 | ## Une commande longue retient l'éditeur |
| 97 | |
| 98 | Un popup est modal : pendant que `npm install` tourne, vous ne pouvez taper nulle part ailleurs. `Échap` le ferme et arrête la commande. |
| 99 | |
| 100 | Si cela gêne pour une commande donnée, donnez-lui `output = "terminal"` — la fenêtre est une fenêtre ordinaire et vous pouvez continuer à travailler à côté. C'est à cela que sert la clé configurable. |
| 101 | |
| 102 | ## Ce qui arrive à vos fichiers ouverts |
| 103 | |
| 104 | `npx prettier --write .` réécrit le fichier que vous regardez, `npm install` écrit `node_modules/` et `package-lock.json` dans le répertoire, et un outil à vous peut faire n'importe quoi. Quand une commande se termine, l'éditeur **relit tous les fichiers ouverts qui n'ont pas de modifications non enregistrées**, un fichier qu'une autre commande a changé apparaît donc tel qu'il est désormais, et l'arbre du projet est rafraîchi pour qu'un nouveau fichier s'y montre. La barre d'état dit combien. |
| 105 | |
| 106 | Un fichier avec des modifications non enregistrées est **laissé tranquille**, et la barre d'état le dit aussi : |
| 107 | |
| 108 | ``` |
| 109 | Reloaded 2 files; 1 file with unsaved changes left alone |
| 110 | ``` |
| 111 | |
| 112 | C'est délibéré : votre modification et la commande sont réellement en désaccord, et ce n'est pas à l'éditeur de décider qui l'emporte. Enregistrez d'abord (`F2`) et relancez la commande, ou continuez à éditer. Avec **Format** en particulier : enregistrez, puis formatez, sinon le travail de Prettier sur ce fichier est ignoré. |
| 113 | |
| 114 | ## Ajouter vos propres commandes |
| 115 | |
| 116 | Éditez `.turbo-js/tools.toml`. Une commande va à `sh -c`, une entrée peut donc être une séquence entière : |
| 117 | |
| 118 | ```toml |
| 119 | [[tool]] |
| 120 | name = "~C~heck" |
| 121 | command = "node --check {{script, e.g. main.js}}" |
| 122 | output = "popup" |
| 123 | |
| 124 | [[tool]] |
| 125 | name = "Lint and ~t~est" |
| 126 | command = "npx eslint . && node --test" |
| 127 | output = "popup" |
| 128 | |
| 129 | [[tool]] |
| 130 | name = "~W~atch" |
| 131 | command = "node --watch {{script, e.g. server.js}}" |
| 132 | output = "terminal" |
| 133 | |
| 134 | [[tool]] |
| 135 | name = "~D~ependencies" |
| 136 | command = "npm ls --all" |
| 137 | output = "editor" |
| 138 | ``` |
| 139 | |
| 140 | Donnez à chacune une touche chaude entre tildes, et gardez-les distinctes — le menu répond à la première correspondance qu'il trouve. |
| 141 | |
| 142 | ## Mettre un outil dans un menu à lui |
| 143 | |
| 144 | Un outil qui n'a rien à voir avec JavaScript n'a pas sa place dans le menu JavaScript. Donnez-lui un `menu` : |
| 145 | |
| 146 | ```toml |
| 147 | [[tool]] |
| 148 | name = "~E~cho" |
| 149 | command = "echo TADA" |
| 150 | output = "terminal" |
| 151 | menu = "Tools" |
| 152 | |
| 153 | [[tool]] |
| 154 | name = "~U~p" |
| 155 | command = "docker compose up -d" |
| 156 | menu = "Docker" |
| 157 | |
| 158 | [[tool]] |
| 159 | name = "~D~own" |
| 160 | command = "docker compose down" |
| 161 | menu = "Docker" |
| 162 | ``` |
| 163 | |
| 164 | Cela vous donne un menu **Tools** et un menu **Docker** sur la barre, entre JavaScript et Help, dans l'ordre où les noms apparaissent pour la première fois dans le fichier. Docker contient ses deux outils. Rien à redémarrer : enregistrez le fichier et la barre suit. |
| 165 | |
| 166 | Le nom est à vous — il n'y a pas de liste où choisir. Omettez `menu` et l'outil reste dans JavaScript, où sont six des sept commandes de départ. |
| 167 | |
| 168 | ### La touche chaude est choisie pour vous |
| 169 | |
| 170 | Vous ne pouvez pas savoir, en écrivant le fichier, quelles lettres les menus propres de l'éditeur ont prises. Il le calcule donc : la première lettre du nom que rien d'autre ne revendique reçoit les tildes. |
| 171 | |
| 172 | `Tools` obtient `Alt-T`, parce que `T` est libre. Un menu appelé `Format` obtiendrait `Alt-M`, parce que `F` est à File, `o` à Options et `r` à Run. Un menu appelé `Jobs` obtiendrait `Alt-B`, parce que `J` est à JavaScript et `o` à Options. |
| 173 | |
| 174 | Écrivez les tildes vous-même — `menu = "Doc~k~er"` — et une lettre libre est conservée. Une lettre prise ne l'est pas : la barre répond au *premier* menu qui correspond à une touche, honorer votre choix rendrait donc l'un des deux menus inatteignable. Il choisit une autre lettre et ne dit rien. |
| 175 | |
| 176 | ## Variantes |
| 177 | |
| 178 | - **Votre projet utilise pnpm, Yarn ou Bun.** Remplacez `npm install` par `pnpm install`, `npx eslint .` par `pnpm exec eslint .`, et ainsi de suite. Le fichier de départ est en npm parce que npm est livré avec Node ; rien dans l'éditeur ne sait quel gestionnaire de paquets tourne. |
| 179 | - **Vous avez un seul script et jamais un autre.** Remplacez `node {{script, e.g. main.js}}` par `node main.js`, et la boîte cesse d'apparaître. Le champ est là parce qu'un fichier de départ ne peut pas savoir quel fichier est le programme. |
| 180 | - **Vos tests utilisent Vitest, Jest ou Mocha.** Remplacez `node --test` par `npx vitest run`, `npx jest` ou `npx mocha`. `npm test` marche aussi, si `package.json` a un script `test` qui n'est pas le `echo "Error: no test specified"` que npm écrit par défaut. |
| 181 | - **Vous avez lancé l'éditeur depuis un sous-répertoire.** Les commandes s'y exécutent, et `npm` cherche `package.json` là et dans les répertoires au-dessus — mais `npx prettier --write .` ne formate que ce sous-répertoire. Partez du répertoire où est `package.json`. |
| 182 | - **Le fichier contient une erreur.** Le menu affiche un `Cannot read tools` grisé à la place des commandes, et **Create tools file** est toujours là. |
| 183 | - **`npx eslint .` dit qu'il ne trouve pas de fichier de configuration.** ESLint 9 lit `eslint.config.js` ; `npm init @eslint/config@latest` en écrit un. Les projets plus anciens ont un `.eslintrc.json`, qu'ESLint 9 ne lit plus. |
| 184 | - **Vous voulez un menu du nom d'un qui existe.** `menu = "File"` vous donne un second menu File, plus loin sur la barre, avec une autre touche chaude. Rien ne l'empêche ; rien ne le recommande non plus. |
| 185 | - **Votre menu n'a pas de touche chaude.** Toutes les lettres de son nom étaient déjà prises. `F10` et les flèches l'atteignent, et la souris aussi. Renommez-le avec une lettre libre. |
| 186 | - **Vous avez mal orthographié la valeur d'`output`.** Tout le fichier est refusé et le menu dit `Cannot read tools`, en nommant l'outil et en listant ce que la valeur aurait pu être. Un repli silencieux aurait envoyé la sortie quelque part où vous ne l'aviez pas demandée. |
| 187 | |
| 188 | ## Demander une valeur à l'exécution |
| 189 | |
| 190 | `Run` le fait déjà. Le motif est un `{{libellé}}` là où va la valeur : |
| 191 | |
| 192 | ```toml |
| 193 | [[tool]] |
| 194 | name = "~A~dd a package" |
| 195 | command = "npm install {{package name}}" |
| 196 | output = "popup" |
| 197 | ``` |
| 198 | |
| 199 | La choisir ouvre une boîte titrée **Add a package** avec un champ, libellé `package name`. **Entrée** lance la commande. Échap, et rien ne se lance. Plusieurs marqueurs donnent plusieurs champs, dans leur ordre d'apparition ; **Tab** passe de l'un à l'autre. |
| 200 | |
| 201 | La valeur est citée, un chemin avec un espace reste donc un seul argument. |
| 202 | |
| 203 | ### Un champ pour plusieurs arguments |
| 204 | |
| 205 | Citer est faux quand on veut dire « mets ceci à la fin ». Ajoutez `...` dans les accolades et la valeur passe telle quelle : |
| 206 | |
| 207 | ```toml |
| 208 | [[tool]] |
| 209 | name = "Run with ~a~rguments" |
| 210 | command = "node main.js {{arguments...}}" |
| 211 | output = "terminal" |
| 212 | ``` |
| 213 | |
| 214 | Tapez `--verbose input.txt` et les deux atteignent le script comme des arguments séparés — `process.argv.slice(2)` les contient. |
| 215 | |
| 216 | ### La même valeur deux fois |
| 217 | |
| 218 | Écrivez le libellé deux fois ; on vous la demande une fois : |
| 219 | |
| 220 | ```toml |
| 221 | [[tool]] |
| 222 | name = "Test ~o~ne" |
| 223 | command = "node --test {{file}} && node --check {{file}}" |
| 224 | ``` |
| 225 | |
| 226 | ### Variantes |
| 227 | |
| 228 | - **La valeur est la même la plupart du temps.** Lancez une fois et la boîte se souvient de ce que vous avez tapé, pour le reste de la session. Ce n'est pas écrit sur le disque. |
| 229 | - **Votre commande a déjà des accolades.** `awk '{print $1}'` et `find . -exec rm {} +` sont laissés tranquilles : seules les doubles accolades demandent quelque chose. De même un `${x}` JavaScript dans une ligne `node -e` — une accolade, pas deux. |
| 230 | - **La commande demande plus de valeurs qu'il n'en tient à l'écran.** L'éditeur le dit plutôt que d'ouvrir une boîte dont le bouton OK est sous le bas du terminal. Agrandissez le terminal, ou coupez la commande en deux outils. |
| 231 | |
| 232 | ## Voir aussi |
| 233 | |
| 234 | - Chaque clé du fichier et chaque règle : [Référence des outils JavaScript](../reference/javascript-tools.md) |
| 235 | - Pourquoi Install vient en premier, et pourquoi un fichier non modifié se recharge : [Outils JavaScript](../explanation/javascript-tools.md) |
| 236 | - Les fenêtres dans lesquelles les commandes tournent : [Fenêtres de terminal](../reference/terminal.md) |