Es geht hier um eine sehr spezifische Kombination von Technologien – Eleventy, der Static Site Generator, mit Seiten, die Bilder enthalten, die Sie letztendlich von Cloudinary gehostet haben möchten – aber ich möchte es einfach dokumentieren, da es sich anhört, als ob eine anständige Anzahl von Leuten auf diese Situation stößt.
Das Geschäft
- Cloudinary hat eine Fetch-URL-Funktion, was bedeutet, dass Sie nichts lernen müssen (schön!), um ihren Service zu nutzen. Sie benötigen ein Konto, aber danach können Sie Ihre Bilder einfach mit einer Cloudinary-URL präfixen, und dann ist es Cloudinary, das Ihr Bild optimiert, skaliert, formatiert und über CDN liefert. Super. Es ist nicht der einzige Dienst, der das tut, aber es ist ein guter.
- Aber… das Bild muss im öffentlichen Internet verfügbar sein. In der Entwicklung sind Ihre Bild-URLs wahrscheinlich nicht dort. Sie sind wahrscheinlich lokal gespeichert. Idealerweise könnten wir also weiterhin lokale URLs für Bilder in der Entwicklung verwenden und das Cloudinary-Fetching in der Produktion durchführen.
Mehrere Leute haben dies auf verschiedene Arten gelöst. Ich werde dokumentieren, wie ich es gemacht habe (weil ich es am besten verstehe), aber auch verlinken, wie mehrere andere Leute es gemacht haben (was schlauer sein könnte, Sie entscheiden).
Das Ziel
- In der Entwicklung sehen Bilder so aus:
/images/image.png - In der Produktion sehen Bilder so aus:
https://res.cloudinary.com/css-tricks/image/fetch/w_1200,q_auto,f_auto/https://production-website.com/images/image.png
Wenn wir das also schablonieren würden (nehmen wir hier Nunjucks an, da es eine schöne Vorlagensprache ist, die Eleventy unterstützt), erhalten wir so etwas wie diesen Pseudocode:
<img src="
{{CLOUDINARY_PREFIX}}{{FULLY_QUALIFIED_PRODUCTION_URL}}{{RELATIVE_IMAGE_URL}}
"
alt="Don't screw this up, fam."
/>
| Entwicklung | Produktion | |
{{CLOUDINARY_PREFIX}} | “” | „https://res.cloudinary.com/css-tricks/image/fetch/w_1200,q_auto,f_auto/“ |
{{FULLY_QUALIFIED_PRODUCTION_URL}} | “” | „https://production-website.com“ |
{{RELATIVE_IMAGE_URL}} | „/images/image.jpg“ | „/images/image.jpg“ |
Der Trick besteht dann darin, diese… ich schätze, wir werden sie globale Variablen nennen?… einzurichten. Wahrscheinlich sind es nur die ersten beiden. Den relativen Bildpfad würden Sie wahrscheinlich von Hand nach Bedarf schreiben.
Eleventy hat hier einige Magie verfügbar. Jede *.js-Datei, die wir in einem _data-Ordner ablegen, wird zu Variablen, die wir in Vorlagen verwenden können. Wenn wir also z.B. /src/_data/sandwiches.js erstellen würden und es so aussähe:
module.exports = {
ham: true
}
In unserer Vorlage könnten wir {{sandwiches.ham}} verwenden, und das wäre als {{true}} definiert.
Da es sich hier um JavaScript (Node) handelt, haben wir die Möglichkeit, einige Logik basierend auf *anderen* Variablen durchzuführen. In unserem Fall sind einige andere globale Variablen nützlich, insbesondere die process.env-Variablen, die Node zur Verfügung stellt. Viele Hoster (Netlify, Vercel usw.) machen „Umgebungsvariablen“ zu einer Sache, die Sie in ihrem System einrichten können, sodass process.env diese während der Build-Prozesse auf ihrem System verfügbar hat. Das könnten wir tun, aber das ist ziemlich spezifisch und an diese Hoster gebunden. Eine andere Möglichkeit, eine globale Node-Variable festzulegen, ist, sie buchstäblich auf der Kommandozeile festzulegen, bevor Sie einen Befehl ausführen. Wenn Sie also Folgendes tun würden:
SANDWICH="ham" eleventy
Dann wäre process.env.SANDWICH überall in Ihrem Node JavaScript ham. Wenn wir all das kombinieren… sagen wir, unser Produktions-Build-Prozess setzt eine Variable, die die Produktion anzeigt, wie:
PROD="true" eleventy
Aber in der lokalen Entwicklung führen wir es *ohne* diese globale Variable aus. Nutzen wir also diese Informationen bei der Einrichtung einiger globaler Variablen, um unsere Bildquellen zu erstellen. In /src/_data/images.js (vollständiges Beispiel aus der Praxis) machen wir Folgendes:
module.exports = {
imageLocation:
process.env.PROD === 'true'
? 'https://coding-fonts.css-tricks.com'
: '',
urlPrefix:
process.env.PROD === 'true'
? 'https://res.cloudinary.com/css-tricks/image/fetch/w_1600,q_auto,f_auto/'
: ''
};
Sie könnten auch process.env.CONTEXT === 'deploy-preview' überprüfen, um Netlify-Deploy-Preview-URLs zu testen, falls Sie die Logik dort anders gestalten möchten.
Nun können wir in jeder unserer Vorlagen {{images.imageLocation}} und {{images.urlPrefix}} verwenden, um die Quellen zu erstellen.
<img
src="
{{images.urlPrefixLarge}}{{images.imageLocation}}/image.png
"
alt="Useful alternative text."
/>
Und da haben wir es. Das wird eine lokale/relative Quelle in der Entwicklung sein, und dann wird es in der Produktion diese mit Präfix und vollständig qualifizierte URL, über die Cloudinarys Fetch funktioniert.
Jetzt, wo es auf Cloudinary ist, können wir noch einen Schritt weiter gehen. Die Präfix-URL kann angepasst werden, um Bilder zu skalieren, was bedeutet, dass wir selbst mit nur einer einzigen Quellbild eine ziemlich angemessene Konfiguration für responsive images erzielen können. Hier ist diese Konfiguration, die mehrere Präfixe verfügbar macht, so dass sie für die vollständige Syntax verwendet werden können.
Das Endergebnis bedeutet ein lokal relatives Bild in der Entwicklung

srcset ist eher ein Produktionsbelang.…und Cloudinary Fetch-URLs in der Produktion

Ideen anderer Leute
Phil hat neulich gezeigt, wie man Netlify-Redirects dafür verwendet.
Dann ist der Trick für die lokale Entwicklung, die 404s abzufangen und sie lokal umzuleiten mit weiteren Redirects.
Wenn das manuelle Erstellen von Responsive-Images-Syntax zu mühsam ist (was es ist), empfehle ich dringend, es zu abstrahieren. In Eleventy gibt es ein Projekt von Nicolas Hoizey: eleventy-plugin-images-responsiver. Eric Portis hat ebenfalls eines, eleventy-respimg, das, wie hier gezeigt, speziell Cloudinary verwendet.
Um zu beweisen, dass diese Dinge die Leute wirklich beschäftigt haben, hat Tim Kadlec gerade über „Proxying Cloudinary Requests with Netlify“ gebloggt. Er erweitert Phils Tweet und fügt einige zusätzliche Performance-Kontexte und Fallstricke hinzu.
Oder Sie könnten browsersync-images-middleware einen kleinen Dreh geben, ob im Eleventy-Umfeld oder nicht!
Was bedeutet, dass Sie noch keinen spezifischen CDN verwenden *müssen*.