https://www.tutory.de/entdecken/dokument/tutory-5tf7glfl
tutory.de – Materialerstellung für den Unterricht
Arbeitsblätter als PDF oder interaktives Arbeitsblatt
Entwicklung 8 Jahre
https://www.tutory.de/entdecken/dokument/tutory-5tf7glfl
Grafikorientierter Editor für (pädagogisches) Material
Drag- & Drop-Funktionalität
Export als PDF
Digitales Arbeitsblatt (mit Selbstkontrollmöglichkeiten)
Kompatibilität mit Desktop und iPad
Keine Installation erforderlich, jedoch als Electron-App verfügbar
https://www.tutory.de/entdecken/dokument/tutory-5tf7glfl
https://www.tutory.de/entdecken/dokument/tutory-5tf7glfl
KISS - Keep it stupid simple
Funktionen > Methoden
POJO > Klassen
wenig Abhängigkeiten
möglichst kein Framework/Lib-spezifischer Code
Modul-lokale Variablen ftw!
Testen wo sinnvoll aber kein Muss
starke Kohesion (auch auf Dateiebene)
zusammengehörende Dateien liegen in gleichen Ordnern (page.js, page.test.js, page.styl)
Vermeidung von Higher-Order Funktionen
Fokus auf Debuggability
kein this – kein prototype - kein class!
https://www.tutory.de/entdecken/dokument/tutory-5tf7glfl
REST-API, SSR, Assets
DB
https://www.tutory.de/entdecken/dokument/tutory-5tf7glfl
Backend: Express/Koa
Frontend: mithril.js
Data-Layer: modelz.js (Frontend und Backend)
ORM/DB: hedy.js/Knex
i18n: translate.js
PDF: puppeteer
tests: mocha + chai (aktuell > 2700 Unit-Tests)
css stylus.lang
https://www.tutory.de/entdecken/dokument/tutory-5tf7glfl
GTD-Framework
braucht keinen speziellen Datenlayer (redux, streams, observervables)
kein XML 🎉
minimale stablie API (keine ständigen Rewrites oder Refactorings nötig)
man versteht es in 1 min, kann es in 1h und beherrscht es in einem Tag
let c = 0const app = { view: () => [ m("h1", [ "Say ", m("button", { onclick: () => c++ },'👋'), " to Mithril!" ]), m("div", c, '👋 sent.') ]}// Mount component into #appm.mount(document.body, app);Framework
Major-API-Änderungen 5 Jahre
Bemerkung
React
3 (Class → Hooks → Server Components)
Vue
2 (Options → Composition API)
Svelte
2 (Syntax/Compiler)
Mithril
0 ✅
stabil seit 2016
https://www.tutory.de/entdecken/dokument/tutory-5tf7glfl
Schema-Definition
Datenkonsistenz ohne Typescript/Klassen
Primitive + Komplexe Datentypen (Nesting)
Computed Properties
Serialisierung/Parsing
Caching
Server/Client-Side
const scheme = modelz()const createUser = schema({ firstName: 'string', lastName: 'string', fullName: { get: u => `${u.firstName} ${m.lastName}`, set: (u, value) => { const [firstName, ...lastName] = value.split(' ') u.firstName = firstName u.lastName = lastName.join(' ') }, cacheKey: ['firstName','lastName'] }})https://www.tutory.de/entdecken/dokument/tutory-5tf7glfl
basierend auf knex.js Query-Builder
einfache API
einfache Dinge (CRUD) sind trivial
komplizierte Dinge (z. B. join-filters), sollten jedoch möglich sein
konsistente Ergebnisse (gleiche Spalten ohne SELECT *)
definierte Mutationen (schreibbare Spalten definierbar)
Create/Update/Delete-Hooks (z. B. zur Cache invalidierung)
Relationen via Sub-Queries
kombinierte PKs, JSONP-Where,
Backend-agnostisch
const userQuery = store('user', { afterDelete: invalidateUser, afterPut: invalidateUser, afterPost: invalidateUser,}).columns(['id', 'firstname', 'lastname']),.hasMany(worksheetQuery).hasManyThrough(groupQuery, groupUserQuery).map(userModel)const user = await userQuery.get(userId)const users = await userQuery .whereLike({ firstname: '%Ada%' }) .load()await userQuery.put(userId, { firstname: 'Konrad'})https://www.tutory.de/entdecken/dokument/tutory-5tf7glfl
minmal (~100loc)
mächtig
einfache Strings
Strings mit Ersetzungen
Pluralformen
subKey-Verarbeitung
Aliase
Dom-Knoten als Ersetzungen
schnell
übersetzte URLs
t('tree') //=> 'Baum't('trees', 1) //=> '1 Baum't('trees', 2) //=> '2 Bäume't('places.with.trees', 2, { place: 'Leipzig' }) // => 'Leipzig hat 2 Eichen'const button = m('button', 'Knopf')t.arr('push.the.button', { button }) //=> ['Drücke den ', button, '!']https://www.tutory.de/entdecken/dokument/tutory-5tf7glfl
langsame JS-Buildzeiten (browserify) → Umstellung auf esbuild
PDF Generierung ohne Mehraufwand → SSR + Puppeteer (vorher wkhtml2pdf)
Konsistente PDF-Generierung über Releases hinweg → WS-Compare
Konsistente Ausgabe über Browserengines → Indentifikation und Vermeidung der Ursachen (z. B. line-height-Behandlung)
Textformatierung + WYSIWYG → zunächste eigene markup-Sprache (eduMark), später Integration von ProseMirror (inkl. eduMark-Konverter)
Infra: Virtueller Server (uberspace) → Bare Metal (hetzner) → Docker + Cloud (hetzner)
Daten-Migration → Migration on-the-fly
https://www.tutory.de/entdecken/dokument/tutory-5tf7glfl
commonjs/esm Umstellung
CSS-Organisation (aktuelle stylus aber ohne klare struktur)
Konsistentes Formular-Handling
Multiplayer
Offline Support (via Service Workers)
Übergang zur Post-A4-Welt
https://www.tutory.de/entdecken/dokument/tutory-5tf7glfl
Framework-Updates/Refactorings
komplexe Build-Pipelines
Limitierungen durch Frameworks/Libs (Kampf wir gegen Framework)
Rendering Performance-Probleme
Mehraufwand einer Frontend/Backend-Trennung
separate Deployments
Doppelstrukturen im Code
Zeit-Abhängigkeiten
Debuggingprobleme durch kompilierten Code
Over-Engineering & Tooling-Explosion
Abhängigkeit von Ökosystem-Tempo
Probleme mit State-Magie
https://www.tutory.de/entdecken/dokument/tutory-5tf7glfl
https://www.tutory.de/entdecken/dokument/tutory-5tf7glfl


