-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Kurzbeschreibung
Das Template soll out-of-the-box TSX (.tsx) unterstützen, sodass UI-Komponenten (z. B. Overlays, Panels, Dialoge) komfortabel und typisiert gebaut und in Userscripts gerendert werden können. Ziel ist ein schlankes, optionales Setup mit Preact als Default (für minimale Bundlegröße) und der Möglichkeit, auf React umzuschalten.
Motivation
- Moderne Userscripts profitieren stark von wiederverwendbaren UI-Komponenten und State-Management via Hooks.
- TSX erhöht Lesbarkeit und Wartbarkeit gegenüber imperativem DOM-Code.
- Das Projekt nutzt bereits Vite und TypeScript; TSX lässt sich mit minimalen Anpassungen integrieren.
- Durch Preact bleibt das Bundle klein; bei Bedarf kann React nahtlos verwendet werden.
Ziele/Nutzen
- .tsx-Dateien werden ohne zusätzliche manuelle Konfiguration kompiliert.
- Beispiel-Komponente und Mount-Helper inklusive (Shadow DOM optional für CSS-Isolation).
- Dokumentation: Kurzanleitung zur Verwendung, Umschalten zwischen Preact und React, Hinweise zu Userscript-Besonderheiten.
- Keine Breaking Changes für bestehende TS-only Nutzer.
Vorgeschlagene Umsetzung (Technische Details)
- Dependencies
- Default (empfohlen): Preact
- Dependencies: preact
- Dev-Dependencies: @types/tampermonkey (für Typen), optional eslint-Plugins falls gewünscht
- Optional: React
- Dependencies: react, react-dom
- Dev-Dependencies: @types/react, @types/react-dom
- tsconfig.json anpassen
- Automatisches JSX-Runtime aktivieren, Tampermonkey-Typen hinzufügen.
Code (tsconfig.json – Preact-Default)
{
"compilerOptions": {
"target": "es2020",
"module": "esnext",
"moduleResolution": "bundler",
"jsx": "react-jsx",
"jsxImportSource": "preact",
"strict": true,
"isolatedModules": true,
"skipLibCheck": true,
"types": ["tampermonkey", "vite/client"]
}
}
Hinweis für React: "jsxImportSource" kann entfallen oder auf "react" gesetzt werden.
- Vite-Config anpassen
- Für Preact entweder Alias für React-Kompatibilität ODER ausschließlich preact/jsx-runtime über jsxImportSource.
- Falls später React-Code/Libs erwartet werden: Alias aktivieren.
Code (vite.config.ts – Alias für Preact-Kompatibilität)
import { defineConfig } from "vite";
export default defineConfig({
resolve: {
alias: {
react: "preact/compat",
"react-dom": "preact/compat",
"react/jsx-runtime": "preact/jsx-runtime"
}
},
build: {
// Userscripts profitieren von einem einzelnen Bundle
target: "es2020",
sourcemap: false
}
});
- Beispiel-Komponente und Mounting
- Beispiel zeigt: Shadow DOM optional zur Stil-Isolation; einfache Einbindung in bestehendes Template (src).
Code (src/components/Hello.tsx)
import { useState } from "preact/hooks";
export function Hello(): JSX.Element {
const [count, setCount] = useState(0);
return (
<div
style={{
position: "fixed",
bottom: "16px",
right: "16px",
zIndex: 999999,
background: "white",
color: "#111",
border: "1px solid #ddd",
borderRadius: "8px",
padding: "12px",
boxShadow: "0 4px 16px rgba(0, 0, 0, 0.15)",
fontFamily: "system-ui, -apple-system, Segoe UI, Roboto, sans-serif"
}}
>
<div style={{ marginBottom: "8px" }}>Hello from TSX 👋</div>
<button
onClick={() => setCount((c) => c + 1)}
style={{
border: "1px solid #ccc",
background: "#f5f5f5",
borderRadius: "6px",
padding: "6px 10px",
cursor: "pointer"
}}
>
Clicked {count}x
</button>
</div>
);
}
Code (src/utils/mount.ts – optionaler Shadow-DOM-Mount)
export function mountInShadowRoot(id = "usp-root"): {
root: HTMLElement;
shadow: ShadowRoot;
} {
const host = document.createElement("div");
host.id = id;
document.documentElement.appendChild(host);
const shadow = host.attachShadow({ mode: "open" });
const root = document.createElement("div");
shadow.appendChild(root);
return { root, shadow };
}
Code (src/index.ts – Render-Einstieg)
import { render } from "preact";
import { Hello } from "./components/Hello";
import { mountInShadowRoot } from "./utils/mount";
// Optional: Shadow DOM für CSS-Isolation
const { root } = mountInShadowRoot("usp-root");
// Alternativ ohne Shadow DOM:
// const root = document.createElement("div");
// document.body.appendChild(root);
render(<Hello />, root);
- Build/Metadata
- Bestehende Header-Generierung (header.config.json / tools) beibehalten.
- Bundling von Preact ins Userscript (Default) für Zero-Config-Nutzung.
- Optional: Dokumentation, wie man Preact/React via @require externalisiert (CDN) und Header entsprechend ergänzt, falls Bundle-Größe kritisch ist.
- Dokumentation
- README ergänzen:
- Wie TSX-Komponenten erstellt und gerendert werden
- Umschalten Preact ↔ React (Dependencies, tsconfig, Aliases)
- Hinweise zu Shadow DOM, CSS-Strategien (CSS-Module, Inline-Styles, GM_addStyle)
- Kompatibilitätshinweise für Tampermonkey/Violentmonkey/GreaseMonkey
Akzeptanzkriterien
- npm run build erstellt ein funktionierendes .user.js, das eine TSX-Komponente rendert.
- .tsx-Dateien werden ohne weitere manuelle Konfiguration unterstützt.
- Beispiel unter src/components/Hello.tsx und Integration im Entry vorhanden.
- Default-Bundle funktioniert in Tampermonkey (Chrome/Firefox) und Violentmonkey.
- Dokumentation zur Nutzung und zum Umschalten zwischen Preact und React vorhanden.
- Keine Breaking Changes für bestehende Nutzer ohne TSX.
Abwärtskompatibilität
- Reine .ts-Projekte funktionieren unverändert weiter.
- TSX ist optional; keine erzwungene Nutzung eines UI-Frameworks.
- Preact-Default kann durch Entfernen der Aliases und Installation von React ersetzt werden.
Alternativen/Abwägungen
- React als Default: Größeres Bundle, aber verbreitete Ökosystem-Kompatibilität.
- Micro-JSX-Libraries (z. B. nano-jsx): Noch kleiner, aber weniger Ökosystem.
- Externe Libs via @require: Kleinere .user.js-Datei, aber CDN-Abhängigkeit.
Offene Fragen
- Default-Runtime Preact vs. React? (Vorschlag: Preact Default, React optional)
- Soll optional ein Shadow-DOM-Flag im Template konfigurierbar sein?
- Sollen CSS-Module out-of-the-box aktiviert werden?
- Bedarf an HMR-Devflow für Userscripts (z. B. via vite-plugin-monkey) oder weiterhin klassischer Build?
Aufgabenliste (Checklist)
- preact und @types/tampermonkey als Dependencies/DevDependencies hinzufügen (Default)
- tsconfig.json: jsx/react-jsx + jsxImportSource + types ergänzen
- vite.config.ts: Preact-Aliases und Build-Target konfigurieren
- Beispieldateien: src/components/Hello.tsx, src/utils/mount.ts, src/index.ts aktualisieren
- README: TSX-Setup, Preact↔React-Guide, Shadow DOM und CSS-Hinweise
- Manuelles Testen in Tampermonkey (Chrome/Firefox) und Violentmonkey
- Optional: Dokumentation zu externer Bereitstellung via @require (CDN)
Kontext
- Repository nutzt Vite (vite.config.ts), tsconfig.json und eine header.config.json-basierte Header-Generierung. Es existieren aktuell keine offenen Issues; TSX-Support fügt sich gut in die bestehende Struktur ein, da Vite TSX nativ über esbuild unterstützt.