Als ich beschloss, meine aktuelle persönliche Website auf Eleventy zu basieren, wollte ich das Rad nicht neu erfinden: Ich testete alle Eleventy-Starter, die mit Tailwind CSS erstellt wurden und die ich in den Starter Projects aus der Dokumentation finden konnte.
Viele der Starter schienen Tailwind CSS auf eine umständliche Weise zu integrieren. Außerdem schienen einige von ihnen davon auszugehen, dass niemand die Tailwind-Konfiguration während der Arbeit an einer Website im laufenden Betrieb aktualisiert. Deshalb habe ich Eleventy selbst mit Tailwind CSS und Alpine.js integriert. Ich habe Grund zu der Annahme, dass Ihnen die Einfachheit meiner Lösung gefallen wird.
Gutes Design ist so wenig Design wie möglich.
— Dieter Rams, 10 Prinzipien für gutes Design
Wenn Sie sich nicht für die Details interessieren, können Sie gerne meinen Starter herunterladen und direkt loslegen.
Erste Schritte
Ich gehe davon aus, dass Sie ein allgemeines Verständnis von Tailwind CSS, HTML, JavaScript, Nunjucks, der Kommandozeile und npm haben.
Beginnen wir mit einem neuen Ordner, wechseln dann mit cd in diesen Ordner und initialisieren ihn mit einer package.json-Datei.
npm init -y
Jetzt können wir Eleventy und Tailwind CSS installieren.
npm install -D @11ty/eleventy tailwindcss@latest
Wir müssen eine Seite erstellen, um zu testen, ob wir die Dinge erfolgreich eingerichtet haben. In einem echten Anwendungsfall werden unsere Seiten Vorlagen verwenden, also werden wir das auch hier tun. Dort kommt Nunjucks ins Spiel und dient als Vorlagen-Engine.
Erstellen wir eine neue Datei namens index.njk im Projektordner. Wir werden sie als Homepage festlegen.
{% extends "_includes/default.njk" %}
{% block title %}It does work{% endblock %}
{% block content %}
<div class="fixed inset-0 flex justify-center items-center">
<div>
<span class="text-change">Good design</span><br/>
<span class="change">is<br/>as little design<br/>as possible</span>
</div>
</div>
{% endblock %}
Grundlegende Vorlagenverwaltung
Erstellen wir nun einen neuen Ordner im Projektordner namens _includes (und ja, der Ordnername ist wichtig). Innerhalb dieses neuen Ordners erstellen wir eine Datei namens default.njk, die wir als Standardvorlage für unser Layout verwenden werden. Wir halten die Dinge einfach mit einem grundlegenden HTML-Boilerplate.
<!DOCTYPE html>
<html lang="en">
<head>
<title>
{% block title %}Does it work?{% endblock %}
</title>
<meta charset="UTF-8"/>
{% if description %}
<meta name="description" content="{{description}}"/>
{% endif %}
<meta http-equiv="x-ua-compatible" content="ie=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, viewport-fit=cover"/>
<link rel="stylesheet" href="/style.css?v={% version %}"/>
{% block head %}{% endblock %}
</head>
<body>
{% block content %}
{{ content | safe }}
{% endblock %}
</body>
</html>
Konfigurieren von Tailwind CSS
Kümmern wir uns um einen Test für Tailwind CSS mit so wenigen Schritten wie möglich. Erstellen Sie zuerst einen neuen Unterordner namens styles und darin eine Datei namens tailwind.config.js.
module.exports = {
content: ['_site/**/*.html'],
safelist: [],
theme: {
extend: {
colors: {
change: 'transparent',
},
},
},
plugins: [],
}
Erstellen Sie dann eine Datei namens tailwind.css im selben styles-Ordner.
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer utilities {
.change {
color: transparent;
}
}
Starten und Erstellen des Projekts
Erstellen wir nun eine weitere neue Datei im selben Stammverzeichnis namens .gitignore. Dies ermöglicht es uns zu definieren, welche Dateien beim Übertragen des Projekts in ein Repository, z. B. auf GitHub, übersprungen werden sollen.
_site/
.DS_Store
node_modules/
Als Nächstes erstellen wir eine Datei namens .eleventy.js (beachten Sie den führenden Punkt), die Eleventy im Grunde konfiguriert und ihm mitteilt, welche Dateien überwacht und wo seine Arbeit gespeichert werden soll.
const now = String(Date.now())
module.exports = function (eleventyConfig) {
eleventyConfig.addWatchTarget('./styles/tailwind.config.js')
eleventyConfig.addWatchTarget('./styles/tailwind.css')
eleventyConfig.addPassthroughCopy({ './_tmp/style.css': './style.css' })
eleventyConfig.addShortcode('version', function () {
return now
})
};
Wir können nun die Datei package.json mit allen Skripten aktualisieren, die wir benötigen, um die Website während der Entwicklung zu starten und zu erstellen. Die Abhängigkeiten sollten nach der anfänglichen Einrichtung bereits vorhanden sein.
{
"scripts": {
"start": "eleventy --serve & npx tailwindcss -i styles/tailwind.css -c styles/tailwind.config.js -o _site/style.css --watch",
"build": "ELEVENTY_PRODUCTION=true eleventy && NODE_ENV=production npx tailwindcss -i styles/tailwind.css -c styles/tailwind.config.js -o _site/style.css --minify"
},
"devDependencies": {
"@11ty/eleventy": "^1.0.0",
"tailwindcss": "^3.0.0"
}
}
Hey, großartige Arbeit! Wir haben es geschafft. Starten wir die Website offiziell.
npm start
Öffnen Sie die Seite https://:8080 in Ihrem Browser. Sie wird nicht nach viel aussehen, aber überprüfen Sie den Seitentitel in der Browser-Registerkarte.

Wir können noch ein wenig mehr überprüfen, um sicherzustellen, dass alles in Ordnung ist. Öffnen Sie /styles/tailwind.config.js und ändern Sie den Wert der transparent-Farbe in etwas anderes, z. B. black. Die Tailwind-Konfiguration sollte zusammen mit der Seite in Ihrem Browser neu geladen werden.
Verlieren Sie Ihren Browser nicht aus den Augen und bearbeiten Sie /styles/tailwind.css, indem Sie transparent wieder in black ändern. Ihre CSS-Datei sollte neu geladen und in Ihrem Browser aktualisiert werden.
Jetzt können wir gut mit Eleventy und Tailwind CSS arbeiten!
Optimieren der Ausgabe
Zu diesem Zeitpunkt funktioniert Tailwind CSS mit Eleventy, aber das generierte HTML ist nicht perfekt, da es Dinge wie überflüssige Zeilenumbruchzeichen enthält. Lassen Sie uns das bereinigen.
npm install -D html-minifier
Fügen Sie die folgende Zeile am Anfang der Datei .eleventy.js hinzu.
const htmlmin = require('html-minifier')
Wir müssen auch htmlmin in .eleventy.js konfigurieren.
eleventyConfig.addTransform('htmlmin', function (content, outputPath) {
if (
process.env.ELEVENTY_PRODUCTION &&
outputPath &&
outputPath.endsWith('.html')
) {
let minified = htmlmin.minify(content, {
useShortDoctype: true,
removeComments: true,
collapseWhitespace: true,
});
return minified
}
return content
})
Wir verwenden hier einen Transform, was eine Eleventy-Sache ist. Transforms können die Ausgabe einer Vorlage ändern. Zu diesem Zeitpunkt sollte .eleventy.js wie folgt aussehen.
const htmlmin = require('html-minifier')
const now = String(Date.now())
module.exports = function (eleventyConfig) {
eleventyConfig.addWatchTarget('./styles/tailwind.config.js')
eleventyConfig.addWatchTarget('./styles/tailwind.css')
eleventyConfig.addShortcode('version', function () {
return now
})
eleventyConfig.addTransform('htmlmin', function (content, outputPath) {
if (
process.env.ELEVENTY_PRODUCTION &&
outputPath &&
outputPath.endsWith('.html')
) {
let minified = htmlmin.minify(content, {
useShortDoctype: true,
removeComments: true,
collapseWhitespace: true,
})
return minified
}
return content
})
}
Lassen Sie uns npm start erneut ausführen. Sie werden sehen, dass sich nichts geändert hat, und das liegt daran, dass die Optimierung nur während des Builds erfolgt. Versuchen Sie stattdessen npm run build und schauen Sie sich dann den Ordner _site an. Es sollte kein einziges unnötiges Zeichen in der Datei index.html vorhanden sein. Das Gleiche gilt für die Datei style.css.
Ein so erstelltes Projekt ist nun bereit für die Bereitstellung. Gut gemacht! 🏆
Integration von Alpine.js
Ich habe mich entschieden, von Gatsby.js zu Eleventy zu wechseln, da es mir einfach zu viel JavaScript war. Ich bin mehr an einer vernünftigen Dosis Vanilla JavaScript gemischt mit Alpine.js interessiert. Wir werden hier nicht auf die Besonderheiten von Alpine.js eingehen, aber es lohnt sich, Hugo DiFrancescos Primer zu lesen, da er ein perfekter Ausgangspunkt ist.
So können wir es über die Kommandozeile in unser Projekt installieren.
npm install -D alpinejs
Jetzt müssen wir .eleventy.js mit dieser Funktion aktualisieren, die Dinge an Alpine.js weitergibt.
eleventyConfig.addPassthroughCopy({
'./node_modules/alpinejs/dist/cdn.js': './js/alpine.js',
})
Zuletzt öffnen wir _includes/default.njk und fügen Alpine.js direkt vor dem schließenden </head>-Tag hinzu.
<script src="/js/alpine.js?v={% version %}"></script>
Wir können überprüfen, ob Alpine funktioniert, indem wir dies zu index.njk hinzufügen.
{% extends "_includes/default.njk" %}
{% block title %}It does work{% endblock %}
{% block content %}
<div class="fixed inset-0 flex justify-center items-center">
<div>
<span class="text-change">Good design</span><br/>
<span class="change">is<br/>as little design<br/>as possible</span><br/>
<span x-data="{message:'🤖 Hello World 🤓'}" x-text="message"></span>
</div>
</div>
{% endblock %}
Starten Sie das Projekt.
npm start
Wenn Alpine.js funktioniert, sehen Sie "Hello World" in Ihrem Browser. Glückwunsch, doppelt! 🏆🏆
Ich hoffe, Sie sehen, wie schnell ein Eleventy-Projekt eingerichtet werden kann, einschließlich der Integration von Nunjucks für die Vorlagenverwaltung, Tailwind für Stile und Alpine.js für Skripte. Ich weiß, dass die Arbeit mit neuer Technologie überwältigend und sogar verwirrend sein kann. Wenn Sie also Probleme beim Start haben oder eine Idee haben, wie dies noch weiter vereinfacht werden kann, können Sie mir gerne eine E-Mail an [email protected] senden.
Toller Artikel! Tailwind hat "eingebaute" Purge in der neuesten Version, die in der Tailwind-Konfigurationsdatei konfiguriert werden kann. Vielleicht könnten wir das anstelle der Konfiguration in der Postcss-Konfiguration nutzen? https://tailwindcss.com/docs/controlling-file-size
Hallo Mario! Ich freue mich, dass Ihnen der Artikel gefallen hat. :)
Vielen Dank für den Vorschlag – ein valider Punkt!
Die Nutzung des "eingebauten" Purge macht Sinn, wenn Sie PostCSS nicht für etwas anderes in Ihrem Setup verwenden. In diesem Fall ist das Setup so minimalistisch wie möglich, daher verwende ich PostCSS nicht nur für Tailwind, sondern auch für den Autoprefixer, um das CSS nach dem Entfernen der ungenutzten Teile zu minimieren (und dies sind nur die im Artikel aufgeführten Elemente; ich verwende PostCSS in meinen Projekten auch für andere Dinge).
Außerdem ist die Verwendung von PostCSS hier nicht meine Idee. :) Die Dokumentation von Tailwind besagt:
„Für die meisten Projekte möchten Sie Tailwind als PostCSS-Plugin in Ihre Build-Kette einbinden.“
Dieser Artikel ist ein Versuch, Eleventy, Tailwind und Alpine auf die "natürlichste" Weise miteinander zum Laufen zu bringen.
Noch einmal: Vielen Dank, Mario! :)
Wenn ich etwas übersehe, lassen Sie es mich bitte wissen.
Es klingt nicht so, als ob Mario vorschlägt, PostCSS komplett abzuschaffen, sondern eher die integrierte PurgeCSS von Tailwind zu nutzen, um die Dinge noch weiter zu vereinfachen.
tailwind.config.js
postcss.config.js
tailwind.css
Guter Artikel, Greg. Kleine Anmerkung, aber trotzdem eine Anmerkung: Ich habe mitgemacht und war bereits mit Tailwind vertraut, als ich dachte, es sei seltsam, dass ich nicht einfach einen bg-blue-300 oder so testen konnte. Keine der Farben, und dann sah ich, wie Sie die Farben in tailwind.config definiert haben. Es ist einfacher (besser?), dies über extend zu tun.
theme: {
extend: {
colors: {
cyan: “#9cdbff”,
},
},
},
da die unbenutzten sowieso entfernt werden. Vielleicht sogar die neue Purge-Option in Tailwind selbst nutzen.
https://tailwindcss.com/docs/controlling-file-size/
Vielen Dank, Leute! Ihr habt mich überzeugt. Ich habe den Artikel und den Starter aktualisiert. Mario, Justin, Tom, danke. :)
Tailwind ist seltsam. Ein riesiges CSS-Paket erstellen und dann definieren, was nicht darin enthalten ist?
Bei der Entwicklung ist es wirklich nützlich, alle verfügbaren Utility-Stile zur Verfügung zu haben. Aber Sie brauchen nicht *jeden* Stil für die Produktion – nur die, die Sie verwenden.
Ich schätze diesen Artikel wirklich. Ich dachte schon seit einiger Zeit, dass dieser Stack brillant wäre, sowohl in Bezug auf die Anpassbarkeit als auch auf die Leichtigkeit. Ich werde diese Anleitung bald für einige persönliche Projekte verwenden.
Hallo Greg!
Toller Artikel! Allerdings benötigen Sie die Purge-Abhängigkeit nicht mehr separat! Wenn Sie Ihr PostCSS-Skript mit der NODE_ENV auf "production" setzen und den purge-Schlüssel in Ihrer Tailwind-Datei konfigurieren, erledigt es das für Sie!
Meine persönliche Website verwendet genau diesen Stack und ist mit weniger Abhängigkeiten konfiguriert, und alles CSS und JS läuft über Rollup zur Minifizierung!
Es ist hier verfügbar: https://github.com/mattwaler/website
Hallo, ich habe nicht ganz verstanden, warum wir Stile nach _tmp rendern und dann nach _site kopieren. Warum nicht direkt in _site rendern? Danke!
Hallo! :) Eine großartige Frage. Ohne den von Ihnen erwähnten Workaround könnten wir kein sauberes Hot-Reloading-Erlebnis genießen.
Habe ein Problem :(
Ich mache das, aber dann funktioniert
bg-indigo-500nicht. Ich kann nurbg-indigoverwenden.Danke für diesen Starter, ich habe gerade mit Eleventy angefangen und mich mit Tailwind CSS und natürlich auch mit Alpine JS vertraut gemacht. Ich freue mich darauf, das Projekt, das ich seit Jahren im Kopf habe, zu bauen und zu gestalten. Danke.
Gute Arbeit, fügen Sie vielleicht die README.md zum .eleventyignore hinzu und ich denke, die JS-Ausgabedatei ist immer noch nicht minifiziert.
Ich dachte also, es wäre eine gute Idee, diese Idee zu kopieren, eine Version an den Link zum Stylesheet anzuhängen.
Beim Überprüfen der Quelle der verschiedenen Seiten, die von Eleventy generiert wurden und alle dieselbe
head.njk-Komponente verwenden, die in meinebase.njkeingebunden ist, sehe ich für dieselbe CSS-Datei einen anderen Versions-Tag. Ich vermute, dass dieses Ergebnis es nicht interessant macht, diese Taktik zu verwenden.Hier sind einige der generierten Version-Tags: 1614537697642, 1614537697643, 1614537697634; für drei verschiedene Seiten.
Der Tag sollte nur einmal pro Build generiert werden, jetzt wird er jedes Mal generiert, wenn eine einzelne Seite geschrieben wird. Vielleicht könnte es mit einem etwas anderen Ansatz funktionieren. Vielleicht bin ich es nur, ich weiß es nicht.
Wäre es möglich, diesen Tag in einer Variablen zu generieren, entweder in eleventy.js oder einer anderen .js-Datei außerhalb, und dann denselben Tag im gesamten (Neu-)Build zu verwenden, bis zu einem weiteren (Neu-)Build?
in eleventy.js
in default/head.njk
Hallo Michel! Vielen Dank für deinen Kommentar. Du hast recht, tut mir leid, ich habe den Artikel aktualisiert. :)
Ich habe Ihr Tutorial durchgearbeitet und Alpine nicht zum Laufen gebracht. Aktualisieren Sie .eleventy.js mit
das alpine Node-Modul heißt jetzt cdn.js nicht alpine.js
Danke, eb! Aktualisiert. :)
Danke für diesen Artikel, Greg. Als relativer Neuling (habe vorher nur Hugo benutzt) bei der Eleventy/Tailwind/Alpine-Kombination habe ich sie als Erfrischung empfunden.
Ich habe nur eine Frage. Ihr "npm start"-Befehl erstellt eine versionierte CSS-Datei, und doch gibt der Build-Befehl nur eine styles.css-Datei aus. Wie lautet der angepasste Build-Befehl, um Versionierung/Cache-Busting in meinen endgültigen _site-Ordner zu integrieren?
Entschuldigen Sie das, wahrscheinlich eine leicht zu beantwortende Frage, aber wie gesagt, ich bin hier relativ neu und finde online keine einfache Hilfe.
Vielen Dank für eine tolle Frage, Richard! :)
<link rel="stylesheet" href="/style.css?v={% version %}"/>in der Vorlage ist für die Versionskontrolle/Cache-Busting verantwortlich.Auch wenn Sie Ihre Website z. B. auf Netlify hosten, benötigen Sie AFAIK
?v={% version %}nicht für Versionskontrolle/Cache-Busting.Nette Kombination. Alpine sieht nach etwas aus, das mir gefallen würde. Ich mag Tailwind, wenn es einmal eingerichtet ist, aber es ist eine solche Qual, es zu tun.
Ich wollte wirklich, dass das funktioniert, aber ich schaffe es nicht. Die Konfigurationsvariante von "An diesem Punkt sollte .eleventy.js wie folgt aussehen" gibt mir 3 Fehler in VSC. Deklaration oder Anweisung erwartet, aber ich sehe sie nicht.
Danke, Little! :) Ich habe es gerade in VSC unter macOS getestet. Keine Fehler. Ich vermute, die Ursache des Problems liegt bei einer der Erweiterungen, die Sie in Ihrer VSC installiert haben. Viel Glück! :)
Hm, ich verstehe nicht, warum dieses Setup unter Windows nicht funktioniert. Wahrscheinlich ein Problem mit der Server-Synchronisation oder ./ in den Pfaden, aber CORS-Fehler No-sniff erscheint und ich kann CSS nicht importieren. Vielleicht bin ich es nur, aber für mich funktioniert es nicht :(
@Ivan das Problem mit Windows ist die Verkettung von Befehlen mit " & " oder " && " in den Start- und Build-Skripten. Versuchen Sie das
und ändern Sie die Skripte zu
Da ist ein kleiner Fehler in Ihrem Code,
const now = String(Date.now())außerhalb der Funktion bedeutet, dass der Wert nach dem anfänglichen Laden nicht neu berechnet wird. Nachfolgende Hot-Reloads lösen nur die Funktion aus. Diese Zeile sollte sich innerhalb der exportierten Funktion befinden.