✨ Highlights
Diese Version schließt den Kreis um drei Issues, die gegen 0.8.10–0.8.12 gemeldet wurden: den #175-GH-Pages-Asset-Pfad-Regress, den #177-Offline-Modus-<base>-Bruch und den #167-Offline-Link-Rewrite. Die Grundursache aller drei war, dass die <base>-Tag-Entscheidung über die Templates verstreut war – 0.8.13 macht den Generator zur einzigen Quelle der Wahrheit.
Als Bonus schlägt der Auto-Install-Wiederholungspfad auf der Linux-CI nicht mehr fehl für @docmd/template-summer, docmd-search und andere On-Demand-Deps, da der Post-Install-Load nun einen manuellen node_modules-Walk-up nutzt, statt sich auf Nodes veralteten require.resolve-Cache zu verlassen.
Keine Breaking Changes. Keine neue erforderliche Config. Bestehende Configs, Plugins und CI-Pipelines funktionieren unverändert.
🐛 Fix: <base>-Tag-Entscheidung im Generator zentralisiert (#175, #167, #177)
0.8.10 fügte ein unbedingtes <base href="/"> zum Layout-Template hinzu. Das behob ein Workspace-Asset-Problem, brach aber gleichzeitig drei andere Dinge:
#175(GH-Pages-Subpfad): wenn ein Benutzerurl: "https://user.github.io/repo"setzte, hätte<base>"/repo/"sein sollen, nicht"/". 0.8.10 wurde für Subpfad repariert, aber der Root-Deploy-Fall gab weiterhin das unnötige<base href="/">aus.#167(Offline-Link-Rewrite): der Markdown-Post-Prozessor schrieb/destination/im Offline-Modus korrekt zu./destination/index.htmlum, aber das<base href="/">wies den Browser dann an, diese relativen Pfade gegen den Dateisystem-Root überfile://neu zu rooten. Die Links “funktionierten” im HTML-Quelltext, schlugen aber im Browser mit 404 fehl.#177(Offline-CSS/Assets): das Öffnen vonsite/index.htmlvon der Festplatte produzierte aus den gleichen Gründen ungestylte Seiten – das<base>re-rootete./assets/css/...zum Dateisystem-Root, was 404 ergibt.
Der Fix (0.8.13): der Generator berechnet nun die kanonische <base>-Entscheidung basierend auf (isOfflineMode, siteRootAbs) und wendet sie nach dem Template-Rendering an. Templates geben selbst kein <base> mehr aus. Die Entscheidungstabelle:
| Szenario | <base> ausgegeben |
Warum |
|---|---|---|
build (online, Root-Deploy) |
nein | Relative URLs lösen gegen die Dokument-URL auf, was wir wollen |
build (online, GH-Pages-Subpfad) |
<base href="/repo/"> |
Browser muss wissen, dass es auf einem Subpfad ist |
build --offline |
nein | file://-Auflösung muss dokument-relativ sein |
file:// (direkte Festplattenansicht) |
n/a | Search-Client zeigt die hilfreiche Offline-Meldung stattdessen |
Keine Template-Änderungen für bestehende Benutzer erforderlich – die Build-Ausgabe ist nun standardmäßig korrekt. Die Änderung ist unsichtbar, sofern Sie sich nicht auf ein Template verlassen, das sein eigenes <base> ausgibt (was kein offizielles Template tat).
🔧 Auto-Install-Wiederholung überlebt jetzt Nodes veralteten Resolve-Cache
Der Auto-Install-Pfad (tryLoadAfterInstall) verwendete ein bloßes import(packageName) für den Post-Install-Load. Auf Linux-CI gab Nodes interner require.resolve-Cache ein veraltetes “not found” zurück, selbst nachdem npm install das Paket in node_modules platziert hatte. Das Ergebnis: der Build installierte @docmd/template-summer und docmd-search erfolgreich und schlug dann fehl mit Could not load @docmd/template-summer after auto-install (das war der CI-Fehler, der GH-Pages-Deployments in 0.8.12 brach).
Der Fix: ein neues manualResolvePackageEntry() durchläuft den node_modules-Verzeichnisbaum mit frischen fs.existsSync()-Prüfungen und umgeht Nodes Resolve-Cache vollständig. Der neue Ablauf ist:
- Versuche
createRequire(consumerCwd).resolve(name)(schnell, beachtet dasexports-Feld). - Falls das fehlschlägt, durchsuche von
consumerCwdaufwärts nachnode_modules/<name>/package.json(zuverlässig, cache-frei).
Als Bonus überschreibt eine neue Umgebungsvariable DOCMD_INSTALL_VERSION die in npm install <name>@<version> verwendete Version, sodass Benutzer auf eine bestimmte Version festlegen oder latest verwenden können, unabhängig davon, was lokal installiert ist.
🐛 Fix: Search-Client zeigt hilfreiche Meldung auf file://
Sowohl die Keyword-Suche als auch die semantische Suche verwenden fetch(), um Indexdateien zu laden. Browser blockieren fetch() von file://-URLs (CORS), sodass das Öffnen von site/index.html von der Festplatte Failed to load search index. zeigte – eine irreführende Fehlermeldung, die den Eindruck erweckte, etwas sei kaputt.
0.8.13 erkennt window.location.protocol === 'file:' vor jedem fetch und zeigt stattdessen eine klare Meldung:
Search requires a web server. Open this site via http://localhost instead of file:// to enable search.
Das macht die Einschränkung explizit, statt den Benutzer rätseln zu lassen, warum die Suche offline “nicht funktioniert”. Ein echter Offline-Index ist ein separates Feature (separat verfolgen, falls gewünscht).
🧹 Test- und Lint-Bereinigung
eslint.config.mjsignoriert jetzt_-präfixierte Variablen/Argumente/catched Errors (Standard-Konvention)tools/prep.jsTest-Runner streamt Test-Output live, statt ihn stillschweigend zu capturentools/simulate-consumer.mjsleerer catch-Block hat einen erklärenden Kommentarpackages/plugins/openapi/entfernte ein toterconst r = ...Binding und eine veraltete eslint-disable-Direktive- Entfernte tote
summariseTests()/extractFailures()Helfer ausprep.js(durch Streaming ersetzt)
Migration
Null. Bestehende Configs, Plugins und CI-Pipelines funktionieren unverändert. Die <base>-Änderung ist vollständig rückwärtskompatibel für jede Site, deren url-Config mit der tatsächlichen Deployment-URL übereinstimmt.
Vollständiges Changelog: https://github.com/docmd-io/docmd/compare/0.8.12...0.8.13