Jaspr Web Architecture Guide (v0.22.x)
Zielsetzung
Jaspr ist ein Dart-Webframework (aktuelle Version: 0.22.x).
Im Gegensatz zu Flutter Web (das Pixel über Canvas zeichnet und schlechte SEO bietet) kompiliert Jaspr Dart zu semantischen HTML- und CSS-DOM-Elementen. Verwenden Sie Jaspr für Websites, Blogs, Landing Pages oder jedes Projekt, das eine ordentliche SEO erfordert.
Anweisungen
1. Kernkonzept: Flutter-ähnliche Programmiererfahrung
Jaspr spiegelt das Komponentenmodell von Flutter wider. Die build-Methode gibt eine einzelne Component zurück (äquivalent zu einem Flutter Widget).
| Flutter-Konzept | Jaspr-Konzept | Hinweise |
|---|---|---|
Widget | Component | Jedes UI-Element in Jaspr ist eine Component |
StatelessWidget | StatelessComponent | Rein deklaratives UI; erhält BuildContext context |
StatefulWidget | StatefulComponent | Verwaltet den Lebenszyklus mit setState, initState, createState() |
InheritedWidget | InheritedComponent | Gibt Zustand im Komponentenbaum weiter |
1.1 DOM-Elemente
Jaspr rendert in das DOM, verwenden Sie daher die HTML-Tag-Helfer (div, p, img, etc.) aus jaspr/dom.dart.
import 'package:jaspr/jaspr.dart';
class ProfileCard extends StatelessComponent {
final String name;
const ProfileCard({required this.name, super.key});
@override
Component build(BuildContext context) {
return div(
classes: 'profile-card',
styles: Styles.box(width: 300.px, backgroundColor: Colors.white),
[
h2([.text(name)]), // 🌟 .text()-Kurzform seit Dart 3.10 (Component.text)
p([
.text('Hello World!'),
]),
button(
onClick: () => print('Button successfully clicked!'),
[.text('Contact Me')]
)
]
);
}
}
2. Tailwind CSS Integration (jaspr_tailwind)
Jaspr bietet eine offizielle Tailwind-CSS-Integration über jaspr_tailwind.
2.1 Installation und Einrichtung
dev_dependencies:
jaspr_tailwind: ^0.1.0
Erstellen Sie web/styles.tw.css mit der Tailwind-v4-CSS-zuerst-Syntax:
/* web/styles.tw.css */
@import "tailwindcss";
2.2 Kompiliertes CSS in der Root-Komponente laden
Verwenden Sie in der Root-Komponente Document, um das kompilierte Stylesheet zu verlinken und Tailwind-Klassen über den classes-Parameter zu nutzen:
import 'package:jaspr/jaspr.dart';
class App extends StatelessComponent {
@override
Component build(BuildContext context) {
return Document(
head: [
// 🌟 jaspr_tailwind kompiliert styles.tw.css automatisch → styles.css
link(href: 'styles.css', rel: 'stylesheet'),
],
body: div(
// Tailwind-Klassen direkt verwenden; jaspr_tailwind aktualisiert automatisch während der Entwicklung
classes: 'bg-gray-100 min-h-screen flex items-center justify-center',
[
h1(classes: 'text-4xl font-bold text-blue-600', [.text('Hello Tailwind!')]),
]
),
);
}
}
3. Routing (jaspr_router)
Das Routing von Jaspr spiegelt go_router mit einer deklarativen API wider.
3.1 Installation und Einrichtung
dependencies:
jaspr_router: ^0.2.0
import 'package:jaspr/jaspr.dart';
import 'package:jaspr_router/jaspr_router.dart';
class MyApp extends StatelessComponent {
@override
Component build(BuildContext context) {
return Router(
routes: [
Route(
path: '/',
builder: (context, state) => const HomePage(),
),
Route(
path: '/about',
builder: (context, state) => const AboutPage(),
),
],
);
}
}
4. SSR: Asynchrones Backend-Daten-Preloading
Der Hauptvorteil von Jaspr gegenüber Flutter Web ist das serverseitige Rendering (SSR). Bei Flutter Web werden Daten in initState geladen, was einen Ladezustand auf dem Client verursacht. Bei Jaspr SSR werden Daten auf dem Server geladen, bevor das HTML an den Browser gesendet wird.
4.1 AsyncStatelessComponent (Nur Server)
Importieren Sie jaspr/server.dart, um AsyncStatelessComponent zu verwenden, das eine async-Build-Methode erlaubt.
import 'package:jaspr/server.dart'; // 🌟 Nur Server-Import
class ArticlePage extends AsyncStatelessComponent {
final String articleId;
const ArticlePage(this.articleId);
@override
Future<Component> build(BuildContext context) async {
// Läuft serverseitig; await kann frei für Datenbank-/API-Aufrufe verwendet werden
final articleData = await Database.fetchArticle(articleId);
// Der Browser erhält vollständig gerendertes HTML für sofortigen, SEO-freundlichen Inhalt
return div([
h1([.text(articleData.title)]),
p([.text(articleData.content)]),
]);
}
}
4.2 Zustandsbehaftetes Preloading (PreloadStateMixin)
Wenn der Zustand erhalten bleiben muss, mischen Sie PreloadStateMixin ein:
class MyState extends State<MyStatefulComponent> with PreloadStateMixin {
@override
Future<void> preloadState() async {
// Läuft serverseitig vor initState(); bereitet den Zustand für die clientseitige Hydration vor
await loadInitialData();
}
// ...
}
5. Testen (jaspr_test)
jaspr_test deckt Komponenten-Unittests, SSR-Ergebnisse und Browser-Interaktionen ab.
5.1 Abhängigkeit einrichten
dart pub add jaspr_test --dev
Da jaspr_test das native package:test reexportiert, muss es nicht separat importiert werden.
5.2 Drei Haupt-Testfunktionen
Aufgrund der Komplexität der HTML/Web-Umgebung bietet Jaspr drei szenariospezifische Testfunktionen:
testComponents (Komponententests in virtueller Umgebung)
Testen Sie Ihre Komponentenlogik in einer headlessen, reinen Dart-Simulationsumgebung. Dies ist die schnellste Methode. Die Verwendung ist der von Flutters testWidgets sehr ähnlich.
import 'package:jaspr_test/jaspr_test.dart';
void main() {
testComponents('Testet, dass ein Klick auf den Button den Zähler erhöht', (tester) async {
tester.pumpComponent(MyComponent());
expect(find.text('Count: 0'), findsOneComponent);
await tester.click(find.tag('button'));
expect(find.text('Count: 1'), findsOneComponent);
});
}
testServer (Tests des serverseitigen Renderings)
Zielt auf das Testen von SSR-Anwendungen ab. Es startet direkt einen simulierten lokalen HTTP-Server. Sie können Requests senden und die zurückgegebenen HTML-Strings oder Zustandseigenschaften des Servers überprüfen.
import 'package:jaspr_test/jaspr_test.dart';
void main() {
testServer('Überprüft serverseitig gerendertes HTML', (tester) async {
final response = await tester.request('/');
expect(response.document.body?.text, contains('Welcome to SSR'));
});
}
testClient (Browser-Hydration und Zustandssynchronisationstests)
Läuft in einer headlessen Browserumgebung und testet, ob der Client die Übernahme durch Hydration korrekt durchführt und DOM-Interaktionen verarbeitet, nachdem er initialStateData vom Server erhalten hat.
Einschränkungen
- Verwenden Sie
AsyncStatelessComponentnur auf der Serverseite (jaspr/server.dart). Niemals im Client-UI-Code. - Verschachteln Sie keine Flutter
Widgets innerhalb von JasprComponents. - Wählen Sie den Tester, der zu Ihrem Rendermodus passt: SSR →
testServer, CSR →testComponents, Browser →testClient. Bevorzugen Sie DOM-String-Abgleich gegenüber strenger Typisierung.