Distribuer l'outil comme un binaire Go autonome
serve.py supposait Python installé et une commande tapée dans un terminal depuis le dossier du dépôt. L'objectif ici : poser l'exécutable et son planning dans un dossier synchronisé, et les retrouver sur n'importe quelle machine sans rien installer. Le binaire embarque l'interface, expose les mêmes routes sur le même format, et cherche son projets.json à côté de lui. Compilé avec CGO_ENABLED=0, il ne dépend d'aucune bibliothèque système, pas même de la glibc ; build.sh produit les cinq plateformes depuis une seule machine. Le front est inchangé : les modules ES sont embarqués et servis tels quels, et --dev les sert depuis le disque pour développer sans recompiler. Deux ajustements dictés par le double-clic, où aucun drapeau ne peut être passé : le port se cherche à partir de 8000 s'il est occupé, et le fichier de données est résolu depuis l'exécutable et non depuis le répertoire courant. La décision 3 est rectifiée au passage : elle affirmait à tort que la File System Access API ne fonctionne pas depuis file://. Vérification faite, c'est CORS sur les modules ES qui ferme cette voie, pas la sécurité de l'API. serve.py est supprimé, le binaire l'ayant remplacé en usage réel. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -44,11 +44,20 @@ décision 4).
|
||||
La première approche envisagée était d'écrire directement dans le fichier depuis le navigateur, via
|
||||
`showOpenFilePicker` / `createWritable`, pour se passer de tout back-end.
|
||||
|
||||
Sauf que cette API exige un **contexte sécurisé** : elle ne fonctionne pas depuis `file://`. Il
|
||||
fallait donc de toute façon lancer un serveur statique. Le « zéro back-end » était perdu d'avance,
|
||||
tout en payant trois prix : limitation aux navigateurs Chromium, re-autorisation du sélecteur de
|
||||
fichier à chaque session, et maintien d'un chemin de repli export/import pour Firefox et Safari,
|
||||
doublé d'un miroir `localStorage`.
|
||||
> **Rectification (1ᵉʳ août 2026).** Le paragraphe suivant affirmait que l'API « ne fonctionne pas
|
||||
> depuis `file://` ». C'est faux, et la vérification sur Chromium 150 le montre : `file://` **est**
|
||||
> un contexte sécurisé (`isSecureContext === true`), `showSaveFilePicker` y ouvre bien son
|
||||
> dialogue, et `localStorage` comme IndexedDB y persistent d'une session à l'autre — un handle
|
||||
> peut donc y être mémorisé. Ce qui bloque réellement en `file://`, c'est autre chose : les
|
||||
> **modules ES** et `fetch` y sont interdits par CORS (origine `null`), donc c'est la décision 10
|
||||
> qui ferme cette voie, pas la sécurité de l'API. La conclusion ci-dessous — lancer un serveur —
|
||||
> reste la bonne, mais pour ce motif-là. Voir décision 22.
|
||||
|
||||
Cette API exige un **contexte sécurisé**, et l'on avait cru qu'elle ne fonctionnait pas depuis
|
||||
`file://`. Il fallait donc de toute façon lancer un serveur statique. Le « zéro back-end » était
|
||||
perdu d'avance, tout en payant trois prix : limitation aux navigateurs Chromium, re-autorisation du
|
||||
sélecteur de fichier à chaque session, et maintien d'un chemin de repli export/import pour Firefox
|
||||
et Safari, doublé d'un miroir `localStorage`.
|
||||
|
||||
Puisqu'une commande doit être lancée dans tous les cas, autant qu'elle serve à quelque chose. Un
|
||||
serveur de la bibliothèque standard, `GET` et `PUT` sur `/api/data`, tient en une centaine de lignes
|
||||
@@ -132,6 +141,13 @@ compilation obsolète.
|
||||
Node n'est utilisé que pour lancer les tests, via son lanceur intégré (`node --test`), sans aucune
|
||||
dépendance.
|
||||
|
||||
**Portée après la décision 22.** Le serveur se compile désormais, mais le front, lui, ne se
|
||||
compile toujours pas : aucun bundler, aucune transformation, aucun `node_modules`. Les fichiers de
|
||||
`js/` sont embarqués tels quels dans le binaire et servis tels quels au navigateur — c'est bien la
|
||||
ligne qu'on lit dans l'éditeur qui s'exécute, et `--dev` les sert directement depuis le disque.
|
||||
Ce qui était visé ici est donc intact ; ce qui change, c'est seulement la façon dont le serveur est
|
||||
distribué.
|
||||
|
||||
## 11. Un en-tête à trois bandes, la semaine pour grain le plus fin
|
||||
|
||||
L'en-tête affichait une seule rangée de graduations dont le contenu changeait selon le
|
||||
@@ -439,3 +455,48 @@ même si l'on ferme le panneau sans rien saisir. Il porte alors le nom
|
||||
« Nouveau projet », se voit sur la frise, et se supprime d'un clic depuis son
|
||||
propre panneau — ce qui reste moins coûteux que d'imposer un dialogue à tout le
|
||||
monde à chaque création.
|
||||
|
||||
## 22. Un binaire Go plutôt qu'un script Python
|
||||
|
||||
`serve.py` supposait Python installé et une commande tapée dans un terminal, depuis le dossier du
|
||||
dépôt. C'est une friction quotidienne pour un outil qu'on veut ouvrir d'un geste, et un obstacle
|
||||
net sous Windows, où Python est absent par défaut.
|
||||
|
||||
L'objectif visé : **poser l'outil et son planning dans un dossier synchronisé, et les retrouver
|
||||
sur n'importe quelle machine**. Trois voies menaient là.
|
||||
|
||||
**Un `index.html` autonome en `file://`.** Séduisante — zéro exécutable, longévité maximale — mais
|
||||
elle impose de renoncer aux modules ES, bloqués par CORS depuis `file://` (voir la rectification en
|
||||
décision 3), donc de concaténer les sources en un fichier unique. Et surtout elle enferme dans
|
||||
Chromium : Firefox et Safari n'implémentent pas la File System Access API.
|
||||
|
||||
**Tauri.** Accès direct au disque, sans dialogue ni permission, et le code du navigateur reste
|
||||
intact. Mais un webview système à installer sous Linux (WebKitGTK), un rendu à vérifier sur trois
|
||||
moteurs différents, une chaîne Rust et une intégration continue multi-OS pour produire les
|
||||
binaires. C'est contradictoire avec la décision 10 : une chaîne Tauri de 2026 ne se recompilera pas
|
||||
aussi sûrement dans dix ans qu'un fichier HTML s'ouvrira.
|
||||
|
||||
**Un binaire Go qui contient le serveur et l'interface**, retenu. Il conserve exactement
|
||||
l'architecture éprouvée — mêmes routes, même fichier JSON, mêmes sauvegardes horodatées, front
|
||||
inchangé — en supprimant la seule vraie friction, l'installation. `CGO_ENABLED=0` produit un
|
||||
exécutable statique de 6 Mo qui ne dépend de rien, pas même de la glibc, et les cinq plateformes se
|
||||
compilent depuis une seule machine sans intégration continue.
|
||||
|
||||
Face à `file://`, il garde **tous** les navigateurs et les modules ES. Face à Tauri, il n'exige
|
||||
aucun webview et divise l'outillage par dix. Ce qu'il concède : l'interface s'ouvre dans un onglet
|
||||
plutôt que dans une fenêtre d'application, et il faut un binaire par plateforme.
|
||||
|
||||
Deux choix de détail méritent d'être notés.
|
||||
|
||||
Le port n'est plus fixe : lancé par un double-clic, l'utilisateur n'a aucun moyen de passer
|
||||
`--port` si 8000 est occupé. Le serveur essaie donc les dix premiers ports libres à partir de 8000.
|
||||
Un `--port` explicite, lui, n'est jamais contourné — c'est un choix de l'utilisateur.
|
||||
|
||||
Le fichier de données est cherché **à côté de l'exécutable**, pas dans le répertoire courant, qui
|
||||
est imprévisible lors d'un double-clic. Le mode `--dev` fait exception : il sert l'interface depuis
|
||||
le disque et lit `data/projets.json`, pour qu'un rafraîchissement suffise à voir ses modifications
|
||||
sans recompiler.
|
||||
|
||||
`serve.py` a été supprimé une fois le binaire validé en usage réel. Il n'y avait rien à migrer : le
|
||||
format du fichier et les routes sont identiques, et son historique reste dans git si le besoin de
|
||||
le relire se présentait.
|
||||
|
||||
Reference in New Issue
Block a user