4.7 KiB
Solution : Squelette de l'extension Firefox
Problème résolu
Poser la structure minimale d'une extension Firefox (Manifest V3, sans build
step, vanilla JS) chargeable en module temporaire via about:debugging sur
NixOS (pas de signature requise en dev). Le clic sur l'icône doit ouvrir une
page dédiée autonome — la future liste agrégeant l'Atelier du Huit et la
ville de Cugnaux. Ce squelette ne récupère aucune donnée : il câble la chaîne
icône → page.
Approche choisie
Entre les deux options du corps de tâche (action.default_popup ou page
dédiée), on retient la page dédiée ouverte dans un onglet via
background.js :
- « liste autonome » = vraie page plein écran, lisible, rechargeable, non contrainte aux ~600 px d'un popup qui se ferme à la perte de focus.
- Cela donne un rôle concret à
background.scripts(clé Firefox explicitement demandée) : écouteraction.onClickedet fairetabs.create. - Contrainte MDN confirmée :
action.onClickedne se déclenche pas sidefault_popupest défini → on n'ajoute pasdefault_popup.
Pas de dépendance runtime. Tests de forme avec bun test à la racine,
web-ext lint en contrôle dev optionnel via bunx (zéro dépendance ajoutée).
Décisions clés
- Sous-dossier
extension/: isole l'extension chargeable (ce que voitabout:debugging) du tooling bun resté à la racine (tests,package.json). Séparation des concerns nette. strict_min_version: "127.0": avant Firefox 127, leshost_permissionsétaient optionnelles (non accordées à l'install). Le seuil 127 garantit qu'elles sont accordées dès l'installation.- Namespace
browser.*(API Firefox native, basée promesses) — jamaischrome.*. Cohérent dans tout le code. - Permission
tabsvolontairement omise :tabs.createne la requiert pas. Principe du moindre privilège. - Icône SVG unique mappée sur les tailles
48/96: accepté par Firefox, low-tech. browser_specific_settings.gecko.idprésent : identité stable de l'extension.
Patterns à réutiliser
Listener onClicked au niveau racine (synchrone) — l'event page MV3 peut
être déchargée ; enregistrer le listener à la racine de background.js (jamais
dans un callback async) garantit qu'il est rattaché au réveil :
// extension/background.js
browser.action.onClicked.addListener(() => {
browser.tabs.create({ url: browser.runtime.getURL("liste.html") });
});
browser.runtime.getURL(...) plutôt qu'une URL concaténée : robuste et sûr.
Test de forme du manifeste (garde-fous structurels) — bun test valide la
structure sans navigateur, dont le garde-fou anti-régression default_popup
absent :
const manifest = await Bun.file(join(extensionDir, "manifest.json")).json();
test("ne définit PAS default_popup (sinon onClicked devient muet)", () => {
expect(manifest.action.default_popup).toBeUndefined();
});
test("demande les host_permissions des deux sources", () => {
expect(manifest.host_permissions).toEqual([/* URLs exactes, ordre vérifié */]);
});
Vérifier aussi l'existence des ressources référencées (existsSync).
Pièges à éviter
default_popup+onClickedincompatibles : ajouterdefault_popuprendonClickedmuet → la page ne s'ouvre plus. Protégé par un test dédié.host_permissions< FF127 : sansstrict_min_version: "127.0", elles ne sont pas accordées à l'install.- Listener dans un callback async : peut être manqué au réveil de l'event page. Toujours au niveau racine.
- Module temporaire volatil : un add-on chargé via
about:debuggingdisparaît au redémarrage de Firefox → à recharger (nature dev, documentée dans le README). - Ressource d'icône manquante : si l'icône SVG n'est pas fournie, retirer
les clés
icons/action.default_iconsinon erreur de ressource au lint. - Worktree sans baseline : le worktree n'héritait pas du README/
docs/canoniques. Résolu par rebase surmainune fois la baseline réelle commitée (328df2d). Penser à vérifier la baseline avant de dupliquer des fichiers. - Warning
MISSING_DATA_COLLECTION_PERMISSIONS(web-ext) : non bloquant ici, mais Firefox recommande désormaisgecko.data_collection_permissions: { "required": ["none"] }pour une extension sans collecte — à prévoir pour les prochaines. - Diagnostics IDE
bun:test:bun testtourne sanstsconfig, mais l'éditeur signaleCannot find module 'bun:test'faute debun-types. Purement cosmétique (aucun impact runtime).
Tags
tags: [firefox-extension, manifest-v3, webextension, vanilla-js, bun-test, web-ext, low-tech, nixos]