ডেভেলপাররা প্রায়ই সরাসরি JSX-এ SVG ঢোকান। এটি ব্যবহার করা সুবিধাজনক, তবে এটি JS বান্ডিলের আকার বাড়ায়। অপ্টিমাইজেশানের সাধনায়, আমি বান্ডিলটি বিশৃঙ্খল না করে SVG আইকনগুলি ব্যবহার করার অন্য উপায় খুঁজে বের করার সিদ্ধান্ত নিয়েছি। আমরা SVG sprites সম্পর্কে কথা বলব, সেগুলি কী, কীভাবে সেগুলি ব্যবহার করতে হয় এবং তাদের সাথে কাজ করার জন্য কী সরঞ্জাম উপলব্ধ।
তত্ত্ব দিয়ে শুরু করে, আমরা একটি স্ক্রিপ্ট লিখব যা ধাপে ধাপে একটি SVG স্প্রাইট তৈরি করে এবং vite এবং ওয়েবপ্যাকের জন্য প্লাগইন নিয়ে আলোচনা করে শেষ করব।
একটি ইমেজ স্প্রাইট হল একটি একক চিত্রের মধ্যে স্থাপন করা চিত্রগুলির একটি সংগ্রহ। এর পরিবর্তে, SVG Sprite হল SVG বিষয়বস্তুর একটি সংগ্রহ, যা <symbol />
এ মোড়ানো হয়, যা <svg />
এ রাখা হয়।
উদাহরণস্বরূপ, আমাদের কাছে একটি সাধারণ SVG পেন আইকন রয়েছে:
একটি SVG স্প্রাইট পেতে, আমরা <svg />
ট্যাগটিকে <symbol />
দিয়ে প্রতিস্থাপন করব, এবং এটিকে বাহ্যিকভাবে <svg />
দিয়ে মোড়ানো হবে:
এখন এটি একটি SVG স্প্রাইট, এবং আমাদের ভিতরে id="icon-pen"
সহ একটি আইকন রয়েছে।
ঠিক আছে, কিন্তু আমাদের এইচটিএমএল পৃষ্ঠায় এই আইকনটি কীভাবে স্থাপন করা যায় তা খুঁজে বের করা উচিত। আমরা href
অ্যাট্রিবিউটের সাথে <use />
ট্যাগটি ব্যবহার করব, আইকনের আইডি নির্দিষ্ট করে, এবং এটি SVG-এর ভিতরে এই উপাদানটিকে নকল করবে।
আসুন কিভাবে <use />
কাজ করে তার একটি উদাহরণ দেখি:
এই উদাহরণে, দুটি বৃত্ত আছে। প্রথমটির একটি নীল আউটলাইন রয়েছে এবং দ্বিতীয়টি প্রথমটির একটি ডুপ্লিকেট কিন্তু একটি লাল ফিল সহ৷
আসুন আমাদের SVG স্প্রাইট-এ ফিরে যাই। <use />
ব্যবহারের পাশাপাশি, আমরা এটি পাব:
এখানে, আমাদের পেন আইকন সহ একটি বোতাম রয়েছে।
এখন পর্যন্ত, আমরা <button />
এ তার কোড ছাড়া একটি আইকন ব্যবহার করেছি। আমাদের পৃষ্ঠায় একাধিক বোতাম থাকলে, এটি আমাদের HTML লেআউটের আকারকে একবারের বেশি প্রভাবিত করবে না কারণ সমস্ত আইকন আমাদের SVG স্প্রাইট থেকে আসবে এবং পুনরায় ব্যবহারযোগ্য হবে।
আসুন আমাদের SVG স্প্রাইটকে একটি আলাদা ফাইলে নিয়ে আসি যাতে আমাদের index.html
ফাইলটি বিশৃঙ্খল করতে না হয়। প্রথমে একটি sprite.svg
ফাইল তৈরি করুন এবং এতে একটি SVG স্প্রাইট রাখুন। পরবর্তী ধাপ হল <use/>
এ href
এট্রিবিউট ব্যবহার করে আইকনে অ্যাক্সেস প্রদান করা:
আইকন ব্যবহারে অনেক সময় বাঁচাতে, আসুন এই প্রক্রিয়াটির জন্য একটি অটোমেশন সেট আপ করি৷ আইকনগুলিতে সহজ অ্যাক্সেস পেতে এবং সেগুলিকে আমরা যেমন চাই তেমন পরিচালনা করতে, সেগুলিকে আলাদা করতে হবে, প্রতিটি তার নিজস্ব ফাইলে।
প্রথমত, আমাদের একই ফোল্ডারে সমস্ত আইকন রাখা উচিত, উদাহরণস্বরূপ:
এখন, আসুন একটি স্ক্রিপ্ট লিখি যা এই ফাইলগুলিকে ধরে এবং একটি একক SVG স্প্রাইটের মধ্যে একত্রিত করে।
আপনার প্রকল্পের রুট ডিরেক্টরিতে generateSvgSprite.ts
ফাইল তৈরি করুন।
গ্লোব লাইব্রেরি ইনস্টল করুন:
npm i -D glob
globSync
ব্যবহার করে প্রতিটি আইকনের জন্য সম্পূর্ণ পাথের একটি অ্যারে পান:
এখন, আমরা প্রতিটি ফাইল পাথ পুনরাবৃত্তি করব এবং নোডের অন্তর্নির্মিত লাইব্রেরি fs ব্যবহার করে ফাইল সামগ্রী পাব:
দুর্দান্ত, আমাদের কাছে প্রতিটি আইকনের SVG কোড আছে, এবং এখন আমরা সেগুলিকে একত্রিত করতে পারি, কিন্তু আমাদের উচিত প্রতিটি আইকনের ভিতরে svg
ট্যাগটিকে symbol
ট্যাগ দিয়ে প্রতিস্থাপন করা এবং অকেজো SVG বৈশিষ্ট্যগুলি সরিয়ে ফেলা উচিত৷
আমাদের SVG কোডকে কিছু HTML পার্সার লাইব্রেরির সাথে পার্স করা উচিত যাতে এর DOM প্রতিনিধিত্ব পাওয়া যায়। আমি node-html-parser ব্যবহার করব:
আমরা SVG কোড পার্স করেছি এবং SVG উপাদানটি পেয়েছি যেন এটি একটি বাস্তব HTML উপাদান।
একই পার্সার ব্যবহার করে, svgElement
এর বাচ্চাদের symbol
সরানোর জন্য একটি খালি symbol
উপাদান তৈরি করুন:
svgElement
থেকে বাচ্চাদের বের করার পরে, আমাদের এটি থেকে id
এবং viewBox
বৈশিষ্ট্যগুলিও পাওয়া উচিত। id
হিসাবে, আইকন ফাইলের নাম সেট করা যাক।
এখন, আমাদের কাছে একটি symbol
উপাদান রয়েছে যা একটি SVG স্প্রাইটে স্থাপন করা যেতে পারে। সুতরাং, ফাইলগুলি পুনরাবৃত্তি করার আগে symbols
পরিবর্তনশীলকে সংজ্ঞায়িত করুন, symbolElement
একটি স্ট্রিংয়ে রূপান্তর করুন এবং এটিকে symbols
পুশ করুন:
চূড়ান্ত ধাপ হল SVG স্প্রাইট নিজেই তৈরি করা। এটি "রুট" এ 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
এবং অন্যান্যও থাকতে পারে। একটি খুব দরকারী CSS বৈশিষ্ট্য আছে যা আমাদের সাহায্য করবে - currentcolor ।
এই কীওয়ার্ডটি একটি উপাদানের রঙ বৈশিষ্ট্যের মান উপস্থাপন করে। উদাহরণস্বরূপ, যদি আমরা color: red
ব্যবহার করি এমন একটি উপাদানে যার একটি background: currentcolor
, তাহলে এই উপাদানটির একটি লাল পটভূমি থাকবে।
মূলত, আমাদের প্রতিটি স্ট্রোক পরিবর্তন করতে হবে বা currentcolor
বৈশিষ্ট্যের মান পূরণ করতে হবে। আমি আশা করি আপনি এটি ম্যানুয়ালি করা দেখছেন না, হেহ। এমনকি কিছু কোড লেখা যা SVG স্ট্রিংগুলিকে প্রতিস্থাপন বা পার্স করবে একটি খুব দরকারী টুল svgo এর তুলনায় খুব দক্ষ নয়।
এটি একটি SVG অপ্টিমাইজার যা শুধুমাত্র রং দিয়েই নয় SVG থেকে অপ্রয়োজনীয় তথ্য মুছে ফেলার ক্ষেত্রেও সাহায্য করতে পারে।
আসুন svgo ইনস্টল করি:
npm i -D svgo
svgo
এর অন্তর্নির্মিত প্লাগইন রয়েছে এবং তাদের মধ্যে একটি হল convertColors
, যার প্রপার্টি আছে currentColor: true
। আমরা এই SVG আউটপুট ব্যবহার করলে, এটি 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
ফলস্বরূপ, SVG sprite-এ currentColor
সহ আইকন থাকবে। এবং এই আইকনগুলি আপনি চান যে কোনও রঙ দিয়ে প্রকল্পের সর্বত্র ব্যবহার করা যেতে পারে।
আমাদের একটি স্ক্রিপ্ট আছে, এবং আমরা যখনই চাই তখন এটি চালাতে পারি, তবে এটি আমাদের ম্যানুয়ালি ব্যবহার করা কিছুটা অসুবিধাজনক। তাই, আমি কয়েকটি প্লাগইন সুপারিশ করছি যেগুলি আমাদের .svg
ফাইলগুলি দেখতে পারে এবং যেতে যেতে SVG স্প্রাইট তৈরি করতে পারে:
vite-plugin-svg-spritemap ( vite ব্যবহারকারীদের জন্য)
এটি আমার প্লাগইন যা মূলত এই স্ক্রিপ্টটি রয়েছে যা আমরা এই নিবন্ধে তৈরি করেছি। প্লাগইনটিতে 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-webpack-plugin ( ওয়েবপ্যাক ব্যবহারকারীদের জন্য)
আমি Vite এ স্যুইচ না করা পর্যন্ত এই ওয়েবপ্যাক প্লাগইনটি ব্যবহার করেছি। কিন্তু আপনি যদি Webpack ব্যবহার করেন তবে এই প্লাগইনটি এখনও একটি ভাল সমাধান। আপনি ম্যানুয়ালি রঙ রূপান্তর সক্ষম করা উচিত, এবং এটি এই মত দেখাবে:
// 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" />; };
সুতরাং, আইকনগুলির সাথে প্রচুর ম্যানুয়াল কাজ রোধ করতে সবকিছুর সংক্ষিপ্তসার, আমরা:
উন্নয়নে দক্ষতা শুধু সময় বাঁচানোর জন্য নয়; এটা আমাদের সৃজনশীল সম্ভাবনা আনলক সম্পর্কে. আইকন ম্যানেজ করার মতো নিটি-কঠিন কাজগুলিকে স্বয়ংক্রিয় করা কেবল একটি শর্টকাট নয়; এটি একটি মসৃণ, আরও প্রভাবশালী কোডিং অভিজ্ঞতার একটি গেটওয়ে। এবং এই জাতীয় রুটিন জিনিসগুলিতে সময় বাঁচানোর ফলে আপনি আরও জটিল কাজগুলিতে ফোকাস করতে পারেন এবং একজন বিকাশকারী হিসাবে দ্রুত বিকাশ করতে পারেন।