Vite ডেভেলপারদের মধ্যে আরও বেশি জনপ্রিয় হয়ে উঠছে, কিন্তু যেহেতু সম্প্রদায়টি ততটা বড় নয় ( ওয়েবপ্যাকের মতো), আপনার সমস্যা সমাধানের জন্য আপনাকে আপনার নিজস্ব কাস্টম প্লাগইন তৈরি করতে হতে পারে৷ এই নিবন্ধে, আমরা কীভাবে Vite- এর জন্য একটি প্লাগইন তৈরি করব তা নিয়ে আলোচনা করব এবং আমি আমার নিজের প্লাগইনটি ভেঙে দেব।
একটি প্লাগইন তৈরি করতে, এটা জানা গুরুত্বপূর্ণ যে Vite ডেভেলপমেন্ট সার্ভার (command vite
) এবং বান্ডেল (command vite build
) এর জন্য বিভিন্ন বিল্ড সিস্টেম ব্যবহার করে।
ডেভেলপমেন্ট সার্ভারের জন্য, এটি নেটিভ ES মডিউলগুলির সাথে esbuild ব্যবহার করে, যা আধুনিক ব্রাউজার দ্বারা সমর্থিত, এবং আমাদের একটি একক ফাইলে কোড বান্ডিল করার দরকার নেই, এবং এটি আমাদের দ্রুত HRM (হট মডিউল প্রতিস্থাপন) দেয়।
বান্ডেলের জন্য, এটি একটি rollup.js ব্যবহার করে কারণ এটি নমনীয় এবং একটি বড় ইকোসিস্টেম রয়েছে; এটি বিভিন্ন আউটপুট ফরম্যাটের সাথে উচ্চ অপ্টিমাইজড প্রোডাকশন বান্ডেল তৈরি করতে দেয়।
Vite এর প্লাগইন ইন্টারফেস রোলআপের উপর ভিত্তি করে কিন্তু ডেভ সার্ভারের সাথে কাজ করার জন্য অতিরিক্ত বিকল্প এবং হুক সহ।
আপনি যখন একটি প্লাগইন তৈরি করেন, আপনি এটি আপনার vite.config.js
এ ইনলাইন করতে পারেন। এর জন্য নতুন কোনো প্যাকেজ তৈরি করতে হবে না। একবার আপনি দেখতে পান যে একটি প্লাগইন আপনার প্রকল্পগুলিতে কার্যকর হয়েছে, এটি সম্প্রদায়ের সাথে ভাগ করে নেওয়ার এবং Vite ইকোসিস্টেমে অবদান রাখার কথা বিবেচনা করুন৷
এছাড়াও, যেহেতু rollup.js-এর একটি বৃহত্তর সম্প্রদায় এবং ইকোসিস্টেম রয়েছে, আপনি rollup.js-এর জন্য একটি প্লাগইন তৈরি করার কথা বিবেচনা করতে পারেন এবং এটি Vite-এ ঠিক তেমনই কাজ করবে। সুতরাং, যদি আপনার প্লাগইন কার্যকারিতা শুধুমাত্র বান্ডেলের জন্য কাজ করে, আপনি Vite এর পরিবর্তে rollup.js প্লাগইন দিয়ে যেতে পারেন এবং ব্যবহারকারীরা তাদের Vite প্রকল্পে আপনার রোলআপ প্লাগইনটি কোনো সমস্যা ছাড়াই ব্যবহার করতে পারেন।
আপনি যদি রোলআপের জন্য একটি প্লাগইন তৈরি করেন, তাহলে আপনি আরও বেশি ব্যবহারকারীকে কভার করবেন যারা শুধুমাত্র rollup.js ব্যবহার করেন। যদি আপনার প্লাগইন ডেভেলপমেন্ট সার্ভারকে প্রভাবিত করে, তাহলে আপনি Vite প্লাগইন দিয়ে যান।
আসুন সরাসরি vite.config.ts
এ প্লাগইন তৈরি করা শুরু করি:
// vite.config.ts import { defineConfig, Plugin } from 'vite'; function myPlugin(): Plugin { return { name: 'my-plugin', configResolved(config) { console.log(config); }, }; } export default defineConfig({ plugins: [ myPlugin(), ], });
এই উদাহরণে, আমি myPlugin
নামে একটি প্লাগইন তৈরি করেছি যা Vite কনফিগারেশনটি প্রিন্ট করে যত তাড়াতাড়ি এটি কনসোলে উভয় পর্যায়ে সমাধান করা হয়: dev সার্ভার এবং বান্ডেল। আমি যদি শুধুমাত্র dev সার্ভার মোডে কনফিগারেশন প্রিন্ট করতে চাই, তাহলে আমার যোগ করা উচিত apply: 'serve'
, এবং apply: 'build'
বান্ডেলের জন্য।
// vite.config.ts import { defineConfig, Plugin } from 'vite'; function myPlugin(): Plugin { return { name: 'my-plugin', apply: 'serve', configResolved(config) { console.log(config); }, }; } export default defineConfig({ plugins: [ myPlugin(), ], });
এছাড়াও, আমি প্লাগইনগুলির একটি অ্যারে ফেরত দিতে পারি; এটি dev সার্ভার এবং বান্ডেলের জন্য কার্যকারিতা পৃথক করার জন্য দরকারী:
// vite.config.ts import { defineConfig, Plugin } from 'vite'; function myPlugin(): Plugin[] { return [ { name: 'my-plugin:serve', apply: 'serve', configResolved(config) { console.log('dev server:', config); }, }, { name: 'my-plugin:build', apply: 'build', configResolved(config) { console.log('bundle:', config); }, }, ]; } export default defineConfig({ plugins: [ myPlugin(), ], });
এবং যে বেশ এটা; আপনি সহজেই Vite কনফিগারেশনে ছোট প্লাগইন যোগ করতে পারেন। এবং যদি একটি প্লাগইন খুব বড় হয়ে যায়, আমি এটিকে অন্য ফাইলে সরাতে বা এমনকি একটি প্যাকেজ তৈরি করতে পছন্দ করি।
আপনার যদি আরও জটিল কিছুর প্রয়োজন হয় তবে ভিটের ডকুমেন্টেশনে আপনি অন্বেষণ করতে পারেন এমন অনেকগুলি দরকারী হুক রয়েছে। কিন্তু একটি উদাহরণ হিসাবে, আসুন নীচে আমার নিজের প্লাগইন ভাঙ্গা যাক।
সুতরাং, আইকন ফাইলগুলির উপর ভিত্তি করে এসভিজি স্প্রিট তৈরি করার জন্য আমার কাছে একটি প্লাগইন রয়েছে - vite-plugin-svg-spritemap ।
লক্ষ্য হল src/icons
ফোল্ডারের সমস্ত আইকন .svg
দখল করা এবং একটি একক .svg
ফাইলে তাদের বিষয়বস্তু সংগ্রহ করা যাকে SVG স্প্রাইট বলা হয়। চলুন বান্ডিল পর্যায় থেকে শুরু করা যাক:
import { Plugin, ResolvedConfig } from 'vite'; import path from 'path'; import fs from 'fs-extra'; function myPlugin(): Plugin { let config: ResolvedConfig; return { name: 'my-plugin:build', apply: 'build', async configResolved(_config) { config = _config; }, writeBundle() { const sprite = getSpriteContent({ pattern: 'src/icons/*.svg' }); const filePath = path.resolve(config.root, config.build.outDir, 'sprite.svg'); fs.ensureFileSync(filePath); fs.writeFileSync(filePath, sprite); }, }; }
Hook configResolved
আমাদেরকে কনফিগার করার অনুমতি দেয় যখন এটি পরবর্তী হুকগুলিতে ব্যবহার করার জন্য সমাধান করা হয়;
বান্ডলিং প্রক্রিয়া শেষ হওয়ার পরে writeBundle
হুক বলা হয়, এবং এখানে, আমি sprite.svg
ফাইলটি তৈরি করব;
getSpriteContent
ফাংশন src/icons/*.svg
প্যাটার্নের উপর ভিত্তি করে প্রস্তুত SVG স্প্রাইটের একটি স্ট্রিং প্রদান করে। আমি এই এক সঙ্গে গভীর যেতে হবে না; আপনি SVG স্প্রাইট প্রজন্মের পুরো প্রক্রিয়া ব্যাখ্যা করে আমার অন্য নিবন্ধটি দেখতে পারেন;
তারপর, আমি path.resolve()
এর সাথে SVG স্প্রাইট কন্টেন্ট রাখার জন্য sprite.svg
এর পরম পথ তৈরি করি, fs.ensureFileSync
এর সাথে ফাইলটি বিদ্যমান (বা একটি তৈরি করুন) আছে কিনা নিশ্চিত করুন এবং এতে SVG স্প্রাইট সামগ্রী লিখুন। .
এখন, সবচেয়ে আকর্ষণীয় অংশের জন্য - দেব সার্ভার পর্যায়। আমি এখানে writeBundle
ব্যবহার করতে পারি না, এবং dev সার্ভার চলমান থাকলে আমি ফাইলগুলি হোস্ট করতে পারি না, তাই sprite.svg
এ অনুরোধটি ধরতে আমাদের সার্ভার মিডলওয়্যার ব্যবহার করতে হবে।
import { Plugin, ResolvedConfig } from 'vite'; function myPlugin(): Plugin { let config: ResolvedConfig; return { name: `my-plugin:serve`, apply: 'serve', async configResolved(_config) { config = _config; }, configureServer(server) { // (1) return () => { server.middlewares.use(async (req, res, next) => { // (2) if (req.url !== '/sprite.svg') { return next(); // (3) } const sprite = getSpriteContent({ pattern, prefix, svgo, currentColor }); res.writeHead(200, { // (4) 'Content-Type': 'image/svg+xml, charset=utf-8', 'Cache-Control': 'no-cache', }); res.end(sprite); }); }; }, }; }
configureServer
হল ডেভ সার্ভার কনফিগার করার জন্য একটি হুক। Vite এর অভ্যন্তরীণ মিডলওয়্যার ইনস্টল হওয়ার আগে এটি ট্রিগার করে; আমার ক্ষেত্রে, আমাকে অভ্যন্তরীণ মিডলওয়্যারের পরে কাস্টম মিডলওয়্যার যোগ করতে হবে, তাই আমি একটি ফাংশন ফেরত দিই;
ডেভ সার্ভারে প্রতিটি অনুরোধ ধরতে কাস্টম মিডলওয়্যার যোগ করতে, আমি server.middlewares.use()
ব্যবহার করি। URL [localhost:3000/sprite.svg](http://localhost:3000/sprite.svg)
সহ অনুরোধগুলি সনাক্ত করার জন্য আমার এটি প্রয়োজন, তাই আমি ফাইলের আচরণ অনুকরণ করতে পারি;
অনুরোধ URL /sprite.svg
না হলে - পরবর্তী মিডলওয়্যারে এড়িয়ে যান (অর্থাৎ, চেইনের পরবর্তী হ্যান্ডলারের কাছে নিয়ন্ত্রণ পাস করুন);
ফাইলের বিষয়বস্তু প্রস্তুত করার জন্য, আমি getSpriteContent
এর ফলাফল পরিবর্তনশীল sprite
এ রাখি এবং কনফিগার করা শিরোনাম (সামগ্রীর ধরন এবং 200 HTTP স্থিতি) সহ একটি প্রতিক্রিয়া হিসাবে পাঠাই।
ফলস্বরূপ, আমি ফাইল আচরণ অনুকরণ.
কিন্তু যদি src/icons
ফাইলগুলি পরিবর্তন, মুছে ফেলা বা যোগ করা হয়, তাহলে getSpriteContent
এর মাধ্যমে নতুন স্প্রাইট সামগ্রী তৈরি করতে আমাদের সার্ভারটি পুনরায় চালু করা উচিত; এর জন্য আমি ফাইল দেখার লাইব্রেরি- চকিদার ব্যবহার করব। কোডে চোকিদার হ্যান্ডলার যোগ করা যাক:
import { Plugin, ResolvedConfig } from 'vite'; import chokidar from 'chokidar'; function myPlugin(): Plugin { let config: ResolvedConfig; let watcher: chokidar.FSWatcher; // Defined variable for chokidar instance. return { name: `my-plugin:serve`, apply: 'serve', async configResolved(_config) { config = _config; }, configureServer(server) { function reloadPage() { // Function that sends a signal to reload the server. server.ws.send({ type: 'full-reload', path: '*' }); } watcher = chokidar .watch('src/icons/*.svg', { // Watch src/icons/*.svg cwd: config.root, // Define project root path ignoreInitial: true, // Don't trigger chokidar on instantiation. }) .on('add', reloadPage) // Add listeners to add, modify, delete. .on('change', reloadPage) .on('unlink', reloadPage); return () => { server.middlewares.use(async (req, res, next) => { if (req.url !== '/sprite.svg') { return next(); } const sprite = getSpriteContent({ pattern, prefix, svgo, currentColor }); res.writeHead(200, { 'Content-Type': 'image/svg+xml, charset=utf-8', 'Cache-Control': 'no-cache', }); res.end(sprite); }); }; }, }; }
আপনি দেখতে পাচ্ছেন, প্লাগইন তৈরির API সত্যিই জটিল নয়। আপনাকে শুধু Vite বা Rollup থেকে এমন হুক খুঁজে বের করতে হবে যা আপনার কাজের জন্য উপযুক্ত হবে। আমার উদাহরণে, আমি Rollup.js থেকে writeBundle
ব্যবহার করছি (যেমন আমি বলেছি, এটি বান্ডেল তৈরি করতে ব্যবহৃত হয়), এবং Vite থেকে configureServer
কারণ Rollup.js-এর নেটিভ ডেভ সার্ভার সমর্থন নেই।
writeBundle
এর ক্ষেত্রে এটা খুবই সহজ ছিল, আমরা SVG স্প্রাইট কন্টেন্ট নিয়েছিলাম এবং এটি একটি ফাইলে রেখেছিলাম। ডেভ সার্ভারের ক্ষেত্রে, এটি আমাকে বিভ্রান্ত করেছে কেন আমি একই কাজ করতে পারিনি; আমি অন্যান্য লেখকদের প্লাগইন দেখেছি, এবং তারা সবাই একই কাজ করে।
তাই, আমি configureServer
ব্যবহার করি এবং server
আর্গুমেন্টের মাধ্যমে, আমি মিডলওয়্যার যোগ করি যা sprite.svg
রিকোয়েস্টকে বাধা দিয়ে ডেভ সার্ভারে প্রতিটি অনুরোধ ট্রিগার করে।
আমি আগে উল্লেখ করেছি, আরও দরকারী প্লাগইন তৈরি করতে, আপনাকে হুকগুলি অন্বেষণ করতে হবে। এগুলি ডকুমেন্টেশনে বিস্তারিতভাবে ব্যাখ্যা করা হয়েছে:
https://vitejs.dev/guide/api-plugin#universal-hooks
https://vitejs.dev/guide/api-plugin#vite-specific-hooks
নামকরণের ক্ষেত্রে, Vite এর প্লাগইনগুলির জন্য কিছু নিয়ম রয়েছে, তাই আপনি শেষ করার আগে এটি পরীক্ষা করে দেখুন। এখানে কিছু মূল পয়েন্ট আছে:
vite-plugin-
উপসর্গ সহ একটি অনন্য নাম থাকা উচিত;
vite-plugin
কীওয়ার্ড অন্তর্ভুক্ত করুন;
vite-plugin-vue-
, vite-plugin-react-
, vite-plugin-svelte-
)।আপনি যদি NPM-এ আপনার প্লাগইন প্রকাশ করার সিদ্ধান্ত নেন, যা আমি সুপারিশ করছি কারণ জ্ঞান এবং দক্ষতা ভাগ করে নেওয়া আইটি সম্প্রদায়ের একটি মৌলিক নীতি, যৌথ বৃদ্ধিকে উৎসাহিত করে। কিভাবে আপনার প্যাকেজ প্রকাশ এবং বজায় রাখতে হয় তা শিখতে, আমার গাইড দেখুন → একটি NPM প্যাকেজ তৈরি করার সবচেয়ে সহজ উপায় ।
আমি আপনার প্লাগইনটিকে ভাইটের সম্প্রদায়ের তালিকায় জমা দেওয়ার সুপারিশ করছি - awesome-vite । অনেক মানুষ সেখানে সবচেয়ে উপযুক্ত প্লাগইন খুঁজছেন, এবং এটি Vite ইকোসিস্টেমে অবদান রাখার একটি দুর্দান্ত সুযোগ হবে! সেখানে আপনার প্লাগইন জমা দেওয়ার প্রক্রিয়া সহজ - শুধু নিশ্চিত করুন যে আপনি শর্তাবলী পূরণ করেছেন এবং একটি পুল অনুরোধ তৈরি করুন৷ আপনি এখানে শর্তাবলীর তালিকা পেতে পারেন।
সামগ্রিকভাবে, এটি Vite (রোলআপ নয়), ওপেন সোর্স এবং ভাল ডকুমেন্টেশনের জন্য নির্দিষ্ট হওয়া দরকার। আপনার প্লাগইনগুলির সাথে সৌভাগ্য কামনা করছি!