Wie man ein Date-Paket auf zwei Kilobyte reduziert, ohne dabei Schmerzen zu haben
Jeder Frontend-Entwickler hat mindestens einmal mit stillem Entsetzen auf einen Webpack Bundle Analyzer Bericht geschaut. Ein riesiges Stück des Kuchens wurde fast immer von Moment.js zusammen mit Dutzenden von Locales belegt, die niemand gebündelt haben wollte. Das Projekt ist längst als Legacy eingestuft, die Autoren selbst empfehlen, nach Alternativen zu suchen, aber alte Gewohnheiten sterben schwer. Die vertraute Methodenverkettung und String-Formatierung sind auf Muskelgedächtnis-Ebene in euren Fingern verankert.
Genau dafür wurde Day.js geschaffen. Die Bibliothek wiegt nur 2 Kilobyte komprimiert, während sie nahezu 100% API-Kompatibilität mit Moment.js bietet.
Was steckt unter der Haube und warum es so leichtgewichtig ist
Das Hauptproblem alter Bibliotheken war ihre monolithische Natur. Man importierte ein Paket nur für die Datumsformatierung, und der Bundler zog Zeitzonen-Parser, relative Zeitberechnung und Übersetzungen in hundert Sprachen mit in das Bundle.
Day.js ist anders aufgebaut. Der Kern enthält grundlegendes Parsing, Validierung, einfache Manipulationen und Formatierung mit Standardmustern. Alle anderen Funktionen sind in unabhängige Plugins aufgeteilt. Wenn ihr Quartale des Jahres oder ein komplexes benutzerdefiniertes Muster berechnen müsst, importiert ihr ein separates Modul.
Locales funktionieren nach dem gleichen Prinzip. Kein Spanisch oder Chinesisch landet in eurem finalen Bundle, bis ihr explizit einen Import für die benötigte Datei aufruft.
import dayjs from 'dayjs'
import 'dayjs/locale/ru'
dayjs.locale('ru')
Immutabilität ohne Überraschungen
Wenn ihr mit dem alten Moment gearbeitet habt, seid ihr wahrscheinlich über Mutation-Fallen gestolpert. Es genügte, ein Date-Objekt an eine Hilfsfunktion zu übergeben und dort .add(1, 'day') aufzurufen, und das ursprüngliche Datum würde sich in der gesamten Anwendung ändern. Solche Bugs zu debuggen war ein zweifelhafter Genuss.
Day.js macht alle Objekte unveränderlich. Jede Manipulationsoperation gibt eine neue Instanz zurück und lässt das Original unberührt.
const today = dayjs('2024-01-01')
const tomorrow = today.add(1, 'day')
console.log(today.format('YYYY-MM-DD')) // 2024-01-01
console.log(tomorrow.format('YYYY-MM-DD')) // 2024-01-02
Dieses Verhalten macht das unnötige Klonen von Objekten vor jeder Berechnung überflüssig.
Vertraute API und Methodenverkettung
Der Umstieg auf neue Tools bleibt oft wegen der Notwendigkeit, das Team umzuschulen, stecken. Bei Day.js gibt es keinen Bedarf für Umschulungen. Fast jede Methode sieht genau so aus wie in Code, der vor fünf Jahren geschrieben wurde.
Parsing, Wertänderungen und Formatierung können verkettet werden:
dayjs()
.startOf('month')
.add(7, 'day')
.set('hour', 12)
.format('YYYY-MM-DD HH:mm:ss')
Bedingte Prüfungen sehen ebenfalls prägnant aus:
const deadline = dayjs('2024-12-31')
const isExpired = dayjs().isAfter(deadline)
Plugins für nicht-standardisierte Aufgaben
Der Minimalismus des Kerns bedeutet keinen Mangel an Funktionen. Wenn die grundlegenden Funktionen nicht ausreichen, kommen Plugins zum Einsatz. Dies wird in ein paar Zeilen mit der dayjs.extend() Methode erledigt.
Wenn euer Projekt zum Beispiel seltene Formatierungstokens oder Ordinalzahlen benötigt:
import dayjs from 'dayjs'
import advancedFormat from 'dayjs/plugin/advancedFormat'
dayjs.extend(advancedFormat)
dayjs().format('Q Do k kk X x')
Relative Zeit (Format wie "vor 5 Minuten"), UTC-Handling, Berechnung von Tagesdifferenzen unter Berücksichtigung von Geschäftszeiten und ISO-Wochen-Unterstützung werden auf die gleiche Weise angebunden. Ihr zahlt nur mit Bundle-Größe für das, was ihr tatsächlich in eurem Projekt verwendet.
Für wen das Projekt geeignet ist und wer es besser meiden sollte
Day.js passt perfekt in Anwendungen, bei denen die Geschwindigkeit des ersten Seitenaufrufs wichtig ist. Für Landingpages, mobile Interfaces, Admin-Panels und Client-Dashboards ist es eine der besten Optionen im Verhältnis von Funktionen zu Größe.
Es gibt jedoch Situationen, in denen ihr andere Optionen wählen solltet:
- Wenn ihr eine Architektur von Grund auf für moderne Browser aufbaut, werft einen Blick auf das native
IntlObjekt oder die kommende Temporal API. Für einfache Formatierungsaufgaben wird möglicherweise keine Bibliothek von Drittanbietern benötigt. - Wenn euer Projekt bereits aktiv einen funktionalen Ansatz und lodash-artige Architektur verwendet, findet ihr es möglicherweise bequemer,
date-fnszu verwenden, wo Funktionen einzeln importiert werden.
Für alle anderen Fälle, insbesondere bei der Migration von einer Moment.js Codebasis, bleibt Day.js die schmerzfreieste und schnellste Lösung. Ihr ändert einfach den Import-Namen in euren Paketen und schneidet Dutzende von Kilobytes nutzlosen Gewichts aus eurem Bundle.
Ähnliche Projekte