Vite-এর প্লাগইন আর্কিটেকচার আবিষ্কার করুন এবং আপনার ডেভেলপমেন্ট কর্মপ্রবাহ উন্নত করতে কাস্টম প্লাগইন তৈরি করতে শিখুন। বিশ্বব্যাপী দর্শকদের জন্য ব্যবহারিক উদাহরণ সহ অপরিহার্য ধারণাগুলি আয়ত্ত করুন।
Vite প্লাগইন আর্কিটেকচারের রহস্য উন্মোচন: কাস্টম প্লাগইন তৈরির একটি বিশ্বব্যাপী নির্দেশিকা
ভিট (Vite), বিদ্যুতের মতো দ্রুতগতির একটি বিল্ড টুল, ফ্রন্টএন্ড ডেভেলপমেন্টে বিপ্লব এনেছে। এর গতি এবং সরলতার মূল কারণ হলো এর শক্তিশালী প্লাগইন আর্কিটেকচার। এই আর্কিটেকচার ডেভেলপারদের Vite-এর কার্যকারিতা বাড়াতে এবং তাদের নির্দিষ্ট প্রকল্পের প্রয়োজন অনুযায়ী এটিকে সাজাতে সাহায্য করে। এই নির্দেশিকাটি Vite-এর প্লাগইন সিস্টেমের একটি বিস্তারিত আলোচনা প্রদান করে, যা আপনাকে নিজের কাস্টম প্লাগইন তৈরি করতে এবং আপনার ডেভেলপমেন্ট কর্মপ্রবাহকে অপটিমাইজ করতে সক্ষম করবে।
Vite-এর মূল নীতিগুলি বোঝা
প্লাগইন তৈরি করার আগে, Vite-এর মৌলিক নীতিগুলি বোঝা অপরিহার্য:
- অন-ডিমান্ড কম্পাইলেশন: ব্রাউজার যখন কোড অনুরোধ করে, শুধুমাত্র তখনই Vite কোড কম্পাইল করে, যা স্টার্টআপ সময়কে উল্লেখযোগ্যভাবে হ্রাস করে।
- নেটিভ ESM: Vite ডেভেলপমেন্টের জন্য নেটিভ ECMAScript মডিউল (ESM) ব্যবহার করে, যা ডেভেলপমেন্টের সময় বান্ডলিংয়ের প্রয়োজনীয়তা দূর করে।
- রোলআপ-ভিত্তিক প্রোডাকশন বিল্ড: প্রোডাকশন বিল্ডের জন্য, Vite একটি অত্যন্ত অপটিমাইজড বান্ডলার, রোলআপ (Rollup) ব্যবহার করে, যা দক্ষ এবং প্রোডাকশনের জন্য প্রস্তুত কোড তৈরি করে।
Vite-এর ইকোসিস্টেমে প্লাগইনগুলির ভূমিকা
Vite-এর প্লাগইন আর্কিটেকচারটি অত্যন্ত প্রসারণযোগ্য (extensible) হিসেবে ডিজাইন করা হয়েছে। প্লাগইনগুলি যা করতে পারে:
- কোড রূপান্তর করা (যেমন, টাইপস্ক্রিপ্ট ট্রান্সপাইল করা, প্রিপ্রসেসর যোগ করা)।
- কাস্টম ফাইল পরিবেশন করা (যেমন, স্ট্যাটিক অ্যাসেট হ্যান্ডেল করা, ভার্চুয়াল মডিউল তৈরি করা)।
- বিল্ড প্রক্রিয়া পরিবর্তন করা (যেমন, ইমেজ অপটিমাইজ করা, সার্ভিস ওয়ার্কার তৈরি করা)।
- Vite-এর CLI প্রসারিত করা (যেমন, কাস্টম কমান্ড যোগ করা)।
সাধারণ পরিবর্তন থেকে শুরু করে জটিল ইন্টিগ্রেশন পর্যন্ত, বিভিন্ন প্রকল্পের প্রয়োজনীয়তার সাথে Vite-কে খাপ খাইয়ে নেওয়ার চাবিকাঠি হলো প্লাগইন।
Vite প্লাগইন আর্কিটেকচার: একটি গভীর বিশ্লেষণ
একটি Vite প্লাগইন মূলত একটি জাভাস্ক্রিপ্ট অবজেক্ট যার নির্দিষ্ট বৈশিষ্ট্য (properties) রয়েছে যা তার আচরণ নির্ধারণ করে। আসুন মূল উপাদানগুলি পরীক্ষা করা যাক:
প্লাগইন কনফিগারেশন
`vite.config.js` (অথবা `vite.config.ts`) ফাইলে আপনি আপনার Vite প্রজেক্ট কনফিগার করেন, যার মধ্যে কোন প্লাগইন ব্যবহার করা হবে তাও নির্দিষ্ট করা থাকে। `plugins` অপশনটি প্লাগইন অবজেক্টের একটি অ্যারে অথবা প্লাগইন অবজেক্ট রিটার্ন করে এমন ফাংশন গ্রহণ করে।
// vite.config.js
import myPlugin from './my-plugin';
export default {
plugins: [
myPlugin(), // প্লাগইন ইনস্ট্যান্স তৈরি করতে প্লাগইন ফাংশনটি কল করুন
],
};
প্লাগইন অবজেক্ট প্রোপার্টি
একটি Vite প্লাগইন অবজেক্টের বিভিন্ন প্রোপার্টি থাকতে পারে যা বিল্ড প্রক্রিয়ার বিভিন্ন পর্যায়ে তার আচরণ নির্ধারণ করে। এখানে সবচেয়ে সাধারণ প্রোপার্টিগুলির একটি বিবরণ দেওয়া হলো:
- name: প্লাগইনটির জন্য একটি অনন্য নাম। এটি আবশ্যক এবং ডিবাগিং ও কনফ্লিক্ট সমাধানে সহায়তা করে। উদাহরণ: `'my-custom-plugin'`
- enforce: প্লাগইনের এক্সিকিউশন ক্রম নির্ধারণ করে। সম্ভাব্য মানগুলি হলো `'pre'` (কোর প্লাগইনগুলির আগে চলে), `'normal'` (ডিফল্ট), এবং `'post'` (কোর প্লাগইনগুলির পরে চলে)। উদাহরণ: `'pre'`
- config: Vite-এর কনফিগারেশন অবজেক্ট পরিবর্তন করার অনুমতি দেয়। এটি ব্যবহারকারীর কনফিগ এবং এনভায়রনমেন্ট (মোড এবং কমান্ড) গ্রহণ করে। উদাহরণ: `config: (config, { mode, command }) => { ... }`
- configResolved: Vite কনফিগ সম্পূর্ণরূপে সমাধান হওয়ার পরে কল করা হয়। চূড়ান্ত কনফিগ অবজেক্ট অ্যাক্সেস করার জন্য এটি দরকারী। উদাহরণ: `configResolved(config) { ... }`
- configureServer: ডেভেলপমেন্ট সার্ভার ইনস্ট্যান্স (Connect/Express-এর মতো) অ্যাক্সেস প্রদান করে। কাস্টম মিডলওয়্যার যোগ করার জন্য বা সার্ভারের আচরণ পরিবর্তন করার জন্য দরকারী। উদাহরণ: `configureServer(server) { ... }`
- transformIndexHtml: `index.html` ফাইলটি রূপান্তর করার অনুমতি দেয়। স্ক্রিপ্ট, স্টাইল বা মেটা ট্যাগ ইনজেক্ট করার জন্য দরকারী। উদাহরণ: `transformIndexHtml(html) { ... }`
- resolveId: মডিউল রেজোলিউশনকে বাধাগ্রস্ত এবং পরিবর্তন করার অনুমতি দেয়। কাস্টম মডিউল রেজোলিউশন লজিকের জন্য দরকারী। উদাহরণ: `resolveId(source, importer) { ... }`
- load: কাস্টম মডিউল লোড করার বা বিদ্যমান মডিউল বিষয়বস্তু পরিবর্তন করার অনুমতি দেয়। ভার্চুয়াল মডিউল বা কাস্টম লোডারের জন্য দরকারী। উদাহরণ: `load(id) { ... }`
- transform: মডিউলগুলির সোর্স কোড রূপান্তর করে। Babel প্লাগইন বা PostCSS প্লাগইনের মতো। উদাহরণ: `transform(code, id) { ... }`
- buildStart: বিল্ড প্রক্রিয়ার শুরুতে কল করা হয়। উদাহরণ: `buildStart() { ... }`
- buildEnd: বিল্ড প্রক্রিয়া সম্পন্ন হওয়ার পরে কল করা হয়। উদাহরণ: `buildEnd() { ... }`
- closeBundle: বান্ডেলটি ডিস্কে লেখা হয়ে যাওয়ার পরে কল করা হয়। উদাহরণ: `closeBundle() { ... }`
- writeBundle: বান্ডেলটি ডিস্কে লেখার আগে কল করা হয়, যা পরিবর্তনের সুযোগ দেয়। উদাহরণ: `writeBundle(options, bundle) { ... }`
- renderError: ডেভলপমেন্টের সময় কাস্টম এরর পেজ রেন্ডার করার অনুমতি দেয়। উদাহরণ: `renderError(error, req, res) { ... }`
- handleHotUpdate: HMR-এর উপর সূক্ষ্ম নিয়ন্ত্রণ প্রদান করে। উদাহরণ: `handleHotUpdate({ file, server }) { ... }`
প্লাগইন হুক এবং এক্সিকিউশন অর্ডার
Vite প্লাগইনগুলি একাধিক হুকের মাধ্যমে কাজ করে যা বিল্ড প্রক্রিয়ার বিভিন্ন পর্যায়ে ট্রিগার হয়। কার্যকর প্লাগইন লেখার জন্য এই হুকগুলি কোন ক্রমে কার্যকর হয় তা বোঝা অত্যন্ত গুরুত্বপূর্ণ।
- config: Vite কনফিগ পরিবর্তন করুন।
- configResolved: সমাধানকৃত কনফিগ অ্যাক্সেস করুন।
- configureServer: ডেভ সার্ভার পরিবর্তন করুন (শুধুমাত্র ডেভেলপমেন্ট)।
- transformIndexHtml: `index.html` ফাইলটি রূপান্তর করুন।
- buildStart: বিল্ড প্রক্রিয়ার শুরু।
- resolveId: মডিউল আইডি সমাধান করুন।
- load: মডিউল বিষয়বস্তু লোড করুন।
- transform: মডিউল কোড রূপান্তর করুন।
- handleHotUpdate: হট মডিউল রিপ্লেসমেন্ট (HMR) হ্যান্ডেল করুন।
- writeBundle: ডিস্কে লেখার আগে আউটপুট বান্ডেলটি পরিবর্তন করুন।
- closeBundle: আউটপুট বান্ডেলটি ডিস্কে লেখা হয়ে যাওয়ার পরে কল করা হয়।
- buildEnd: বিল্ড প্রক্রিয়ার শেষ।
আপনার প্রথম কাস্টম Vite প্লাগইন তৈরি করা
আসুন একটি সাধারণ Vite প্লাগইন তৈরি করি যা প্রোডাকশন বিল্ডের প্রতিটি জাভাস্ক্রিপ্ট ফাইলের উপরে একটি ব্যানার যুক্ত করবে। এই ব্যানারে প্রজেক্টের নাম এবং সংস্করণ অন্তর্ভুক্ত থাকবে।
প্লাগইন বাস্তবায়ন
// banner-plugin.js
import { readFileSync } from 'node:fs';
import { resolve } from 'node:path';
export default function bannerPlugin() {
return {
name: 'banner-plugin',
apply: 'build',
transform(code, id) {
if (!id.endsWith('.js')) {
return code;
}
const packageJsonPath = resolve(process.cwd(), 'package.json');
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
const banner = `/**\n * Project: ${packageJson.name}\n * Version: ${packageJson.version}\n */\n`;
return banner + code;
},
};
}
ব্যাখ্যা:
- name: প্লাগইনটির নাম 'banner-plugin' নির্ধারণ করে।
- apply: নির্দিষ্ট করে যে এই প্লাগইনটি শুধুমাত্র বিল্ড প্রক্রিয়ার সময় চলবে। এটিকে 'build' সেট করলে এটি শুধুমাত্র প্রোডাকশনের জন্য কাজ করবে, যা ডেভেলপমেন্টের সময় অপ্রয়োজনীয় ওভারহেড এড়ায়।
- transform(code, id):
- এটি প্লাগইনটির মূল অংশ। এটি প্রতিটি মডিউলের কোড (`code`) এবং আইডি (`id`) গ্রহণ করে।
- শর্তাধীন পরীক্ষা: `if (!id.endsWith('.js'))` নিশ্চিত করে যে রূপান্তরটি শুধুমাত্র জাভাস্ক্রিপ্ট ফাইলগুলিতে প্রয়োগ করা হবে। এটি অন্যান্য ফাইলের প্রকার (যেমন CSS বা HTML) প্রসেসিং থেকে বিরত রাখে, যা ত্রুটি বা অপ্রত্যাশিত আচরণের কারণ হতে পারে।
- Package.json অ্যাক্সেস:
- `resolve(process.cwd(), 'package.json')` `package.json` ফাইলের সম্পূর্ণ পাথ তৈরি করে। `process.cwd()` বর্তমান ওয়ার্কিং ডিরেক্টরি প্রদান করে, যা কমান্ডটি যেখান থেকেই চালানো হোক না কেন সঠিক পাথ ব্যবহার নিশ্চিত করে।
- `JSON.parse(readFileSync(packageJsonPath, 'utf-8'))` `package.json` ফাইলটি পড়ে এবং পার্স করে। `readFileSync` ফাইলটি সিঙ্ক্রোনাসভাবে পড়ে এবং `'utf-8'` এনকোডিং ইউনিকোড অক্ষর সঠিকভাবে হ্যান্ডেল করার জন্য নির্দিষ্ট করে। এখানে সিঙ্ক্রোনাস রিডিং গ্রহণযোগ্য কারণ এটি রূপান্তরের শুরুতে একবার ঘটে।
- ব্যানার জেনারেশন:
- ``const banner = `/**\n * Project: ${packageJson.name}\n * Version: ${packageJson.version}\n */\n`;`` ব্যানার স্ট্রিংটি তৈরি করে। এটি টেমপ্লেট লিটারেল (ব্যাকটিক) ব্যবহার করে `package.json` ফাইল থেকে প্রকল্পের নাম এবং সংস্করণ সহজেই এম্বেড করে। `\n` সিকোয়েন্সগুলি ব্যানারকে সঠিকভাবে ফর্ম্যাট করার জন্য নতুন লাইন যুক্ত করে। `*` কে `\*` দিয়ে এস্কেপ করা হয়েছে।
- কোড রূপান্তর: `return banner + code;` মূল জাভাস্ক্রিপ্ট কোডের আগে ব্যানারটি যুক্ত করে। এটি `transform` ফাংশন দ্বারা ফেরত দেওয়া চূড়ান্ত ফলাফল।
প্লাগইনটি ইন্টিগ্রেট করা
আপনার `vite.config.js` ফাইলে প্লাগইনটি ইম্পোর্ট করুন এবং `plugins` অ্যারেতে যোগ করুন:
// vite.config.js
import bannerPlugin from './banner-plugin';
export default {
plugins: [
bannerPlugin(),
],
};
বিল্ড চালানো
এখন, `npm run build` (অথবা আপনার প্রকল্পের বিল্ড কমান্ড) চালান। বিল্ড সম্পন্ন হওয়ার পরে, `dist` ডিরেক্টরিতে তৈরি হওয়া জাভাস্ক্রিপ্ট ফাইলগুলি পরীক্ষা করুন। আপনি প্রতিটি ফাইলের উপরে ব্যানারটি দেখতে পাবেন।
অ্যাডভান্সড প্লাগইন কৌশল
সাধারণ কোড রূপান্তরের বাইরেও, Vite প্লাগইনগুলি তাদের ক্ষমতা বাড়াতে আরও উন্নত কৌশল ব্যবহার করতে পারে।
ভার্চুয়াল মডিউল
ভার্চুয়াল মডিউল প্লাগইনগুলিকে এমন মডিউল তৈরি করতে দেয় যা ডিস্কে প্রকৃত ফাইল হিসেবে বিদ্যমান থাকে না। এটি ডাইনামিক কনটেন্ট তৈরি করার জন্য বা অ্যাপ্লিকেশনে কনফিগারেশন ডেটা সরবরাহ করার জন্য দরকারী।
// virtual-module-plugin.js
export default function virtualModulePlugin(options) {
const virtualModuleId = 'virtual:my-module';
const resolvedVirtualModuleId = '\0' + virtualModuleId; // রোলআপকে প্রসেসিং থেকে বিরত রাখতে \0 দিয়ে শুরু করুন
return {
name: 'virtual-module-plugin',
resolveId(id) {
if (id === virtualModuleId) {
return resolvedVirtualModuleId;
}
},
load(id) {
if (id === resolvedVirtualModuleId) {
return `export default ${JSON.stringify(options)};`;
}
},
};
}
এই উদাহরণে:
- `virtualModuleId` একটি স্ট্রিং যা ভার্চুয়াল মডিউলের আইডেন্টিফায়ারকে প্রতিনিধিত্ব করে।
- `resolvedVirtualModuleId` কে `\0` দিয়ে শুরু করা হয়েছে যাতে রোলআপ এটিকে একটি প্রকৃত ফাইল হিসেবে প্রসেস না করে। এটি রোলআপ প্লাগইনগুলিতে ব্যবহৃত একটি কনভেনশন।
- `resolveId` মডিউল রেজোলিউশনকে বাধা দেয় এবং যদি অনুরোধ করা আইডি `virtualModuleId`-এর সাথে মিলে যায় তবে সমাধানকৃত ভার্চুয়াল মডিউল আইডি ফেরত দেয়।
- `load` মডিউল লোডিংকে বাধা দেয় এবং যদি অনুরোধ করা আইডি `resolvedVirtualModuleId`-এর সাথে মিলে যায় তবে মডিউলের কোড ফেরত দেয়। এক্ষেত্রে, এটি একটি জাভাস্ক্রিপ্ট মডিউল তৈরি করে যা `options`-কে একটি ডিফল্ট এক্সপোর্ট হিসেবে রপ্তানি করে।
ভার্চুয়াল মডিউল ব্যবহার করা
// vite.config.js
import virtualModulePlugin from './virtual-module-plugin';
export default {
plugins: [
virtualModulePlugin({ message: 'Hello from virtual module!' }),
],
};
// main.js
import message from 'virtual:my-module';
console.log(message.message); // আউটপুট: Hello from virtual module!
ইনডেক্স HTML রূপান্তর করা
`transformIndexHtml` হুক আপনাকে `index.html` ফাইলটি পরিবর্তন করার সুযোগ দেয়, যেমন স্ক্রিপ্ট, স্টাইল বা মেটা ট্যাগ ইনজেক্ট করা। এটি অ্যানালিটিক্স ট্র্যাকিং যোগ করা, সোশ্যাল মিডিয়া মেটাডেটা কনফিগার করা বা HTML কাঠামো কাস্টমাইজ করার জন্য দরকারী।
// inject-script-plugin.js
export default function injectScriptPlugin() {
return {
name: 'inject-script-plugin',
transformIndexHtml(html) {
return html.replace(
'