डेवलपर्स अक्सर SVG को सीधे JSX में सम्मिलित करते हैं। इसका उपयोग करना सुविधाजनक है, लेकिन यह JS बंडल आकार को बढ़ाता है। अनुकूलन की खोज में, मैंने बंडल को अव्यवस्थित किए बिना एसवीजी आइकन का उपयोग करने का एक और तरीका खोजने का फैसला किया। हम एसवीजी स्प्राइट्स के बारे में बात करेंगे, वे क्या हैं, उनका उपयोग कैसे करें और उनके साथ काम करने के लिए कौन से उपकरण उपलब्ध हैं।
सिद्धांत से शुरू करके, हम एक स्क्रिप्ट लिखेंगे जो चरण दर चरण एक एसवीजी स्प्राइट उत्पन्न करती है और वाइट और वेबपैक के लिए प्लगइन्स पर चर्चा करके समाप्त होगी।
एक इमेज स्प्राइट एक ही छवि में रखी गई छवियों का एक संग्रह है। बदले में, एसवीजी स्प्राइट एसवीजी सामग्री का एक संग्रह है, जिसे <symbol />
में लपेटा गया है, जिसे <svg />
में रखा गया है।
उदाहरण के लिए, हमारे पास एक सरल एसवीजी पेन आइकन है:
एसवीजी स्प्राइट प्राप्त करने के लिए, हम <svg />
टैग को <symbol />
से बदल देंगे, और इसे बाहरी रूप से <svg />
से लपेट देंगे:
अब यह एक एसवीजी स्प्राइट है, और हमारे अंदर id="icon-pen"
वाला एक आइकन है।
ठीक है, लेकिन हमें यह पता लगाना चाहिए कि इस आइकन को अपने HTML पेज पर कैसे रखा जाए। हम आइकन की आईडी निर्दिष्ट करते हुए href
विशेषता के साथ <use />
टैग का उपयोग करेंगे, और यह SVG के अंदर इस तत्व की नकल करेगा।
आइए एक उदाहरण देखें कि <use />
कैसे काम करता है:
इस उदाहरण में, दो वृत्त हैं। पहले वाले की रूपरेखा नीली है, और दूसरा पहले वाले का डुप्लिकेट है लेकिन लाल रंग से भरा हुआ है।
आइए अपने एसवीजी स्प्राइट पर वापस आएं। <use />
के उपयोग के साथ, हमें यह मिलेगा:
यहां, हमारे पास पेन आइकन वाला एक बटन है।
अब तक, हमने <button />
में बिना कोड वाले आइकन का उपयोग किया है। यदि हमारे पास पृष्ठ पर एक से अधिक बटन हैं, तो यह हमारे HTML लेआउट के आकार को एक से अधिक बार प्रभावित नहीं करेगा क्योंकि सभी आइकन हमारे एसवीजी स्प्राइट से आएंगे और पुन: प्रयोज्य होंगे।
आइए अपने SVG स्प्राइट को एक अलग फ़ाइल में ले जाएँ ताकि हमें index.html
फ़ाइल को अव्यवस्थित न करना पड़े। सबसे पहले, एक sprite.svg
फ़ाइल बनाएं और उसमें एक SVG स्प्राइट डालें। अगला कदम <use/>
में href
विशेषता का उपयोग करके आइकन तक पहुंच प्रदान करना है:
आइकन के उपयोग पर बहुत सारा समय बचाने के लिए, आइए इस प्रक्रिया के लिए एक स्वचालन स्थापित करें। आइकनों तक आसान पहुंच पाने और उन्हें अपनी इच्छानुसार प्रबंधित करने के लिए, उन्हें अलग करना होगा, प्रत्येक को अपनी फ़ाइल में।
सबसे पहले, हमें सभी आइकन को एक ही फ़ोल्डर में रखना चाहिए, उदाहरण के लिए:
अब, चलिए एक स्क्रिप्ट लिखते हैं जो इन फ़ाइलों को पकड़ती है और उन्हें एक एकल एसवीजी स्प्राइट में जोड़ती है।
अपने प्रोजेक्ट की रूट डायरेक्टरी में generateSvgSprite.ts
फ़ाइल बनाएं।
ग्लोब लाइब्रेरी स्थापित करें:
npm i -D glob
globSync
का उपयोग करके प्रत्येक आइकन के लिए पूर्ण पथों की एक सरणी प्राप्त करें:
अब, हम प्रत्येक फ़ाइल पथ को पुनरावृत्त करेंगे और नोड की अंतर्निहित लाइब्रेरी fs का उपयोग करके फ़ाइल सामग्री प्राप्त करेंगे:
बढ़िया, हमारे पास प्रत्येक आइकन का एसवीजी कोड है, और अब हम उन्हें जोड़ सकते हैं, लेकिन हमें प्रत्येक आइकन के अंदर svg
टैग को symbol
टैग से बदलना चाहिए और बेकार एसवीजी विशेषताओं को हटा देना चाहिए।
हमें अपने एसवीजी कोड को उसका DOM प्रतिनिधित्व प्राप्त करने के लिए कुछ HTML पार्सर लाइब्रेरी के साथ पार्स करना चाहिए। मैं नोड-एचटीएमएल-पार्सर का उपयोग करूंगा:
हमने एसवीजी कोड को पार्स किया है और एसवीजी तत्व प्राप्त किया है जैसे कि यह एक वास्तविक HTML तत्व था।
उसी पार्सर का उपयोग करके, svgElement
के बच्चों को symbol
में ले जाने के लिए एक खाली symbol
तत्व बनाएं:
svgElement
से बच्चों को निकालने के बाद, हमें इससे id
और viewBox
विशेषताएँ भी प्राप्त करनी चाहिए। एक id
के रूप में, आइए आइकन फ़ाइल का नाम सेट करें।
अब, हमारे पास एक symbol
तत्व है जिसे एसवीजी स्प्राइट में रखा जा सकता है। तो, फ़ाइलों को पुनरावृत्त करने से पहले बस symbols
वेरिएबल को परिभाषित करें, symbolElement
एक स्ट्रिंग में बदलें, और इसे symbols
में धकेलें:
अंतिम चरण स्वयं एसवीजी स्प्राइट बनाना है। यह "रूट" में svg
और बच्चों के रूप में प्रतीकों के साथ एक स्ट्रिंग का प्रतिनिधित्व करता है:
const svgSprite = `<svg>${symbols.join('')}</svg>`;
और यदि आप प्लगइन्स का उपयोग करने पर विचार नहीं कर रहे हैं, जिसके बारे में मैं नीचे बात करूंगा, तो आपको फ़ाइल को बनाए गए स्प्राइट के साथ कुछ स्थिर फ़ोल्डर में रखना होगा। अधिकांश बंडलर public
फ़ोल्डर का उपयोग करते हैं:
fs.writeFileSync('public/sprite.svg', svgSprite);
और यही है; स्क्रिप्ट उपयोग के लिए तैयार है:
// 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);
आप इस स्क्रिप्ट को अपने प्रोजेक्ट के रूट में डाल सकते हैं और इसे tsx के साथ चला सकते हैं:
npx tsx generateSvgSprite.ts
दरअसल, मैं यहां tsx का उपयोग कर रहा हूं क्योंकि मैं हर जगह टाइपस्क्रिप्ट में कोड लिखता था, और यह लाइब्रेरी आपको टाइपस्क्रिप्ट में लिखी गई नोड स्क्रिप्ट को निष्पादित करने की अनुमति देती है। यदि आप शुद्ध जावास्क्रिप्ट का उपयोग करना चाहते हैं, तो आप इसे इसके साथ चला सकते हैं:
node generateSvgSprite.js
तो, आइए सारांशित करें कि स्क्रिप्ट क्या कर रही है:
.svg
फ़ाइल के लिए src/icons
फ़ोल्डर में देखता है।
<svg />.
public
फ़ोल्डर में sprite.svg
फ़ाइल बनाता है।आइए एक बारंबार और महत्वपूर्ण मामले को कवर करें: रंग! हमने एक स्क्रिप्ट बनाई जहां आइकन एक स्प्राइट में चला जाता है, लेकिन इस आइकन के पूरे प्रोजेक्ट में अलग-अलग रंग हो सकते हैं।
हमें यह ध्यान रखना चाहिए कि न केवल <svg/>
तत्वों में भरण या स्ट्रोक विशेषताएँ हो सकती हैं, बल्कि path
, circle
, line
और अन्य भी हो सकते हैं। एक बहुत ही उपयोगी सीएसएस सुविधा है जो हमारी मदद करेगी - currentcolor ।
यह कीवर्ड किसी तत्व के रंग गुण का मान दर्शाता है। उदाहरण के लिए, यदि हम किसी ऐसे तत्व पर color: red
उपयोग करते हैं जिसकी background: currentcolor
है, तो इस तत्व की पृष्ठभूमि लाल होगी।
मूलतः, हमें प्रत्येक स्ट्रोक या भरण विशेषता मान को currentcolor
में बदलने की आवश्यकता है। मुझे आशा है कि आप इसे मैन्युअल रूप से किया हुआ नहीं देख रहे हैं, हेह। और यहां तक कि कुछ कोड लिखना जो एसवीजी स्ट्रिंग्स को प्रतिस्थापित या पार्स करेगा, एक बहुत ही उपयोगी टूल svgo की तुलना में बहुत कुशल नहीं है।
यह एक एसवीजी ऑप्टिमाइज़र है जो न केवल रंगों के साथ बल्कि एसवीजी से अनावश्यक जानकारी को हटाने में भी मदद कर सकता है।
आइए svgo इंस्टॉल करें:
npm i -D svgo
svgo
में अंतर्निहित प्लगइन्स हैं, और उनमें से एक convertColors
है, जिसमें currentColor: true
गुण है। यदि हम इस एसवीजी आउटपुट का उपयोग करते हैं, तो यह रंगों को currentcolor
से बदल देगा। यहां convertColors
के साथ svgo
का उपयोग दिया गया है:
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);
और आउटपुट होगा:
<svg viewBox="0 0 24 24"><path fill="currentColor" d="m15 5 4 4"/></svg>
आइए अपनी जादुई स्क्रिप्ट में 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);
और स्क्रिप्ट चलाएँ:
npx tsx generateSvgSprite.ts
परिणामस्वरूप, एसवीजी स्प्राइट में currentColor
वाले आइकन शामिल होंगे। और इन आइकनों का उपयोग प्रोजेक्ट में हर जगह आपके इच्छित रंग के साथ किया जा सकता है।
हमारे पास एक स्क्रिप्ट है, और हम जब चाहें इसे चला सकते हैं, लेकिन यह थोड़ा असुविधाजनक है कि हमें इसे मैन्युअल रूप से उपयोग करना चाहिए। इसलिए, मैं कुछ प्लगइन्स की अनुशंसा करता हूं जो हमारी .svg
फ़ाइलें देख सकते हैं और चलते-फिरते SVG स्प्राइट उत्पन्न कर सकते हैं:
वाइट-प्लगइन-एसवीजी-स्प्राइटमैप ( वाइट उपयोगकर्ताओं के लिए)
यह मेरा प्लगइन है जिसमें मूल रूप से यह स्क्रिप्ट शामिल है जिसे हमने अभी इस लेख में बनाया है। प्लगइन में डिफ़ॉल्ट रूप से currentColor
रिप्लेसमेंट सक्षम है, जिससे आप प्लगइन को बहुत आसानी से सेट कर सकते हैं।
// vite.config.ts import svgSpritemap from 'vite-plugin-svg-spritemap'; export default defineConfig({ plugins: [ svgSpritemap({ pattern: 'src/icons/*.svg', filename: 'sprite.svg', }), ], });
svg-spritemap-वेबपैक-प्लगइन ( वेबपैक उपयोगकर्ताओं के लिए)
मैंने इस वेबपैक प्लगइन का उपयोग तब तक किया जब तक कि मैंने Vite पर स्विच नहीं किया। लेकिन यदि आप वेबपैक का उपयोग कर रहे हैं तो यह प्लगइन अभी भी एक अच्छा समाधान है। आपको मैन्युअल रूप से रंग रूपांतरण सक्षम करना चाहिए, और यह इस तरह दिखेगा:
// 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', }, }), ], }
मैं रिएक्ट में एक उदाहरण प्रदान करूंगा, लेकिन आप इसे जहां चाहें वहां लागू कर सकते हैं क्योंकि यह ज्यादातर HTML के बारे में है। इसलिए, चूंकि हमारे बिल्ड फ़ोल्डर में sprite.svg
है, हम स्प्राइट फ़ाइल तक पहुंच सकते हैं और मूल Icon
घटक बना सकते हैं:
const Icon: FC<{ name: string }> = ({ name }) => ( <svg> <use href={`/sprite.svg#${name}`} /> </svg> ); const App = () => { return <Icon name="pen" />; };
इसलिए, आइकनों के साथ बहुत सारे मैन्युअल काम को रोकने के लिए, सब कुछ संक्षेप में प्रस्तुत करते हुए, हम:
विकास में दक्षता केवल समय बचाने के बारे में नहीं है; यह हमारी रचनात्मक क्षमता को उजागर करने के बारे में है। आइकनों को प्रबंधित करने जैसे महत्वपूर्ण कार्यों को स्वचालित करना केवल एक शॉर्टकट नहीं है; यह एक सहज, अधिक प्रभावशाली कोडिंग अनुभव का प्रवेश द्वार है। और ऐसी नियमित चीज़ों पर समय बचाकर, आप अधिक जटिल कार्यों पर ध्यान केंद्रित कर सकते हैं और एक डेवलपर के रूप में तेजी से विकसित हो सकते हैं।