Designa en gång, kör överallt: En UI-fil på webben, iOS och Android
Vad som verkligen krävs för att designa en gång och köra ett användargränssnitt på webben, iOS och Android: delad layout och rörelse, plattformsspecifika delar, testning och var ExodeUI passar.
Core Takeaway
Design en gång, kör överallt innebär att en källfil beskriver en UI-komponent och varje plattform spelar upp den med en runtime, istället för att bygga om samma rörelse i React, SwiftUI och Flutter. Det fungerar när layout, tillstånd, rörelse och ingångar finns i den delade filen, och det förblir ärligt när navigering, tillgänglighet och systemgester förblir plattformsspecifika. ExodeUI stöder denna modell med runtime-paket för React, Vue, Svelte, Angular, Solid, React Native, SwiftUI och Flutter.
Vad "design en gång, spring överallt" faktiskt kräver
Det kräver mer än en exportknapp. Den delade filen måste beskriva hur komponenten ser ut i olika storlekar, hur den ser ut i varje tillstånd, hur den rör sig mellan tillstånd och hur appen driver den med ingångar. Varje plattform behöver också en körtid som kan spela upp filen och koppla dessa ingångar till verkliga händelser. Om någon av dessa bitar saknas, förvandlas löftet till ytterligare en handoff.
Delad fil kontra ombyggnad per plattform
Den traditionella vägen är att designa en gång och bygga om tre gånger: webb i CSS och JavaScript, iOS i SwiftUI och Android i Kotlin eller Flutter. Varje ombyggnad introducerar små skillnader i timing, avstånd och gesthantering. En delad filväg håller komponentdefinitionen på ett ställe och låter varje plattform spela upp den. Avvägningen är att en körtid sitter mellan filen och plattformen, så du ger upp lite direkt kontroll över plattformsspecifik rendering.
Vad ska förbli plattformsspecifikt
En delad komponent ska inte låtsas att alla plattformar är likadana. Navigationsmönster, bakåtgester, systemdialoger, behörigheter och tillgänglighets-API:er skiljer sig. Den delade filen bör äga den interaktiva visuella komponenten; värdappen ska äga plattformen chrome och de semantiska kontrollerna runt den. Till exempel kan en delad animerad knapp sitta inuti ett inbyggt knappelement som visar rätt roll och etikett.
Hur körtider fungerar
En körning läser filen, bygger det visuella trädet och uppdaterar det när indata ändras. Din applikationskod ställer in ingångar som tryckt, inaktiverat eller laddat, och lyssnar efter händelser som bekräfta eller avvisa. Eftersom den visuella definitionen är data snarare än handskriven kod per plattform, är körtiden det som gör samma fil portabel. Körtiden är också ett beroende, så mät dess effekt på ditt eget bygge istället för att anta att det är gratis.
Testar samma fil i alla miljöer
Testa filen där den ska köras, inte bara i editorn. Kontrollera layouten i de minsta och största storlekarna som stöds, verifiera varje stat med verkligt innehåll och testa inmatning från pek, mus och tangentbord separat. Kontrollera sedan tillgängligheten: fokusordning, etiketter, minskad rörelse och skärmläsarens beteende. En delad fil minskar visuell drift, men det tar inte bort behovet av att testa varje plattform.
Där ExodeUI passar
ExodeUI lagrar en komponent i en öppen .exode-fil och tillhandahåller körtidspaket för React, Vue, Svelte, Angular, Solid, React Native, SwiftUI och Flutter. Filen kan innehålla layout och brytpunkter, tidslinjer, tillståndsmaskiner, vårfysik, ingångar och händelser. Samma fil kan redigeras i webbläsaren eller skrivbordsredigeraren, och AI-kodningsverktyg kan arbeta med den via MCP-servern.
När man inte ska använda en delad fil
En delad fil passar dåligt när gränssnittet är starkt beroende av API:er endast för plattform, när du behöver pixelnivåkontroll över inbyggd rendering eller när komponenten mestadels är en video- eller 3D-scen. Det är också en dålig passform om ditt lag inte kan testa varje mål. I dessa fall är plattformsspecifik kod det ärliga valet, och en delad fil bör endast täcka de delar som verkligen drar nytta av den.
Produktionsimplementeringsutdrag
import { ExodeUICanvas } from 'exodeui';
// The same component file can be played by the runtime your app already uses.
// Web, React Native, SwiftUI and Flutter packages read the same .exode source.
export function ShareSheet({ open, progress, onClose }) {
return (
<ExodeUICanvas
src="/share_sheet.exode"
inputs={{ open, progress }}
onTrigger={(name) => name === 'close' && onClose()}
/>
);
}Nyckel Principles att komma ihåg
- Design en gång och kör överallt behöver delad layout, tillstånd, rörelse och ingångar, plus en körtid per plattform
- API:er för navigering, behörigheter och tillgänglighet bör förbli plattformsspecifika
- En körtid är ett beroende; mät dess effekt på din konstruktion
- Testa varje mål för layout, input, rörelse och tillgänglighet
- ExodeUI tillhandahåller körtider för React, Vue, Svelte, Angular, Solid, React Native, SwiftUI och Flutter