Projektstruktur
Ein Rebase-Starterprojekt besteht aus drei miteinander verbundenen Packages:
my-app/├── .env # Generated for you: JWT_SECRET, a database password, a free port├── rebase.json # Which apps this repository contains, and how each is built├── package.json # Root workspace config├── tsconfig.json # Typechecks scripts/; each workspace typechecks on its own├── docker-compose.yml # Self-hosting: Postgres + the published runtime image├── scripts/│ └── example.ts # The SDK end to end against the running backend: `pnpm example`│├── config/ # Shared by the backend and the admin panel│ ├── index.ts # Re-exports `collections`; the runtime reads `storageAuthorize` from here│ ├── collections/ # Your data model│ │ ├── index.ts # Sort order (`collections`) and `defaultSecurityRules` — not a registry│ │ ├── posts.ts # Example collections│ │ └── users.ts # The auth collection│ ├── resources.ts # What this project needs from wherever it runs│ ├── storage.ts # Who may read, write and list files│ └── cms.d.ts # One line that makes the `admin` block legal here│├── backend/│ ├── functions/ # Custom API routes, auto-mounted at /api/functions/<name>│ │ └── hello.ts│ └── src/│ └── schema.generated.ts # Drizzle schema, regenerated from your collections│└── frontend/ # The admin panel (React + Vite) ├── src/App.tsx ├── src/main.tsx └── vite.config.tstsc --noEmit im Root prüft scripts/; in config/, backend/ oder frontend/ prüft es
jeweils diesen Workspace. Seit 0.25
Unter 0.24 hat das Root keine tsconfig.json, und tsc gibt dort seine Hilfe aus und prüft
nichts.
Frontend (frontend/)
Abschnitt betitelt „Frontend (frontend/)“Das Frontend ist eine standardmäßige Vite + React + TypeScript-Anwendung. Die wichtigste Datei ist App.tsx, die alle Rebase-Controller miteinander verknüpft:
import React from "react";
import "@fontsource/jetbrains-mono";import "@fontsource-variable/inter";import "@fontsource-variable/instrument-sans";
import { Rebase, RebaseAuth, useRebaseAuthController } from "@rebasepro/app";import { RebaseCMS, RebaseShell } from "@rebasepro/cms";import { ErrorBoundary } from "@rebasepro/ui";import { RebaseStudio } from "@rebasepro/studio";import { createRebaseClient } from "@rebasepro/client";import { collections } from "virtual:rebase-collections";
// `rebase dev` injects VITE_API_URL with the port it actually bound, and that// port is derived from this project's path rather than fixed — so a// `http://localhost:3001` fallback here names a port nothing is listening on.// A deployed build serves the admin from the same origin as the API, where an// empty value is exactly what you want.const API_URL = import.meta.env.VITE_API_URL;const GOOGLE_CLIENT_ID = import.meta.env.VITE_GOOGLE_CLIENT_ID;
export function App() { const rebaseClient = React.useMemo(() => createRebaseClient({ baseUrl: API_URL, // Store the refresh token in an httpOnly cookie (XSS-safe) rather than // localStorage. The backend issues it via `auth.cookieAuth`. auth: { authFlowMode: "cookie" } }), []);
const authController = useRebaseAuthController({ client: rebaseClient, googleClientId: GOOGLE_CLIENT_ID });
return ( <ErrorBoundary fullPage> <Rebase client={rebaseClient} authController={authController} > {/* The sign-in screen. On its own this changes nothing — it is where you pass `loginView` to replace it. */} <RebaseAuth /> <RebaseCMS collections={collections} /> <RebaseStudio/> <RebaseShell title="Rebase"/> </Rebase> </ErrorBoundary> );}main.tsx bindet es unter einem react-router-basename ein, der aus
import.meta.env.BASE_URL übernommen wird. Diesen setzt rebase build anhand des
path, den diese App in rebase.json deklariert — so stimmen die Assets, der
Router und der Server bei einem einzigen Wert überein, ohne dass er dreimal manuell
angegeben werden muss.
Wichtige Konzepte
Abschnitt betitelt „Wichtige Konzepte“createRebaseClient— Erstellt den SDK-Client, der HTTP-Anfragen, WebSocket-Verbindungen und die Verwaltung von Authentifizierungstoken übernimmtvirtual:rebase-collections— Ein Vite-Plugin, das Ihre geteilten Collections zur Build-Zeit automatisch importiertuseRebaseAuthController— Verwaltet den angemeldeten Benutzer sowie den Token-Lebenszyklus und wird von<Rebase>an alle untergeordneten Komponenten weitergegeben
Backend (backend/)
Abschnitt betitelt „Backend (backend/)“Es gibt keine Server-Datei zu lesen, und das ist beabsichtigt: Ein neu erstelltes
Projekt deklariert runtime: "managed", sodass das veröffentlichte
rebasepro/server-Image Ihr Projekt startet. backend/ enthält den Code, den
die Runtime einliest:
| Pfad | Beschreibung |
|---|---|
backend/functions/ |
Eigene Routen, automatisch unter /api/functions/<filename> gemountet |
backend/crons/ |
Zeitgesteuerte Jobs (Cronjobs), die auf dieselbe Weise erkannt werden (erstellen Sie das Verzeichnis bei Bedarf) |
backend/src/schema.generated.ts |
Das Drizzle-Schema Ihrer Collections: von rebase init geschrieben und bei jedem rebase dev und rebase build neu generiert |
Die Runtime richtet Folgendes ein:
- REST-API unter
/api/data/*— generierte CRUD-Operationen für jede Collection - Auth unter
/api/auth/*— Registrierung, Login, Refresh, OAuth - Storage unter
/api/storage/*— Upload und Download - WebSocket — Echtzeitsynchronisierung über Postgres LISTEN/NOTIFY
- Ihre Functions und Crons aus den oben genannten Verzeichnissen
Die Konfiguration erfolgt über rebase.json, das config/-Verzeichnis und
Umgebungsvariablen. Siehe Environment & Configuration.
rebase build wandelt all dies in ein Bundle um — die kompilierten
Collections, Functions und Crons samt einem Manifest —, das die Managed Runtime
bootet. Nichts an diesem Bundle wird von Hand geschrieben; wenn Sie sehen möchten,
wie eines aufgebaut ist, finden Sie die Details unter
Runtime & Bundles.
Das vom Frontend bereitgestellte Panel besteht aus zwei Hälften. Studio ist der Entwicklerbereich — der Schema-Editor, die SQL-Konsole, der RLS-Policy-Browser — und befindet sich hinter dem Umschalter im Drawer, kein separates Deployment. Siehe Studio.
Um stattdessen die Kontrolle über den Prozess zu übernehmen — eigene Middleware,
Routen und Auth-Verdrahtung —, führen Sie rebase eject aus. Alles unterhalb dieses
Absatzes gilt nur für ausgeworfene (ejected) Projekte: Ein neu erstelltes Projekt
besitzt keine dieser Dateien, und nichts darin ruft initializeRebaseBackend auf.
Der Befehl schreibt einen Einstiegspunkt, der initializeRebaseBackend direkt aufruft,
sowie ein Dockerfile und eine Compose-Datei, die dieses baut; von da an warten Sie
den Server selbst, und Plattform-Runtime-Upgrades werden nicht mehr auf das Projekt
angewendet. Diese Schnittstelle ist in Custom Server Integration
dokumentiert.
Collections (config/collections/)
Abschnitt betitelt „Collections (config/collections/)“Collections sind die Single Source of Truth für Ihr Datenmodell. Sie werden in TypeScript definiert und sowohl vom Frontend (zur UI-Generierung) als auch vom Backend (zur Schema-Generierung und für das API-Routing) verwendet.
import { defineCollection } from "@rebasepro/cms-types";
const productsCollection = defineCollection({ slug: "products", name: "Products", properties: { name: { type: "string", name: "Name" }, price: { type: "number", name: "Price" } }});
// The default export is what the loader picks up — every file in this directory// is loaded, listed in index.ts or not, and every collection in the scaffold is// written this way.export default productsCollection;Der slug wird zum URL-Pfad in der Admin-UI und zum REST-API-Endpunkt (/api/data/products), und der PostgreSQL-Tabellenname entspricht standardmäßig diesem Wert. Geben Sie table nur an, wenn sich beide voneinander unterscheiden.
Wie alles zusammenhängt
Abschnitt betitelt „Wie alles zusammenhängt“- Sie definieren Collections in
config/collections/ - Das Backend liest sie ein, um Drizzle-Schemas zu generieren und REST-Routen einzubinden
- Das Frontend liest sie ein (über ein Vite-Plugin), um Tabellen, Formulare und die Navigation zu rendern
- Die CLI liest sie ein, um das Drizzle-Schema (
rebase schema generate), die SDK-Typen (rebase generate-sdk) und, aus diesem Schema, Migrationsdateien (rebase db generate) zu erzeugen
Während rebase dev läuft, werden beim Speichern einer Datei unter config/collections/
die Datei backend/src/schema.generated.ts und die SDK-Typen in generated/sdk/ neu
generiert und das Backend neu gestartet; beim Hochfahren werden fehlende Tabellen und
Spalten automatisch erstellt. Außerhalb von rebase dev entsprechen diese Schritte
rebase schema generate und rebase generate-sdk.
Unter 0.23 generiert rebase dev nur das Schema neu, und rebase generate-sdk ist ein
eigener Schritt.
Nächste Schritte
Abschnitt betitelt „Nächste Schritte“- Quickstart — Starten Sie mit einem neuen Rebase-Projekt
- Configuration — Alle Umgebungsvariablen und Optionen