Im vergangenen Jahr sind eine ganze Reihe neuer Entwicklertools auf den Markt gekommen, und sie machen den Tools Konkurrenz, die die Frontend-Entwicklung in den letzten Jahren dominiert haben, darunter webpack, Babel, Rollup, Parcel, create-react-app.
Diese neuen Tools sind nicht dafür konzipiert, exakt dieselbe Funktion zu erfüllen, und jedes hat unterschiedliche Ziele und Funktionen, um diese zu erreichen. Trotz ihrer Unterschiede teilen diese Tools ein gemeinsames Ziel: die Entwicklererfahrung zu verbessern.
Inhaltsverzeichnis
- Warum kommen diese Tools jetzt alle?
- Wie unterscheiden sich diese von bestehenden Tools?
- Das Experiment
- Vergleichbare Funktionen
- esbuild
- Snowpack
- Vite
- wmr
- Funktionsvergleich
- Zusammenfassung
Ich möchte jedes davon im Detail untersuchen, aufzeigen, was sie tun, warum wir sie brauchen und ihre Anwendungsfälle. Mir ist bewusst, dass Vergleiche nicht immer fair sind. Nochmals, es ist nicht so, dass die Dinge, die wir in diesem Artikel betrachten, direkte Konkurrenten wären. Tatsächlich nutzen Snowpack und Vite für bestimmte Aufgaben tatsächlich esbuild im Hintergrund. Unser Ziel ist es vielmehr, einen besseren Überblick über die Landschaft der Entwicklungstools zu bekommen, die Aufgaben erleichtern. So sehen wir, welche Optionen es gibt und wie sie sich vergleichen, damit wir die besten Entscheidungen treffen können, wenn wir sie brauchen.
Natürlich wird all dies von meiner Erfahrung mit React und Preact geprägt sein. Ich bin mit diesen Frameworks Bibliotheken vertrauter, aber wir werden uns auch ihre Unterstützung für andere Frontend-Frameworks ansehen.
Es gab eine ganze Menge großartiger Artikel, Streams und Podcasts über diese neuen Entwicklungstools. Ich kann Ihnen ein paar Episoden der ShopTalk Show für mehr Kontext empfehlen: Episode 454 bespricht Vite und Episode 448 mit den Machern von wmr und Snowpack. Etwas, das bei diesen Episoden hervorsticht, ist, dass enorme Arbeit in den Aufbau dieser Tools geflossen ist, um unsere Entwicklungsumgebungen zu modernisieren.
Warum kommen diese Tools jetzt alle?
Teilweise glaube ich, dass diese Tools als Reaktion auf die Ermüdung durch JavaScript-Tooling entstanden sind – etwas, das in diesem Artikel über das Erlernen von JavaScript im Jahr 2016 schön eingefangen wurde. Sie füllen auch eine fehlende Zwischenzone zwischen dem Schreiben einer einzelnen Vanilla-JavaScript-Datei und dem Herunterladen von 200 Megabyte Tooling-Abhängigkeiten, bevor man eine Zeile eigenen Code geschrieben hat. Sie sind "batteries included", ohne die Abhängigkeitsliste, und Teil eines Trends, Schichten im JavaScript-Ökosystem zu kollabieren.
Snowpack, Vite und wmr wurden alle durch native JavaScript-Module im Browser ermöglicht. Bereits 2018 wurde Firefox 60 mit standardmäßig aktivierten ECMAScript 2015-Modulen veröffentlicht. Seitdem unterstützen alle großen Browser-Engines native JavaScript-Module. Node.js lieferte im November 2019 auch native JavaScript-Module aus. Wir finden auch heute noch im Jahr 2021 heraus, welche Möglichkeiten native JavaScript-Module eröffnen.
Wie unterscheiden sich diese von bestehenden Tools?
Ob wir webpack, Rollup oder Parcel für einen Entwicklungsserver verwenden, das Tool bündelt unseren gesamten Code aus unserem Quellcode und dem `node_modules`-Ordner, durchläuft Build-Prozesse – wie Babel, TypeScript oder PostCSS – und liefert dann den gebündelten Code an unseren Browser. Das alles erfordert Arbeit und kann Entwicklungsserver bei größeren Codebasen bis zum Stillstand verlangsamen, selbst nach all der Arbeit, die in Caching und Optimierung geflossen ist.
Snowpack-, Vite- und wmr-Entwicklungsserver folgen diesem Modell nicht. Stattdessen warten sie, bis der Browser eine Importanweisung findet und eine HTTP-Anfrage für das Modul stellt. Erst nachdem diese Anfrage gestellt wurde, wendet das Tool Transformationen auf das angeforderte Modul und alle Blattknoten im Importbaum des Moduls an und liefert diese dann an den Browser. Das beschleunigt die Dinge erheblich, da beim Bereitstellen auf einem Dev-Server weniger Arbeit anfällt.
Sie werden feststellen, dass esbuild in diesem Bild fehlt. Es ist in erster Linie ein Bundler. Es umgeht das Bündeln nicht auf die gleiche Weise wie die anderen Tools. Stattdessen verarbeitet esbuild Code extrem schnell, indem es kostspielige Transformationen vermeidet, Parallelisierung nutzt und die Go-Sprache verwendet.
Das Experiment
Ich habe eine der Beispiel-Apps aus den React-Docs genommen und sie mit jedem in diesem Artikel behandelten Tool neu aufgebaut. Das Projekt, das ich gewählt habe, war Snap Shot von Yogita Verma. Hier ist ein Link zum Original-Repo und ein Link zu meinem Repo mit den vier Versionen von Snap Shot, die jeweils ein anderes Build-Tool verwenden. Wir werden die Ausgabe jedes Build-Schritts später vergleichen. Das Neuerstellen dieser App hat es mir ermöglicht, die Entwicklererfahrung beim Einbinden ziemlich standardmäßiger React-Abhängigkeiten in die Tools zu testen, darunter React Router und axios.
Vergleichbare Funktionen
Bevor wir uns mit den Einzelheiten jedes einzelnen Tools befassen, unterstützen sie alle (in unterschiedlichem Maße) die folgenden Funktionen out-of-the-box:
- Erstklassige Unterstützung für native JavaScript-Module
- TypeScript-Kompilierung (aber keine Typüberprüfung)
- JSX
- Plugin-API für Erweiterbarkeit
- Ein integrierter Entwicklungsserver
- CSS-Bundling und Unterstützung für CSS-in-JS-Bibliotheken
All diese Tools können TypeScript in JavaScript kompilieren, aber sie tun dies auch wenn Typfehler vorhanden sind. Für eine ordnungsgemäße Typüberprüfung müssten Sie TypeScript installieren und `tsc --noEmit` auf Ihrer Stamm-JavaScript-Datei ausführen oder alternativ Editor-Plugins verwenden, um auf Typfehler zu achten.
Okay, werfen wir einen Blick auf jedes Tool.
esbuild
esbuild wurde von Evan Wallace (CTO von Figma) entwickelt. Sein Hauptmerkmal ist, dass es einen Build-Schritt bietet, der 10- bis 100-mal schneller ist als Node-basierte Bundler (laut ihren eigenen Benchmarks). Es bietet nicht viele der Entwicklerfreundlichkeiten, die man in etwas wie create-react-app finden könnte. Aber es tauchen immer mehr esbuild-Starter auf, die diese Lücken füllen, darunter create-react-app-esbuild, estrella und Snowpack, das esbuild für seinen Build-Schritt verwendet.
esbuild ist sehr neu. Es hat noch keine Version 1.0 erreicht und ist noch nicht ganz bereit für den Produktionseinsatz – aber das ist nicht mehr weit. Es bietet intuitive JavaScript- und Kommandozeilen-APIs mit intelligenten Standardeinstellungen.
Anwendungsfälle
esbuild ist ein kompletter Game-Changer in der Bundler-Welt. Es wird am nützlichsten in großen Codebasen sein, wo der Geschwindigkeitsunterschied zwischen esbuild und Node-Bundlern multipliziert wird. Wenn esbuild 1.0 erreicht, wird es für große Produktionsseiten sehr nützlich sein und Teams viel Zeit beim Warten auf abgeschlossene Builds sparen. Leider müssen große Produktionsseiten warten, bis esbuild stabil wird. In der Zwischenzeit wird es einfach gut sein, Nebenprojekten etwas Geschwindigkeit beim Bündeln zu verleihen.
Die blitzschnelle Geschwindigkeit von esbuild wird ein Bonus für jede Art von Arbeit sein, die Sie leisten. Weniger Zeit mit dem Warten auf laufende Builds ist immer gut für die Entwicklererfahrung! In Anbetracht dessen, wenn Sie schnell Prototypen für Anwendungen erstellen, möchten Sie vielleicht mit etwas Höherem als esbuild beginnen – andernfalls müssen Sie einige Zeit damit verbringen, Abhängigkeiten zu laden und Ihre Umgebung zu konfigurieren, bevor Sie die Bequemlichkeiten erhalten, die wir im JavaScript-Ökosystem erwarten. Wenn Sie auch die Größe Ihres Bundles so weit wie möglich minimieren möchten, könnten Sie Rollup und terser verwenden, die etwas kleinere Bundle-Größen erzeugen.
Setup
Ich habe beschlossen, ein React-Projekt in esbuild auf naive Weise zu starten: npm-Installieren von esbuild, React und ReactDOM. Ich habe eine Datei `src/app.jsx` und eine Datei `dist/index.html` erstellt. Dann habe ich den folgenden Befehl verwendet, um die App in eine Datei `dist/bundle.js` zu kompilieren:
./node_modules/.bin/esbuild src/app.jsx --bundle --platform=browser --outfile=dist/bundle.js
Als ich `index.html` gehostet und im Browser geöffnet habe, wurde ich mit dem "White Screen of Death" und einem Konsolenfehler "Uncaught ReferenceError: process is not defined" begrüßt. Sowohl die Dokumentation als auch die CLI erklären genau, was Sie tun müssen, um dies zu verhindern, aber es könnte ein "Gotcha" für Anfänger sein, da es ein zusätzliches Argument beim Bündeln von React erfordert.
--define:process.env.NODE_ENV=\"production\"
Oder, wenn Sie esbuild in npm-Skripten einbinden, die so geschrieben sind, um die Anführungszeichen zu escapen:
--define:process.env.NODE_ENV=\\\"production\\\"
Dieses `define`-Argument ist für jede Bibliothek erforderlich, die für den Browser gebündelt wird und Node-Umgebungsvariablen erwartet. Vue 2.0 erwartet ebenfalls diese. Sie werden dasselbe Problem nicht mit Preact haben, da es keine Umgebungsvariablen erwartet und standardmäßig fertig für den Browser geliefert wird.
Nachdem ich den Befehl mit dem `define`-Argument ausgeführt hatte, funktionierte meine "Hello world"-React-App perfekt. JSX funktioniert sofort mit `.jsx`-Dateien. Dennoch muss React manuell importiert werden, und dann wird JSX in `React.createElement` umgewandelt. Es gibt jedoch Möglichkeiten, Auto-Imports in JSX und/oder JSX-Konfigurationen für Preact hinzuzufügen.
Verwendung
esbuild bietet eine `–serve`-Option für einen Entwicklungsserver. Dies umgeht das Dateisystem und liefert Module direkt aus dem Speicher, um sicherzustellen, dass der Browser keine älteren Versionen von Modulen lädt. Es gibt jedoch kein Live/Hot-Reloading, sodass Sie beim Speichern den Browser neu laden müssen, was keine ideale Erfahrung ist.
Ich habe mich entschieden, die neu veröffentlichte **watch** Funktion zu verwenden. Dies weist esbuild an, Code jedes Mal neu zu kompilieren, wenn eine Quelldatei gespeichert wird. Aber wir brauchen immer noch einen Server, um unsere gespeicherten Änderungen zu sehen. Wir können ein Entwicklungsserver-Paket einbinden, wie z.B. das von Luke Jackson servor.
npm install servor --save-dev
Dann können wir die esbuild JavaScript API verwenden, um einen Server zu starten und den Watch-Modus von esbuild gleichzeitig auszuführen. Erstellen wir eine Datei im Stammverzeichnis unseres Projekts namens `watch.js`.
// watch.js
const esbuild = require("esbuild");
const servor = require("servor");
esbuild.build({
// pass any options to esbuild here...
entryPoints: ["src/app.jsx"],
outdir: "dist",
define: { "process.env.NODE_ENV": '"production"' },
watch: true,
});
async function serve(){
console.log("running server from: https://:8080/");
await servor({
// pass any options to servor here...
browser:true,
root: "dist",
port: 8080,
});
}
serve();
Führen Sie nun `node watch.js` in der Kommandozeile aus. Dies gibt uns einen schönen Dev-Server, obwohl er uns wieder kein Hot Module Replacement oder Fast Refresh bietet (d.h. Ihr clientseitiger Zustand wird nicht beibehalten). Aber das war für meine Testzwecke ausreichend.
Auch wenn wir unsere gesamte Anwendung jedes Mal neu bündeln, wenn wir eine Datei speichern, müssten wir eine ziemlich riesige Anwendung haben, bevor esbuild langsamer wird. Nachdem ich dieses Tooling eingerichtet hatte, erhielt ich sofortiges Feedback von Änderungen. Mein Computer verwendet einen Intel i7 aus dem Jahr 2012, also ist es sicherlich keine Spitzenmaschine.
Wenn Sie eine vorkonfigurierte Version von esbuild mit Live-Reload und einigen React-Standardeinstellungen benötigen, können Sie dieses Repo klonen.
Unterstützte Dateien
esbuild kann CSS in JavaScript importieren, wenn das Ihr Stil ist. Es kompiliert CSS in eine Ausgabedatei mit demselben Namen wie Ihre Hauptausgabe-JavaScript-Datei. Es kann auch CSS-`@import`-Anweisungen standardmäßig bündeln. Es gibt keine Unterstützung für CSS Modules, aber es gibt Pläne dafür.
Es gibt eine wachsende Community von Plugins für esbuild. Zum Beispiel gibt es Plugins für Vue Single File Components und Svelte Components.
esbuild arbeitet mit JSON-Dateien und kann sie ohne Konfiguration in JavaScript-Module bündeln.
Es kann auch Bilder in JavaScript importieren, mit der Option, sie entweder in Daten-URLs umzuwandeln oder sie in einen Ausgabeordner zu kopieren. Dieses Verhalten ist nicht standardmäßig aktiviert, aber Sie können das Folgende in Ihr esbuild-Konfigurationsobjekt einfügen, um eine der Optionen zu aktivieren:
loader: { '.png': 'dataurl' } // Converts to data url in JS bundle
loader: { '.png': 'file' } // Copies to output folder
Code-Splitting scheint noch in Arbeit zu sein, ist aber im ESM-Ausgabeformat weitgehend vorhanden, und es sieht so aus, als ob es eine Priorität für das Projekt ist. Es ist auch erwähnenswert, dass Tree-Shaking standardmäßig in esbuild integriert ist und nicht ausgeschaltet werden kann.
Produktions-Build
Die Verwendung der Optionen "minify" und "bundle" in Ihrem esbuild-Befehl erstellt kein ganz so kleines Bundle wie eine Rollup/Terser-Pipeline. Dies liegt daran, dass esbuild einige Optimierungen der Bundle-Größe opfert, um in möglichst wenigen Durchläufen durch Ihren Code zu gelangen. Der Unterschied kann jedoch vernachlässigbar sein und für die Erhöhung der Bündelgeschwindigkeit, je nach Projekt, lohnenswert sein. In meinem Klon der Snap Shot-Anwendung erstellte esbuild ein Bundle von 177 KB, was nicht viel mehr ist als die 165 KB, die von Vite produziert wurden, das Rollup und Terser verwendet.
Gesamt
| esbuild | |
|---|---|
| Vorlagen für verschiedene Frontend-Frameworks | ❌ |
| Entwicklungsserver mit Hot Module Replacement | ❌ |
| Streaming-Imports | ❌ |
| Vorkonfigurierter Produktions-Build | ❌ |
| Automatische PostCSS- und Präprozessor-Konvertierung | ❌ |
| HTM-Transform | ❌ |
| Rollup-Plugin-Unterstützung | ❌ |
| Größe auf der Festplatte (Standardinstallation) | 7,34 MB |
esbuild ist ein extrem mächtiges Werkzeug. Aber es kann schwierig sein, wenn man an Zero-Config-Setups gewöhnt ist. Wenn Sie mehr brauchen, sollten Sie sich das nächste Tool, Snowpack, ansehen, das esbuild verwendet.
Snowpack
Snowpack ist ein Build-Tool von den Machern von Skypack und Pika. Es bietet einen großartigen Entwicklungsserver und wurde mit der Philosophie des "unbundled development" entwickelt. Um die Dokumentation zu zitieren: "Sie sollten einen Bundler verwenden können, weil Sie es wollen, und nicht, weil Sie es müssen."
Standardmäßig bündelt der Build-Schritt von Snowpack keine Dateien zu einem einzigen Paket, sondern liefert ungebündelte ESM-Module, die im Browser laufen. esbuild ist tatsächlich als Abhängigkeit enthalten, aber die Idee ist, JavaScript-Module zu verwenden und nur mit esbuild zu bündeln, wenn es benötigt wird.
Snowpack hat eine sehr slick Dokumentation, einschließlich einer Liste von Anleitungen für die Verwendung mit JavaScript-Frameworks und einer Vielzahl von Vorlagen dafür. Einige Anleitungen sind noch in Arbeit, aber andere wie die für React sind schön und klar. Es sieht auch so aus, als ob Snowpack Svelte als erstklassigen Bürger behandelt. Ich habe zum ersten Mal von Snowpack in Rich Harris' Vortrag "Futuristic Web Development" auf der Svelte Summit 2020 gehört. Allerdings sollte das kommende Svelte-Meta-Framework SvelteKit von Snowpack angetrieben werden, hat aber inzwischen auf Vite umgestellt (das wir als nächstes besprechen werden).
Anwendungsfälle
Snowpack ist eine gute Wahl, wenn Sie auf ungebündelte Bereitstellung setzen möchten. Sie schreiben vielleicht Quellcode mit einer kleinen Anzahl von Modulen. Das würde bedeuten, dass Sie mit einem ungebündelten Build keinen großen Request-Wasserfall erstellen. Wenn Sie die zusätzliche Komplexität und technische Schuld des Bündelns nicht benötigen, ist Snowpack eine ausgezeichnete Wahl. Ein guter Anwendungsfall wäre, wenn Sie schrittweise ein Frontend-Framework in eine serverseitig gerenderte oder statische Anwendung integrieren. Sie würden so wenig Tooling wie möglich aus dem Node-Ökosystem ziehen, aber immer noch die Vorteile deklarativer Frontend-Frameworks nutzen.
Zweitens würde ich argumentieren, dass Snowpack ein großartiger Wrapper um esbuild ist. Wenn Sie esbuild ausprobieren möchten, aber auch einen Entwicklungsserver und vorgefertigte Vorlagen für Frontend-Frameworks wünschen, können Sie mit Snowpack nichts falsch machen. Aktivieren Sie esbuild im Build-Schritt Ihrer Snowpack-Konfiguration und Sie sind bereit.
Nach aktuellem Stand würde ich argumentieren, dass Snowpack kein guter Ersatz für ein Zero-Config-Tool wie create-react-app wäre, da Sie Plugins einbinden und selbst konfigurieren müssen, wenn Sie eine große Anwendung haben und einen super-schicken, optimierten, produktionsreifen Build-Schritt benötigen.
Setup
Lassen Sie uns ein Projekt mit Snowpack beginnen, indem wir in die Kommandozeile springen:
mkdir snowpackproject
cd snowpackproject
npm init #fill with defaults
npm install snowpack
Fügen wir nun das Folgende zu `package.json` hinzu:
// package.json
"scripts": {
"start": "snowpack dev",
"build": "snowpack build"
},
Als nächstes erstellen wir eine Konfigurationsdatei:
// Mac or Linux
touch snowpack.config.js
// Windows
new-item snowpack.config.js
Ich denke, der magischste Teil von Snowpack kommt, wenn man ein unschuldig aussehendes Schlüssel-Wert-Paar in der Konfigurationsdatei einstellt. Fügen Sie dies zum Beispiel in die Konfigurationsdatei ein:
// snowpack.config.js
module.exports = {
packageOptions: {
"source": "remote",
}
};
`source: remote` aktiviert etwas namens Streaming Imports. Streaming Imports ermöglichen es Snowpack, die npm-Installation zu umgehen, indem Bare Imports (z.B. `import React from 'react';`) in CDN-Imports von Skypack umgewandelt werden.
Als nächstes erstellen wir eine `index.html`-Datei:
<!--index.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">>
<title>Snowpack streaming imports</title>
</head>
<body>
<div id="root"></div>
<!-- Note the type="module". This is important for JavaScript module imports. -->
<script type="module" src="app.js"></script>
</body>
</html>
Und schließlich fügen wir eine `app.jsx`-Datei hinzu:
// app.jsx
import React from 'react'
import ReactDOM from 'react-dom'
const App = ()=>{
return <h1>Welcome to Snowpack streaming imports!</h1>
}
ReactDOM.render(<App />,document.getElementById('root')); 0
Beachten Sie, dass wir zu keinem Zeitpunkt React oder ReactDOM über npm installiert haben. Aber wenn wir den Snowpack-Entwickler-Server so starten:
./node_modules/.bin/snowpack dev
…funktioniert unsere App trotzdem!
Anstatt aus einem `node_modules`-Ordner zu laden, lädt Snowpack das npm-Paket von Skypack herunter, einem CDN, das das npm-Registry hostet, und es ist vorkompiliert, um im Browser zu funktionieren. Snowpack liefert es dann unter einer `./_snowpack/pkg`-URL aus.
Verwendung
Dies ist ein großer Schritt weg vom Node/npm-basierten Workflow. Was wir uns tatsächlich ansehen, ist ein neuer Workflow basierend auf CDN/JavaScript-Modulen.
Wenn wir jedoch unsere App wie sie ist ausführen und einen Produktions-Build durchführen, wirft Snowpack einen Fehler. Das liegt daran, dass es die Versionen von React und ReactDOM kennen muss, die es beim Erstellen verwenden soll. Sie können dies beheben, indem Sie in eine `snowpack.deps.json`-Datei schreiben, die automatisch durch Ausführen des folgenden Befehls erstellt werden kann:
./node_modules/.bin/snowpack add react
./node_modules/.bin/snowpack add react-dom
Das lädt das Paket nicht von npm herunter, sondern zeichnet die Version der für Snowpack-Builds verwendeten Pakete auf.
Ein Vorbehalt ist, dass wir auf Entwickler-Fehlermeldungen verzichten müssen, da Skypack die Produktionsversion von Paketen ausliefert.
Selbst wenn wir keine Streaming-Imports verwenden, bündelt der Snowpack-Entwickler-Server jede Abhängigkeit aus `node_modules` in eine JavaScript-Datei pro Abhängigkeit, konvertiert diese Dateien in ein natives JavaScript-Modul und liefert sie dann an den Browser. Das bedeutet, der Browser kann diese Skripte cachen und sie nur neu anfordern, wenn sie sich geändert haben. Der Entwicklungsserver aktualisiert sich automatisch beim Speichern, bewahrt aber nicht den clientseitigen Zustand. Alle Abhängigkeiten von Node schienen out-of-the-box zu funktionieren, unabhängig davon, ob sie Legacy-Modulformate oder Node-APIs (wie das berüchtigte `process.env`, mit dem wir bei esbuild Probleme hatten) verwendeten.
Die Beibehaltung des clientseitigen Zustands in React erfordert react-refresh, was einige Babel-Pakete als eigene Abhängigkeiten benötigt. Diese sind nicht standardmäßig enthalten, sind aber über die umfangreichere React-Vorlage verfügbar. Die Vorlage lädt react-refresh, Prettier, Chai und React Testing Library, was insgesamt ein Node-Abhängigkeitspaket von 80 MB ergibt.
npx create-snowpack-app my-react-project --template @snowpack/app-template-react
Unterstützte Dateien
JSX wird unterstützt, aber standardmäßig ebenfalls nur mit `.jsx`-Dateien. Snowpack erkennt automatisch, ob React oder Preact verwendet wird, und entscheidet entsprechend, welche Renderfunktion für die JSX-Transformation verwendet wird. Wenn wir JSX jedoch weiter anpassen möchten, müssten wir Babel über ihr Plugin einbinden. Es gibt auch ein Snowpack-Plugin für Vue Single File Components und natürlich für Svelte Components. Außerdem kompiliert Snowpack TypeScript, aber für die Typüberprüfung benötigen wir das TypeScript-Plugin.
CSS kann in JavaScript importiert und zur Laufzeit in den `
` des Dokuments eingefügt werden. CSS-Module werden ebenfalls standardmäßig zur Strukturierung unterstützt, solange sie die Erweiterung `.module.css` haben.Importierte JSON-Dateien werden in ein JavaScript-Modul mit einem Objekt als Standardexport umgewandelt. Snowpack unterstützt Bilder und kopiert sie in den Produktionsordner. Entsprechend seiner ungebündelten Philosophie enthält Snowpack keine Bilder als Daten-URLs im Bundle.
Produktions-Build
Der Standardbefehl `snowpack build` kopiert im Grunde die exakte Quellcode-Struktur in einen Ausgabeordner. Für Dateien, die zu JavaScript kompiliert werden (z.B. TypeScript, JSX, JSON, `.vue`, `.svelte`), transformiert er jede einzelne Datei in ein separates, browserfreundliches JavaScript-Modul.
Das funktioniert gut, ist aber für die Produktion nicht ideal, da es zu einem großen Wasserfall von Anfragen kommen kann, wenn der Quellcode in viele Dateien aufgeteilt ist. In der Snap Shot-Anwendung hatte ich am Ende 184 KB Quellcode-Dateien, die dann weitere 105 KB an Abhängigkeiten von Skypack anforderten, was zu einem ziemlich großen Wasserfall führte.
Allerdings zieht Snowpack esbuild als Abhängigkeit heran, und wir können esbuild aktivieren, um unseren Code zu bündeln, zu minifizieren und zu kompilieren, indem wir ein "optimize"-Objekt zur Snowpack-Konfiguration hinzufügen:
// snowpack.config.js
module.exports = {
optimize: {
bundle: true,
minify: true,
target: 'es2018',
},
};
Dies führt den Code mit den von esbuild bereitgestellten Optimierungsfunktionen aus, sodass wir durch Hinzufügen dieser Optionen denselben Build erhalten, den wir zuvor mit esbuild hatten.
Da esbuild noch keine Version 1.0 erreicht hat, empfiehlt Snowpack für Produktions-Builds entweder das webpack- oder das Rollup-Plugin, die beide konfiguriert werden müssen.
Gesamt
Snowpack bietet eine leichtgewichtige Entwicklererfahrung mit einem voll ausgestatteten Entwicklungsserver, detaillierter Dokumentation und einfach zu installierenden Vorlagen. Sie müssen entscheiden, ob Sie Ihre Anwendung bündeln möchten und wie Sie dies tun möchten. Wenn Sie ein Tool wünschen, das sowohl einen Dev-Server als auch einen stärker meinungsgeprägten Build-Schritt bietet, sollten Sie sich Vite, das nächste Tool auf unserer Liste, ansehen.
| Snowpack | |
|---|---|
| Vorlagen für verschiedene Frontend-Frameworks | ✅ |
| Entwicklungsserver mit Hot Module Replacement | ✅ (bei Verwendung von Vorlagen) |
| Streaming-Imports | ✅ |
| Vorkonfigurierter Produktions-Build | ❌ |
| Automatische PostCSS- und Präprozessor-Konvertierung | ❌ |
| HTM-Transform | ❌ |
| Rollup-Plugin-Unterstützung | ✅ (bei Verwendung von snowpack-plugin-rollup-bundle für den Build-Schritt) |
| Größe auf der Festplatte (Standardinstallation) | 16 MB |
Vite
Vite wird vom Vue-Schöpfer (und Hades Speedrunner) Evan You entwickelt. Wo esbuild sich auf den Build-Schritt konzentriert und Snowpack auf den Entwicklungsserver, bietet Vite beides: einen vollständigen Entwicklungsserver und einen optimierten Build-Befehl mit Rollup.
Anwendungsfälle
Wenn Sie einen ernsthaften Konkurrenten für Vue CLI/Create-React-App suchen, ist Vite derjenige, der am nächsten herankommt, da er mit "batteries included"-Funktionen ausgestattet ist. Der blitzschnelle Entwicklungsserver und der Zero-Config-optimierte Produktions-Build bedeuten, dass Sie von Null bis zur Produktion ohne jegliche Konfiguration gelangen können. Vite ist ein Werkzeug, das sowohl in einem winzigen Nebenprojekt als auch in einer großen Produktionsanwendung verwendet werden kann. Ein guter Anwendungsfall für Vite wäre jede größere Single Page App.
Warum würden Sie Vite nicht verwenden? Vite ist ein meinungsgeprägtes Tool, und Sie könnten mit seinen Meinungen nicht einverstanden sein. Sie möchten vielleicht Rollup nicht für Ihren Build verwenden (wir haben darüber gesprochen, wie schnell esbuild ist), oder Sie möchten, dass Ihr Tooling Ihnen die volle Leistung von Babel, eslint und dem Ökosystem der webpack-Loader out-of-the-box bietet.
Auch wenn Sie Zero-Config-Server-Side-Rendering-Meta-Frameworks wünschen, wäre es besser, bei webpack-basierten Frameworks wie Nuxt.js und Next.js zu bleiben, bis die Geschichte für Vite-Server-Side-Rendering vollständiger ist.
Setup
Vite hat meinungsgeprägtere Standardeinstellungen als esbuild und Snowpack. Seine Dokumentation ist klar und detailliert. Wir erhalten volle Unterstützung für Vue, da Evan der Schöpfer ist und so weiter, also ist Vite ein definitiver Happy Path für Vue-Entwickler. Nichtsdestotrotz kann Vite mit jedem Frontend-Framework verwendet werden und bietet sogar eine Liste von Vorlagen für den Einstieg.
Verwendung
Vites Entwicklungsserver ist ziemlich leistungsstark. Vite bündelt alle Abhängigkeiten eines Projekts zu einem einzigen nativen JavaScript-Modul mit esbuild, liefert es dann mit einem stark gecachten HTTP-Header aus. Das bedeutet, dass nach dem ersten Seitenaufruf keine Zeit mit Kompilieren, Ausliefern oder Anfordern von importierten Abhängigkeiten verschwendet wird. Vite bietet auch klare Fehlermeldungen, indem es den genauen Codeblock und die Zeilennummern zur Fehlerbehebung anzeigt. Auch bei Vite hatte ich keine Probleme, Abhängigkeiten einzubinden, die Node-APIs oder ältere Formate verwendeten. Sie schienen alle in ein browserkompatibles ES-Modul "gepatched" worden zu sein.
Vites React- und Vue-Vorlagen binden Plugins ein, die Hot Module Replacement aktivieren. Die Vue-Vorlage bindet ein Vue-Plugin für Single File Components und ein Vue-Plugin für JSX ein. Die React-Vorlage bindet das react-refresh-Plugin ein. In jedem Fall bieten beide Hot Module Replacement und Beibehaltung des clientseitigen Zustands. Sicher, sie fügen ein paar weitere Abhängigkeiten hinzu, einschließlich Babel-Paketen, aber Babel ist bei der Verwendung von JSX in Vite nicht wirklich notwendig. Standardmäßig funktioniert JSX genauso wie esbuild – es wird in `React.createElement` umgewandelt. Es importiert React nicht automatisch, aber sein Verhalten kann konfiguriert werden.
Und während wir schon dabei sind, unterstützt Vite keine Streaming-Imports wie Snowpack und wmr. Das bedeutet, dass Abhängigkeiten wie üblich über npm installiert werden.
Eine coole Sache ist, dass Vite experimentelle Unterstützung für Server-Side Rendering bietet. Wählen Sie Ihr bevorzugtes Framework und generieren Sie statisches HTML, das direkt an den Client geliefert wird. Im Moment sieht es so aus, als müssten wir diese Architektur selbst aufbauen, aber trotzdem scheint dies eine gute Gelegenheit für Meta-Frameworks zu sein, die auf Vite aufbauen. Evan You hat bereits eine Arbeit in Arbeit namens VitePress, ein Ersatz für VuePress mit den Vorteilen der Verwendung von Vite. Und Sveltekit hat Vite auch zu seiner Abhängigkeitsliste hinzugefügt. Es sieht so aus, als ob die Einbindung von CSS-Code-Splitting einer der Gründe war, warum Sveltekit zu Vite gewechselt hat.
Unterstützte Dateien
Für CSS bietet Vite die meisten Funktionen aller Tools, die wir betrachten. Es unterstützt das Bündeln von CSS-Imports sowie CSS-Modulen. Aber wir können auch PostCSS-Plugins per `npm install` installieren und eine `postcss.config.js`-Datei erstellen, und Vite beginnt automatisch, diese Transformationen auf CSS anzuwenden.
Wir können CSS-Präprozessoren installieren und verwenden – einfach den Präprozessor `npm install`en und die Datei in die richtige Erweiterung umbenennen (z.B. `.filename.scss`), und Vite beginnt, die entsprechenden Präprozessoren anzuwenden. Und, wie wir im Überblick sagten, unterstützt Vite CSS-Code-Splitting.
Bildimporte sind standardmäßig öffentliche URLs, aber wir können sie auch als Strings in das Bundle laden, indem wir einen `?raw`-Parameter am Ende des URL-Strings verwenden.
JSON-Dateien können in der Quelle importiert und in ein ES-Modul umgewandelt werden, das ein einzelnes Objekt exportiert. Wir können auch einen benannten Import bereitstellen, und Vite sucht im "root"-Feld der JSON-Datei nach dem Import und "treeshakt" den Rest.
Produktions-Build
Vite verwendet Rollup für einen vorkonfigurierten Produktions-Build mit einer Reihe von Optimierungen. Es liefert bewusst einen Zero-Config-Build, der für die meisten Anwendungsfälle ausreichen sollte.
Der Build kommt mit den Rollup-Funktionen, die wir erwarten: Bündeln, Minifizieren und Tree-Shaking. Aber wir bekommen auch Extras, wie Code-Splitting für dynamische Imports und etwas namens "asynchrones Chunk-Laden", was eine schicke Art ist zu sagen, dass, wenn wir ein JavaScript-Modul anfordern, das ein anderes Modul importiert, der Build vorkompiliert wird, um beide gleichzeitig (asynchron) zu laden.
Beim Ausführen von Vites Standard-Build mit der Snap Shot-App hatte ich einen 5 KB großen JavaScript-Datei und eine 160 KB große JavaScript-Datei (insgesamt 165 KB) und die gesamte CSS im Projekt wurde automatisch zu einer winzigen 2,71 KB-Datei minifiziert.
Gesamt
Die meinungsgeprägte Natur von Vite macht es zu einem ernsthaften Konkurrenten unserer aktuellen Tooling. Viel Arbeit wurde investiert, um die Entwicklererfahrung wirklich nahtlos zu gestalten und Out-of-the-Box produktionsreife Builds zu erstellen.
| Vite | |
|---|---|
| Vorlagen für verschiedene Frontend-Frameworks | ✅ |
| Entwicklungsserver mit Hot Module Replacement | ✅ (bei Verwendung von Vorlagen) |
| Streaming-Imports | ❌ |
| Vorkonfigurierter Produktions-Build | ✅ |
| Automatische PostCSS- und Präprozessor-Konvertierung | ✅ |
| HTM-Transform | ❌ |
| Rollup-Plugin-Unterstützung | ✅ |
| Größe auf der Festplatte (Standardinstallation) | 17,1 MB |
wmr
Wie Vite ist wmr ein weiteres meinungsgeprägtes Build-Tool, das sowohl einen Entwicklungsserver als auch einen Build-Schritt bietet. Es wurde vom Schöpfer von Preact, Jason Miller, entwickelt, daher ist es definitiv ein Happy Path für Preact-Entwickler. Jason Miller erklärte das Denken hinter wmr, als er als Gast in der JS Party Podcast war.
Preact ist winzig und es ist wirklich gut, wenn man ein leichtgewichtiges Projekt machen will. Wo ist unser Tooling dafür? Wir haben ein webpack-basiertes Tool, das in der Produktion von vielen hochkarätigen Websites verwendet wird, aber das ist das schwere Werkzeug. Wo ist das Prototyping-Tool? Das war die eine Hand. Die andere Hand bin ich und ein paar andere, die dem Preact-Team angehören; Wir waren eine Weile am Rande des Bundler-Ökosystems, haben Leute angestoßen und versucht, einen Konsens über eine Richtung zu finden, in die wir uns bewegen können, um diese Idee des Schreibens von modernem Code und des Auslieferns von modernem Code weiter voranzutreiben.
Das sagt uns, dass wmr alles darum geht, modernen Code zu schreiben und auszuliefern, und leichteres Tooling in einem Projekt zu ermöglichen.
Sie fragen sich vielleicht, wofür wmr steht? Nichts! Die Namen "Web Modules Runtime" und "Wet Module Replacement" wurden diskutiert, aber es ist eine falsche Abkürzung, ähnlich wie npm.
wmr ist mit derselben rücksichtslosen Bereinigung der Bundle-Größe wie Preact gebaut, daher ist es winzig – es wiegt nur 2,6 MB und enthält exakt Null npm-Abhängigkeiten. Trotzdem schafft es, viele wirklich fantastische Funktionen zu packen, darunter einen Hot-Module-Replacing-Entwicklungsserver und einen optimierten Produktions-Build.
Anwendungsfälle
Ich würde wmr verwenden, wenn ich schnell einen Prototyp mit Preact erstellen wollte. Es gibt keine Konfiguration und es dauert nur Sekunden zum Herunterladen. Es fühlt sich an wie die Verwendung eines superaufgeladenen statischen Dateiservers. Mit TypeScript, einem optimierten Build-Schritt und statischem HTML-Rendering bietet wmr alles, was für die Auslieferung kleiner bis mittelgroßer Anwendungen benötigt wird. Seine geringe Größe ist auch großartig, um schnell eine Bibliothek auszuprobieren oder eine Idee zu demonstrieren.
wmr ist vielleicht nicht das richtige Werkzeug für Sie, wenn Sie nicht Preact, React oder Vanilla JavaScript verwenden. Das Preact-Team stellt noch keine Vorlagen für andere Frameworks bereit. Die Dokumentation ist auch nicht so detailliert wie bei den anderen Tools, die wir uns angesehen haben. Das bedeutet, je weiter Sie vom Happy Path abweichen, desto mehr müssen Sie in den Quellcode eintauchen. Daher kann ich es nicht empfehlen, wenn viel Anpassung erforderlich ist.
Setup
Wenn Sie Preact verwenden, ist absolut keine Einrichtung erforderlich, außer einem schnellen npm-Install. Um React anstelle von Preact mit wmr zu verwenden, sind derzeit zwei Schritte erforderlich. Zuerst aliasieren Sie `htm/preact` zu `htm/react` und `react` zu `es-react` in Ihrem `package.json`.
"alias": {
"htm/preact": "htm/react",
"react": "es-react"
},
Fügen Sie dann Imports von `es-react` in Ihre Komponenten hinzu:
// ReactDOM only needed on root render
import { React, ReactDOM,} from 'es-react';
Das bedeutet, dass wir nicht tatsächlich das normale React-Paket verwenden, an das Sie vielleicht gewöhnt sind, sondern stattdessen React aus es-react laden. Das liegt daran, dass wmr davon abhängt, dass Pakete mit nativen JavaScript-Modulen kompatibel sind. React verwendet standardmäßig keine nativen Module, sondern einen älteren Modulstil namens UMD-Module. es-react ist ein Paket, das React lädt, aber Exporte bereitstellt, die mit der Web-Plattform kompatibel sind.
Dies veranschaulicht die Philosophie von wmr, native Primitive der Web-Plattform zu verwenden, anstatt Tooling zu verwenden, um sie zu umgehen und abzubilden.
Eine weitere Option könnte die Verwendung von Skypack-Imports in unserer Anwendung sein, die ebenfalls vorkompiliert sind, um im Browser zu funktionieren:
import React from 'https://cdn.skypack.dev/react';
import ReactDOM from 'https://cdn.skypack.dev/react-dom';
wmr erwartet, dass Sie modernen Code schreiben, der im Browser läuft, was bedeuten kann, dass Sie einige Konfigurationen vornehmen müssen, wenn Sie Abhängigkeiten einbinden, die Node-APIs oder ältere Modulsysteme verwenden. Um die Snap Shot-App zum Laufen zu bringen, musste ich in die Node-Module eintauchen und eine oder zwei Bibliotheken konvertieren, um native JavaScript-Modulsyntax zu verwenden. Das könnte Sie verlangsamen, wenn Sie ältere Bibliotheken verwenden. Das Preact-Ökosystem ist für den Browser optimiert und sollte keine Nacharbeit erfordern. Dies ist ein weiterer Grund, sich in wmr an den Preact-Happy-Path zu halten.
Es gibt Plugins für wmr. Es exponiert eine Plugin-API, die Rollup-Plugins für einen Build-Schritt unterstützt. Es gibt immer mehr wmr-spezifische Beispiele in den Docs, darunter ein Plugin, das HTML minifiziert, und eines, das dateisystembasiertes Routing–komponentenladung bietet.
wmr unterstützt verschiedene Frameworks, aber es gibt keine vorgefertigten Vorlagen dafür. Und anfangs fand ich die Konfiguration des JSX-Transforms ziemlich schwierig. Trotzdem hat Jason bestätigt, dass es Pläne gibt, JSX konfigurierbarer zu machen, und dass wmr als Framework-agnostisch gedacht ist. JSX soll in regulären JavaScript-Dateien out-of-the-box funktionieren.
Verwendung
Um zu beginnen, können Sie entweder diesen Befehl in der Kommandozeile ausführen:
npm init wmr your-project-name
Oder alternativ können Sie diese Befehle ausführen, um Ihre Anwendung manuell aufzubauen:
npm init -y
npm install wmr
mkdir public
touch public/index.html
touch public/index.js
Fügen Sie dann einen Skript-Import im Body Ihrer `index.html` hinzu (achten Sie wieder darauf, `type="module"` zu verwenden):
<script type="module" src="./index.js"></script>
Jetzt können Sie ein Preact-Hello-World in Ihre `index.js`-Datei schreiben:
import { render } from 'preact';
render(<h1>Hello World!</h1>, document.body);
Und schließlich starten Sie Ihren Entwicklungsserver:
node_modules/.bin/wmr
Jetzt haben wir einen vollständigen Hot-Module-Replacement-Entwicklungsserver, der sofort auf alle Änderungen an unserem Quellcode reagiert.
wmr verwendet `htm`, wenn JSX transformiert wird, was einige großartige Vorteile bietet. Nehmen wir an, wir schreiben einen Zähler mit Preact in wmr und machen einen Fehler:
import { render } from 'preact';
import { useState } from 'preact/hooks';
function App() {
const [count,setCount] = useState(0)
return <>
<button onClick={()=>{setCount(cout+5)}}>Click to add 5 to count</button> // HIGHLIGHT
<p>count: {count}</p>
</>
}
render(<App />, document.body);
`count` ist im `onClick`-Handler-Funktion falsch geschrieben, daher führt die Ausführung dieses Codes zu einem Fehler. Normalerweise müssten wir uns auf unser Tooling und eine Source Map verlassen, um Informationen darüber zu erhalten, wo sich der Fehler befindet, aber wmr verfolgt eine andere Lösung. Mit htm kommt es dem nativen JSX im Browser so nahe wie möglich, indem es tagged template literals verwendet. Also, wo das Schreiben von React- oder Preact-Code normalerweise so aussieht:
<MyComponent>I am JSX. I am not actually valid Javascript</MyComponent>
…sieht htm eher so aus:
html`<${MyComponent}>I am about as close as it gets to JSX as you can get while being able to run in the browser</MyComponent>`
Wenn wir nun unseren Code debuggen und das "Sources"-Panel in DevTools öffnen, sollten wir ein Skript sehen, das dem Quellcode im Editor fast identisch ist.

Auf diese Weise können wir ordnungsgemäß untersuchen, wo sich Fehler im Browser befinden, ohne Sourcemaps verwenden zu müssen. Sicher, dieses spezielle Beispiel ist ziemlich konstruiert, aber Sie können sehen, wie nützlich dies sein könnte, da es bedeutet, dass wmr in Ihrer Entwicklungsumgebung keine Sourcemaps benötigt.
wmr unterstützt Streaming-Imports standardmäßig, sodass Bare Imports aus dem npm-Registry heruntergeladen werden. Dies geschieht durch einen komplexen Prozess, der den gesamten Quellcode im npm-Paket untersucht, alle Tests und Metadaten entfernt und ihn in einen einzigen nativen JavaScript-Import umwandelt. Ähnlich wie Snowpack ist es möglich, eine komplexe App zu erstellen, ohne npm zu verwenden, um etwas zu installieren. Tatsächlich ist wmr das erste Tool, das diese Idee unterstützt.
Unterstützte Dateien
Was andere Dateitypen betrifft, die wmr unterstützt: CSS-Dateien können in JavaScript importiert werden, und CSS-Module werden ebenfalls unterstützt.
Es gibt keine integrierte Unterstützung für Vue Single File Components oder Svelte Components. Allerdings arbeitet der Build-Schritt von wmr mit Rollup-Plugins zusammen, und der Entwicklungsserver kann mit Polka/Express Middleware konfiguriert werden, sodass es möglich ist, diese zu verwenden, um Imports in Vue- und Svelte-Komponenten umzuwandeln. Tatsächlich habe ich ein kleines Plugin für Vue Single File Components geschrieben, um zu zeigen, wie das gehen könnte.
Wir können Bilder nicht ohne ein Plugin in JavaScript als Daten-URLs in wmr importieren. Stattdessen müssen wir sie mit einer syntaktisch korrekten JavaScript-Methode importieren. Wenn wir also zum Beispiel ein Bild eines Hundes in unserem öffentlichen Ordner haben, könnten wir es in einer Preact-Komponente wie folgt einbinden:
function Dog() {
return <img src={new URL('./dog.jpg', import.meta.url)} alt="dog hanging out"></img>
}
Und sobald der Build-Schritt ausgeführt wird, wird das Bild kopiert und ist aus dem Distributionsordner zugänglich. Es gibt Hot Module Replacement für Bilder im Entwicklungsserver, sodass Änderungen an Bildern sofort im Browser widergespiegelt werden.
Eine weitere Anmerkung zur Dateisupport: JSON kann importiert und in ein JavaScript-Objekt zur Verwendung umgewandelt werden. Aber beim tatsächlichen Erstellen einer Anwendung benötigen wir das Rollup JSON-Plugin.
Produktions-Build
wmr bietet einen Produktions-Build-Schritt, der Bündeln, Minifizieren und Tree-Shaking ohne zusätzliche Abhängigkeiten beinhaltet. Wenn man sich den Quellcode von wmr ansieht, scheint es, dass Rollup und Terser im Hintergrund verwendet werden, und minifizierte Versionen davon sind im wmr-Paket enthalten. Das wmr-Bundle für die Snap Shot-App war 164 KB groß, also erzeugte es ein Bundle, das nur geringfügig kleiner war als die Gesamtgröße der beiden von Vite erstellten JavaScript-Dateien.
Es gibt auch eine Möglichkeit, wmr so zu konfigurieren, dass es eine Anwendung in statisches HTML rendert und im Browser mit preact-iso hydriert. Das bedeutet, wmr kann als Meta-Framework für Preact verwendet werden, ähnlich wie Next.js.
Gesamt
Ich liebe die Erfahrung, wmr zum Prototypisieren von React- und Preact-Anwendungen zu verwenden. Es fühlt sich großartig an, mit einem Werkzeug zu beginnen, das lächerlich klein ist, aber Entwickler-Annehmlichkeiten bietet, die fast an schwere Bundler heranreichen.
| wmr | |
|---|---|
| Vorlagen für verschiedene Frontend-Frameworks | ✅ |
| Entwicklungsserver mit Hot Module Replacement | ✅ |
| Streaming-Imports | ✅ |
| Vorkonfigurierter Produktions-Build | ✅ |
| Automatische PostCSS- und Präprozessor-Konvertierung | ❌ |
| HTM-Transform | ✅ |
| Rollup-Plugin-Unterstützung | ✅ |
| Größe auf der Festplatte (Standardinstallation) | 2,57 MB |
Funktionsvergleich
Wir haben gerade viel Stoff behandelt! Anstatt diesen Artikel auf und ab zu scrollen, um die Ergebnisse zu vergleichen, habe ich alles hier zusammengestellt, um zu sehen, wie die Tools nebeneinander bestehen. Ich habe sogar zusätzliche Vergleiche für Funktionen aufgenommen, die wir nicht explizit behandelt haben.
Anwendungsfälle
| Tool | Anwendungsfall |
|---|---|
| esbuild | Große Codebasen. Noch nicht produktionsreif. |
| Snowpack | Kleine Anwendungen, die kein Bündeln benötigen, oder Anwendungen, bei denen Sie wählen möchten, welchen Bundler Sie verwenden. Auch gut für die schrittweise Einführung von JavaScript-Frameworks in serverseitig gerenderte Apps. |
| Vite | Ersatz für Vue CLI/Create-React-App zur Erstellung von Single-Page-Anwendungen. Dies ist der Happy Path für Vue. |
| wmr | Prototypen. Gut für kleine bis mittelgroße Apps und kann für Single-Page- oder serverseitig gerenderte Apps verwendet werden. Dies ist der Happy Path für Preact. |
Setup
| esbuild | Snowpack | Vite | wmr | |
|---|---|---|---|---|
| Vorlagen für verschiedene Frontend-Frameworks | ❌ | ✅ | ✅ | ❌ |
| Größe auf der Festplatte (Standardinstallation) | 7,34 MB | 16 MB | 17,1 MB | 2,57 MB |
| Zero-Config-Produktions-Build | ❌ | ❌ | ✅ | ✅ |
| HMR Development Server mit Zero Config | ❌ | ✅ | ✅ | ✅ |
| Verarbeitung von `process.env` für Node-Pakete | ❌ | ✅ | ✅ | ✅ |
Entwicklungsserver
| esbuild | Snowpack | Vite | wmr | |
|---|---|---|---|---|
| Hot Module Replacement | ❌ | ✅ | ✅ | ✅ |
| CSS Hot Replacement | ❌ | ✅ | ✅ | ✅ |
| npm-Abhängigkeiten Vorab-Bündelung | ❌ | ✅ | ✅ | ❌ |
| Browser-Fehlermeldungen | ❌ | ✅ | ✅ | ❌ |
| HTM-Transform | ❌ | ❌ | ❌ | ✅ |
Produktions-Build
| esbuild | Snowpack | Vite | wmr | |
|---|---|---|---|---|
| Ausgabe Bundle-Größe der Snap Shot App | 177 KB | 184 KB aus mehreren JavaScript-Dateien, plus 105 KB von Skypack CDN-Abhängigkeiten | 165 KB (eine 5 KB-Datei und eine 160 KB-Datei) | 164 KB |
| Go-basiertes Bündeln | ✅ | ✅ bei Verwendung von esbuild im Build-Schritt | ❌ | ❌ |
| Vorkonfigurierter Produktions-Build | ❌ | ❌ | ✅ | ✅ |
| Asynchrones Chunk-Laden | ❌ | ❌ | ✅ | ✅ |
| Rollup-Plugin-Unterstützung | ❌ | ✅ | ✅ | ✅ |
Weitere Funktionen
| esbuild | Snowpack | Vite | wmr | |
|---|---|---|---|---|
| Streaming-Imports | ❌ | ✅ | ❌ | ✅ |
| Server-Side Rendering | ❌ | ❌ | ✅ (experimentell) | ✅ |
| CSS Modules | ❌ | ✅ | ✅ | ✅ |
| Automatische PostCSS- und Präprozessor-Konvertierung | ❌ | ❌ | ✅ | ❌ |
Zusammenfassung
Ich bin begeistert davon, JavaScript-Anwendungen mit allen Tools zu erstellen, die wir gerade betrachtet haben. Egal, ob wir ein kleines Nebenprojekt oder eine große Produktionsseite schreiben, all diese Tools beschleunigen Feedbackschleifen und steigern die Produktivität. Sie haben die Tore geöffnet, um zu fragen, was für das JavaScript-Ökosystem notwendig ist und ob wir den Ballast, der durch Legacy-Module und Browser mitgebracht wird, abbauen können. Diese Tools werden die Einstiegshürde für neue Entwickler senken, indem sie eine schlankere, schnellere Entwicklungsumgebung mit weniger Abstraktionen zwischen dem Code, der geschrieben wird, und dem Code, der im Browser läuft, bieten.
Wenn Sie es leid sind, auf das Herunterladen Ihrer Abhängigkeiten und das Ausführen Ihrer Build-Schritte zu warten, empfehle ich Ihnen, diese neue Generation von Tooling auszuprobieren.
Weitere Lektüre
- "Vergleiche mit anderen No-Bundler-Lösungen" (Vite)
- "Lass uns esbuild lernen! (mit Sunil Pai)" (Jason Lengstorf)
- Durch die Pipeline: Eine Erkundung von Frontend-Bundlern (Andrew Walpole)
Korrektur in den Tabellen am Ende
Unter "Entwicklungsserver": Snowpack unterstützt npm-Abhängigkeiten-Vorab-Bündelung (mit Rollup, wenn keine Streaming-Imports verwendet werden).
Unter "Produktions-Build": Vite unterstützt Rollup-Plugins.
Danke Evan, mein Fehler. Ich habe die Tabellen jetzt korrigiert. Außerdem bin ich mir sicher, dass Sie Ihre Speedrun-Zeit in Hades seit dem von mir verlinkten Tweet verbessert haben!
Fantastische Arbeit! Zweifellos der beste und tiefgehendste Überblick über die etwas überwältigende Landschaft des Next-Gen-JS-Tooling. Sehr nützlich! Danke.
Ich frage mich, ob Sie erwägen würden, diesen Artikel vierteljährlich (oder so ähnlich) zu aktualisieren? Die Dinge bewegen sich derzeit sehr schnell in diesem Bereich, und wahrscheinlich werden all diese Tools in den nächsten Jahren zumindest erheblich wachsen und sich verändern.
Hallo Rasmus, vielen Dank für die lieben Kommentare! Ich habe mein Bestes getan, um einen guten Überblick zu geben, also freue ich mich, dass er hilfreich sein konnte.
Ich werde mein Bestes tun, um die Dinge aktuell zu halten und alle paar Monate nach neuen Fortschritten bei den Tools zu suchen.
Endlich ein guter Artikel, gut gemacht, Hugh!
Toller Artikel, es wäre schön, wenn Sie ihn alle paar Monate aktualisieren würden, da sich alles so schnell ändert. Svelte ist gerade zu Vite gewechselt, habe ich gelesen.
Es wäre vielleicht erwähnenswert, welche weit verbreiteten Drittanbieterbibliotheken Probleme bereiten würden.
Zum Beispiel ist Jest (das im Node-Bereich lebt) derzeit nicht einfach mit Vite zu verwenden.
Ich frage mich, warum Sie im Artikel angeben, dass `Process.env handling for node packages` nicht von esbuild unterstützt wird.
Das ist mit seiner "define"-Option (https://esbuild.github.io/api/) super einfach.
Sie haben Recht, es ist super einfach und in der Dokumentation klar ersichtlich, wie das `process.env`-Problem gelöst werden kann.
Allerdings erledigt esbuild dies nicht automatisch/standardmäßig. Alle anderen Tools scheinen dies ohne Konfiguration/Argumente zu handhaben.
Sie könnten dies jedoch tatsächlich als Vorteil von esbuild betrachten. Wenn Sie "Magie" vermeiden und explizit darlegen möchten, wie Ihr Build-Tool Node-APIs für den Browser shimmt, bevorzugen Sie vielleicht den esbuild-Stil, indem Sie explizit angeben, wie es damit umgeht.
Ich frage mich nur, warum Sie einen Befehl mit
./node_modules/.bin/esbuildausführen und nicht mitnpx esbuild?Weil ich nicht wusste, dass npx das tut.
Oder mit den Worten von Krusty dem Clown "Weil ich ein Idiot bin, glücklich?"
Ich würde Dev-Mode-Sourcemaps zur Feature-Liste hinzufügen. Da dies als kritisches Feature für die Möglichkeit, Code zu debuggen, betrachtet wird.
+1, ich auch!
Mich würde interessieren, ob Sie Chrome Dev Tools ausprobiert haben, um mit einem dieser neuen Tools an Sourcen zu debuggen. Ich versuche, Vite zu verwenden, aber wenn Sie eine Datei bearbeiten, endet HMR damit, dass die Datei nicht mehr in Dev Tools geöffnet ist. Wenn Sie sie dann wieder öffnen, gehen alle gesetzten Breakpoints verloren. Dies liegt daran, dass Dev Tools sie als unterschiedliche Datei betrachtet. Das ist für mich ein Showstopper.
Mich wundert, dass Sie dafür Chrome Dev Tools verwenden. Fügen Sie Debug-Breakpoints in VS Code hinzu.
Danke für den Artikel, tolle Zusammenfassung! Mir ist gerade aufgefallen, dass Sie am Ende sagen, dass Snowpack keine CSS-Module unterstützt, was es scheinbar tut (laut Doku).
Außerdem habe ich gelesen, dass das Testen mit Jest oder anderen in Vite etwas umständlich werden kann. Haben Sie damit Erfahrungen?
Ups! Guter Hinweis auf die Snowpack CSS-Module. Ich habe es in den Tabellen aktualisiert. Im Artikel habe ich bestätigt, dass CSS-Module in Snowpack funktionieren, habe aber in der Tabelle einen Fehler gemacht.
Die meisten dieser Tools werden zu diesem Zeitpunkt nicht gut mit Jest funktionieren.
Es ist noch in Arbeit, aber für Vite gibt es einen vite-jest Wrapper
https://github.com/sodatea/vite-jest
Es gibt auch ein gutes Video zur Verwendung von Cypress zum Testen mit Vite hier
https://www.vuemastery.com/conferences/vueconf-us-2021/component-testing-with-vite-vue-and-cypress/
Und wenn Sie bereit sind, zu einem anderen Tool zu wechseln, ist ein beliebter ESM-first Unit-Test-Runner: https://github.com/lukeed/uvu
Dies ist ein großartiger Überblick über die Build-Tools der nächsten Generation, Hugh – eine nützliche Referenz, danke.
Ich bin seit einiger Zeit mit etablierten Tools (wie Webpack etc.) vertraut, aber ich habe mich nie wirklich mit der ganzen Kultur von Build-Tools und Toolchains beschäftigt, die in den 2010er Jahren entstanden ist.
Also… das erfordert vielleicht einen weiteren Artikel, aber nur für den Fall, dass es eine kurze Antwort gibt… was ist der zugrunde liegende Zweck von Build-Tools?
Welche Probleme lösen sie?
Ich weiß, wenn ich an meinem Stack arbeite, der aus verschiedenen einzelnen HTML-, CSS-, JS-, SVG-, JSON-, ESM- und PHP-Dateien besteht, brauche ich kein Build-Tool, also erkenne ich, dass sie nichts für mich sind (noch nicht jedenfalls)… aber woran arbeiten Entwickler, die Build-Tools verwenden (welche Dateien? welche Formate?), dass sie dann ein Build-Tool benötigen, um das, was sie geschrieben haben, in ein vom Server/Browser konsumierbares Format umzuorganisieren?
Ich wäre dankbar für jede Aufklärung, die jemand, der dies liest, zu meiner gut gemeinten, aber letztendlich verwirrten Neugier geben kann.
Hier sind einige Gründe, warum Sie Frontend-Build-Tools verwenden möchten
Zusätzlich und als Teil des Node/NPM-Ökosystems…
Was es wert ist, ich benutze Parcel 2.
Ich denke, Kev hat es ziemlich gut auf den Punkt gebracht! Wie Sie sehen können, ist "Build-Tools" ein ziemlich allgemeiner Begriff, und diese Tools können viel tun, daher gibt es keine kurze Antwort.
Wenn Sie Vanilla JavaScript und CSS von Hand schreiben und zufrieden sind, den exakten Code zu liefern, den Sie schreiben, benötigen Sie möglicherweise kein Build-Tool.
In JavaScript-lastigen Projekten möchten Sie jedoch wahrscheinlich das Schreiben Ihres JS in eine Reihe von Modulen aufteilen. Wenn der Browser all diese als separate Dateien anfordern muss, kann dies zu einer langen Kette von Anfragen führen und lange zum Laden dauern. Bundler schlagen die JS-Module zu einer einzigen Datei zusammen (oder verwenden cleveres Code-Splitting, sodass jede Seite genau das bekommt, was sie braucht).
Möglicherweise möchten Sie Ihr JavaScript minimieren, damit Ihre Formatierung, Variablennamen und Kommentare nicht die Menge an JavaScript erhöhen, die Sie ausliefern. Alle Tools in diesem Artikel tun dies für Sie.
Sie schreiben möglicherweise JS mit APIs, die nur neuere Browser haben, unterstützen aber weiterhin ältere Browser. Babel ist ein branchenüblicher Tool, um neuere APIs automatisch zu polyfillen, damit sie von älteren Browsern unterstützt werden können.
Sie möchten vielleicht in TypeScript schreiben. Oder früher Coffeescript. Vielleicht lieben Sie Closure und möchten ClosureScript ausprobieren. Wenn Sie React-Code schreiben, verwenden Sie normalerweise eine Syntax namens "JSX". All dies muss in JS transpilert werden, bevor es im Browser funktioniert. Dann benötigen Sie eine Build-Pipeline!
Und bisher habe ich nur über JavaScript gesprochen! Wie Kev erwähnte, unterstützen viele dieser Tools die Verarbeitung von CSS, Bildern, JSON – die Liste geht weiter.
Wenn Sie PHP schreiben und die Art und Weise, wie Sie JavaScript schreiben und statische Assets verarbeiten, für Sie funktioniert, dann ändern Sie nichts!
Aber wenn Sie denken, dass einige dieser Automatisierungen hilfreich sein könnten, dann ist es an der Zeit, ein Build-Tool einzuführen.
Das Tolle an den in diesem Artikel aufgeführten Tools ist, dass sie alle leichtgewichtig und superschnell sind. So sollten Sie sie einführen können, ohne eine Woche lernen zu müssen, wie man sie benutzt, und Ihren Workflow komplett verlangsamen, während Sie darauf warten, dass sie transpilieren.
Danke, Kev Bonett und Hugh Haworth – enorm erhellend.
Das hilft wirklich, etwas unterstützenden Kontext für diejenigen von uns zu geben, die mit den Anwendungsfällen, in denen Build-Tools üblicherweise eingesetzt werden, relativ wenig vertraut sind.
"Vite bündelt alle Abhängigkeiten eines Projekts zu einem einzigen nativen JavaScript-Modul mit esbuild"
Sie meinten Rollup, nicht esbuild, oder?
Nein, ich meinte dort esbuild. Vite verwendet beide Bundler: esbuild in seinem Entwicklungsserver zum Vorbündeln von Abhängigkeiten und rollup für den Produktions-Build-Schritt.
Ihnen fehlt ein Index für "Maintainer-Zealotry". Vite-Maintainer sind auf einem Kreuzzug gegen Bibliotheken, die ursprünglich für Node geschrieben wurden und Polyfills benötigen. Sie schließen Bug-Reports explizit mit "wontfix" und bieten als Abhilfemaßnahme nur "schauen Sie sich dieses Repository an, um herauszufinden, wie jemand anderes dieses Problem gelöst hat" an.
Dies erschwert die Einführung erheblich und erhöht die allgemeine Reibung erheblich, bis das Internet mit Anleitungen aufholt.
Dies ist eine großartige Ressource, aber ich empfehle, sie zu aktualisieren, um Snowpack fallen zu lassen (wird nicht mehr gepflegt und sie empfehlen Vite als Ersatz) und Parcel hinzuzufügen (Version 2 verwendet jetzt swc, was es zu einem Build-Tool der neuen Generation macht).