Entwickler fügen SVG häufig direkt in JSX ein. Dies ist bequem zu verwenden, erhöht jedoch die Größe des JS-Bundles. Im Streben nach Optimierung habe ich beschlossen, eine andere Möglichkeit zu finden, SVG-Symbole zu verwenden, ohne das Paket zu überladen. Wir werden über SVG-Sprites sprechen, was sie sind, wie man sie verwendet und welche Tools für die Arbeit mit ihnen verfügbar sind. Beginnend mit der Theorie werden wir ein Skript schreiben, das Schritt für Schritt ein SVG-Sprite generiert, und abschließend die Plugins für und besprechen. Vite Webpack Was ist SVG-Sprite? Ein Bild-Sprite ist eine Sammlung von Bildern, die in einem einzigen Bild zusammengefasst sind. SVG Sprite wiederum ist eine Sammlung von SVG-Inhalten, verpackt in , die in platziert werden. <symbol /> <svg /> Wir haben zum Beispiel ein einfaches SVG-Stiftsymbol: Um ein SVG-Sprite zu erhalten, ersetzen wir das Tag durch und umschließen es extern mit : <svg /> <symbol /> <svg /> Jetzt ist es ein SVG-Sprite und wir haben darin ein Symbol mit . id="icon-pen" Ok, aber wir sollten herausfinden, wie wir dieses Symbol auf unserer HTML-Seite platzieren. Wir verwenden das Tag mit dem Attribut , geben die ID des Symbols an und duplizieren dieses Element innerhalb von SVG. <use /> href Schauen wir uns ein Beispiel an, wie funktioniert: <use /> In diesem Beispiel gibt es zwei Kreise. Das erste hat einen blauen Umriss und das zweite ist ein Duplikat des ersten, jedoch mit einer roten Füllung. Kommen wir zurück zu unserem SVG-Sprite. Zusammen mit der Verwendung von erhalten wir Folgendes: <use /> Hier haben wir eine Schaltfläche mit unserem Stiftsymbol. Bisher haben wir in ein Symbol ohne Code verwendet. Wenn wir mehr als eine Schaltfläche auf der Seite haben, wirkt sich dies nicht mehr als einmal auf die Größe unseres HTML-Layouts aus, da alle Symbole aus unserem SVG-Sprite stammen und wiederverwendbar sind. <button /> Erstellen einer SVG-Sprite-Datei Verschieben wir unser SVG-Sprite in eine separate Datei, damit wir die Datei nicht überladen müssen. Erstellen Sie zunächst eine Datei und fügen Sie darin ein SVG-Sprite ein. Der nächste Schritt besteht darin, mithilfe des Attributs in Zugriff auf das Symbol bereitzustellen: index.html sprite.svg href <use/> Automatisierung der SVG-Sprite-Erstellung Um bei der Verwendung von Symbolen viel Zeit zu sparen, richten wir eine Automatisierung für diesen Prozess ein. Um einen einfachen Zugriff auf die Symbole zu erhalten und sie nach unseren Wünschen verwalten zu können, müssen sie getrennt werden, jedes in einer eigenen Datei. Zuerst sollten wir alle Symbole im selben Ordner ablegen, zum Beispiel: Schreiben wir nun ein Skript, das diese Dateien erfasst und zu einem einzigen SVG-Sprite zusammenfügt. Erstellen Sie die Datei im Stammverzeichnis Ihres Projekts. generateSvgSprite.ts Bibliothek installieren: Glob- npm i -D glob Rufen Sie mit ein Array vollständiger Pfade für jedes Symbol ab: globSync Jetzt werden wir jeden Dateipfad iterieren und den Dateiinhalt mithilfe der integrierten Bibliothek von Node abrufen: fs Großartig, wir haben den SVG-Code jedes Symbols und können sie jetzt kombinieren, aber wir sollten das Tag in jedem Symbol durch das Tag ersetzen und nutzlose SVG-Attribute entfernen. svg symbol Wir sollten unseren SVG-Code mit einer HTML-Parser-Bibliothek analysieren, um seine DOM-Darstellung zu erhalten. Ich werde verwenden: node-html-parser Wir haben den SVG-Code analysiert und das SVG-Element erhalten, als wäre es ein echtes HTML-Element. Erstellen Sie mit demselben Parser ein leeres , um untergeordnete Elemente von in das zu verschieben: symbol svgElement symbol Nachdem wir untergeordnete Elemente aus extrahiert haben, sollten wir auch die Attribute und daraus erhalten. Als legen wir den Namen der Symboldatei fest. svgElement id viewBox id Jetzt haben wir ein , das in einem SVG-Sprite platziert werden kann. Definieren Sie also einfach die Variable , bevor Sie die Dateien iterieren, wandeln Sie das in einen String um und schieben Sie es in : symbol symbols symbolElement symbols Der letzte Schritt besteht darin, das SVG-Sprite selbst zu erstellen. Es stellt eine Zeichenfolge mit in „root“ und Symbolen als untergeordneten Elementen dar: svg const svgSprite = `<svg>${symbols.join('')}</svg>`; Und wenn Sie nicht erwägen, Plugins zu verwenden, auf die ich weiter unten eingehen werde, müssen Sie die Datei mit dem erstellten Sprite in einem statischen Ordner ablegen. Die meisten Bundler verwenden einen Ordner: public fs.writeFileSync('public/sprite.svg', svgSprite); Und das ist es; Das Skript ist einsatzbereit: // generateSvgSprite.ts import { globSync } from 'glob'; import fs from 'fs'; import { HTMLElement, parse } from 'node-html-parser'; import path from 'path'; const svgFiles = globSync('src/icons/*.svg'); const symbols: string[] = []; svgFiles.forEach(file => { const code = fs.readFileSync(file, 'utf-8'); const svgElement = parse(code).querySelector('svg') as HTMLElement; const symbolElement = parse('<symbol/>').querySelector('symbol') as HTMLElement; const fileName = path.basename(file, '.svg'); svgElement.childNodes.forEach(child => symbolElement.appendChild(child)); symbolElement.setAttribute('id', fileName); if (svgElement.attributes.viewBox) { symbolElement.setAttribute('viewBox', svgElement.attributes.viewBox); } symbols.push(symbolElement.toString()); }); const svgSprite = `<svg>${symbols.join('')}</svg>`; fs.writeFileSync('public/sprite.svg', svgSprite); Sie können dieses Skript im Stammverzeichnis Ihres Projekts ablegen und es mit ausführen: tsx npx tsx generateSvgSprite.ts Eigentlich verwende ich hier , weil ich früher überall Code in TypeScript geschrieben habe und diese Bibliothek es Ihnen ermöglicht, in TypeScript geschriebene Knotenskripte auszuführen. Wenn Sie reines JavaScript verwenden möchten, können Sie es ausführen mit: tsx node generateSvgSprite.js Fassen wir also zusammen, was das Skript tut: Es durchsucht den Ordner nach Dateien. src/icons .svg Es extrahiert den Inhalt jedes Symbols und erstellt daraus ein Symbolelement. Es fasst alle Symbole in einem einzigen <svg />. Es erstellt die Datei im Ordner. sprite.svg public So ändern Sie die Symbolfarben Lassen Sie uns einen häufigen und wichtigen Fall behandeln: Farben! Wir haben ein Skript erstellt, in dem das Symbol in ein Sprite eingefügt wird. Dieses Symbol kann jedoch im gesamten Projekt unterschiedliche Farben haben. Wir sollten bedenken, dass nicht nur Elemente Füll- oder Strichattribute haben können, sondern auch , , und andere. Es gibt eine sehr nützliche CSS-Funktion, die uns helfen wird – . <svg/> path circle line currentcolor Dieses Schlüsselwort stellt den Wert der Farbeigenschaft eines Elements dar. Wenn wir beispielsweise die für ein Element verwenden, das den hat, hat dieses Element einen roten Hintergrund. color: red background: currentcolor Grundsätzlich müssen wir jeden Strich- oder Füllattributwert in die ändern. Ich hoffe, Sie sehen nicht, dass es manuell erledigt wird, heh. Und selbst das Schreiben von Code, der SVG-Strings ersetzt oder analysiert, ist im Vergleich zu einem sehr nützlichen Tool, nicht sehr effizient. currentcolor SVGO, Dabei handelt es sich um einen SVG-Optimierer, der nicht nur bei den Farben, sondern auch beim Entfernen redundanter Informationen aus SVG helfen kann. Lassen Sie uns installieren: SVGo npm i -D svgo verfügt über integrierte Plugins, und eines davon ist mit der Eigenschaft . Wenn wir diese SVG-Ausgabe verwenden, werden die Farben durch ersetzt. Hier ist die Verwendung von zusammen mit : svgo convertColors currentColor: true currentcolor svgo convertColors import { optimize } from 'svgo'; const output = optimize( '<svg viewBox="0 0 24 24"><path fill="#000" d="m15 5 4 4" /></svg>', { plugins: [ { name: 'convertColors', params: { currentColor: true, }, } ], } ) console.log(output); Und die Ausgabe wird sein: <svg viewBox="0 0 24 24"><path fill="currentColor" d="m15 5 4 4"/></svg> Fügen wir zu unserem magischen Skript hinzu, das wir im vorherigen Teil geschrieben haben: svgo // generateSvgSprite.ts import { globSync } from 'glob'; import fs from 'fs'; import { HTMLElement, parse } from 'node-html-parser'; import path from 'path'; import { Config as SVGOConfig, optimize } from 'svgo'; // import `optimize` function const svgoConfig: SVGOConfig = { plugins: [ { name: 'convertColors', params: { currentColor: true, }, } ], }; const svgFiles = globSync('src/icons/*.svg'); const symbols: string[] = []; svgFiles.forEach(file => { const code = fs.readFileSync(file, 'utf-8'); const result = optimize(code, svgoConfig).data; // here goes `svgo` magic with optimization const svgElement = parse(result).querySelector('svg') as HTMLElement; const symbolElement = parse('<symbol/>').querySelector('symbol') as HTMLElement; const fileName = path.basename(file, '.svg'); svgElement.childNodes.forEach(child => symbolElement.appendChild(child)); symbolElement.setAttribute('id', fileName); if (svgElement.attributes.viewBox) { symbolElement.setAttribute('viewBox', svgElement.attributes.viewBox); } symbols.push(symbolElement.toString()); }); const svgSprite = `<svg xmlns="http://www.w3.org/2000/svg">${symbols.join('')}</svg>`; fs.writeFileSync('public/sprite.svg', svgSprite); Und führen Sie das Skript aus: npx tsx generateSvgSprite.ts Infolgedessen enthält das SVG-Sprite Symbole mit . Und diese Symbole können überall im Projekt in jeder gewünschten Farbe verwendet werden. currentColor Plugins Wir haben ein Skript und können es jederzeit ausführen, aber es ist etwas unpraktisch, es manuell zu verwenden. Daher empfehle ich ein paar Plugins, die unsere Dateien ansehen und unterwegs SVG-Sprites generieren können: .svg (für Benutzer) vite-plugin-svg-spritemap Vite- Dies ist mein Plugin, das im Wesentlichen dieses Skript enthält, das wir gerade in diesem Artikel erstellt haben. Für das Plugin ist die Ersetzung standardmäßig aktiviert, sodass Sie das Plugin ganz einfach einrichten können. currentColor // vite.config.ts import svgSpritemap from 'vite-plugin-svg-spritemap'; export default defineConfig({ plugins: [ svgSpritemap({ pattern: 'src/icons/*.svg', filename: 'sprite.svg', }), ], }); (für Benutzer) svg-spritemap-webpack-plugin Webpack- Ich habe dieses Webpack-Plugin verwendet, bis ich zu Vite gewechselt bin. Aber dieses Plugin ist immer noch eine gute Lösung, wenn Sie Webpack verwenden. Sie sollten die Farbkonvertierung manuell aktivieren, dann sieht es so aus: // webpack.config.js const SVGSpritemapPlugin = require('svg-spritemap-webpack-plugin'); module.exports = { plugins: [ new SVGSpritemapPlugin('src/icons/*.svg', { output: { svgo: { plugins: [ { name: 'convertColors', params: { currentColor: true, }, }, ], }, filename: 'sprite.svg', }, }), ], } Verwendung im Layout Ich werde ein Beispiel in bereitstellen, aber Sie können es implementieren, wo Sie möchten, da es hauptsächlich um HTML geht. Da wir also in unserem Build-Ordner haben, können wir auf die Sprite-Datei zugreifen und die grundlegende Komponente erstellen: React sprite.svg Icon const Icon: FC<{ name: string }> = ({ name }) => ( <svg> <use href={`/sprite.svg#${name}`} /> </svg> ); const App = () => { return <Icon name="pen" />; }; Das Endergebnis Um also viel manuelle Arbeit mit Symbolen zu vermeiden, fassen wir Folgendes zusammen: Sie können Symbole ganz einfach mit gewünschten Namen im Projekt speichern und organisiert aufbewahren Wir verfügen über ein Skript, das alle Symbole in einem einzigen Sprite in einer separaten Datei zusammenfasst, wodurch die Bundle-Größe reduziert wird und wir diese Symbole überall im Projekt verwenden können Wir verfügen über ein nützliches Tool, das uns hilft, Symbole von unnötigen Attributen zu befreien und die Farben am Verwendungsort zu ändern Wir verfügen über ein Plugin, das unsere Symboldateien ansehen und im Rahmen des Build-Prozesses unterwegs Sprites generieren kann haben eine Icon-Komponente, die das Sahnehäubchen darstellt Abschluss Bei der Effizienz in der Entwicklung geht es nicht nur um Zeitersparnis; Es geht darum, unser kreatives Potenzial freizusetzen. Die Automatisierung wichtiger Aufgaben wie der Verwaltung von Symbolen ist nicht nur eine Abkürzung; Es ist ein Tor zu einem reibungsloseren und wirkungsvolleren Codierungserlebnis. Und Sie sparen Zeit für solche Routineaufgaben, können sich auf komplexere Aufgaben konzentrieren und sich als Entwickler schneller weiterentwickeln.