Vite डेवलपर्स के बीच अधिक से अधिक लोकप्रिय हो रहा है, लेकिन चूंकि समुदाय उतना बड़ा नहीं है (जैसा कि वेबपैक में है), आपको अपनी समस्याओं को हल करने के लिए अपना स्वयं का कस्टम प्लगइन बनाने की आवश्यकता हो सकती है। इस लेख में, हम चर्चा करेंगे कि Vite के लिए एक प्लगइन कैसे बनाया जाए, और मैं अपने स्वयं के प्लगइन को तोड़ दूंगा।
प्लगइन बनाने के लिए, यह जानना महत्वपूर्ण है कि Vite डेवलपमेंट सर्वर (कमांड vite
) और बंडल (कमांड vite build
) के लिए अलग-अलग बिल्ड सिस्टम का उपयोग करता है।
विकास सर्वर के लिए, यह देशी ES मॉड्यूल के साथ esbuild का उपयोग करता है, जो आधुनिक ब्राउज़रों द्वारा समर्थित हैं, और हमें कोड को एक फ़ाइल में बंडल करने की आवश्यकता नहीं है, और यह हमें तेज़ HRM (हॉट मॉड्यूल रिप्लेसमेंट) देता है।
बंडल के लिए, यह रोलअप.जेएस का उपयोग करता है क्योंकि यह लचीला है और इसमें एक बड़ा पारिस्थितिकी तंत्र है; यह विभिन्न आउटपुट स्वरूपों के साथ अत्यधिक अनुकूलित उत्पादन बंडलों के निर्माण की अनुमति देता है।
वाइट का प्लगइन इंटरफ़ेस रोलअप पर आधारित है लेकिन डेव सर्वर के साथ काम करने के लिए अतिरिक्त विकल्प और हुक के साथ है।
जब आप एक प्लगइन बनाते हैं, तो आप इसे अपने vite.config.js
में इनलाइन कर सकते हैं। इसके लिए कोई नया पैकेज बनाने की जरूरत नहीं है. एक बार जब आप देखते हैं कि कोई प्लगइन आपकी परियोजनाओं में उपयोगी रहा है, तो इसे समुदाय के साथ साझा करने और वाइट पारिस्थितिकी तंत्र में योगदान करने पर विचार करें।
इसके अलावा, चूँकिrollup.js में एक बड़ा समुदाय और पारिस्थितिकी तंत्र है, इसलिए आपrollup.js के लिए एक प्लगइन बनाने पर विचार कर सकते हैं, और यह Vite में भी ठीक से काम करेगा। इसलिए, यदि आपकी प्लगइन कार्यक्षमता केवल बंडल के लिए काम करती है, तो आप Vite के बजाय रोलअप.js प्लगइन के साथ जा सकते हैं, और उपयोगकर्ता बिना किसी समस्या के अपने Vite प्रोजेक्ट्स में आपके रोलअप प्लगइन का उपयोग कर सकते हैं।
यदि आप रोलअप के लिए एक प्लगइन बनाते हैं, तो आप अधिक उपयोगकर्ताओं को कवर करेंगे जो केवल रोलअप.जेएस का उपयोग करते हैं। यदि आपका प्लगइन डेवलपमेंट सर्वर को प्रभावित करेगा, तो आप 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 कॉन्फिगरेशन को प्रिंट करता है: डेव सर्वर और बंडल। यदि मैं कॉन्फ़िगरेशन को केवल डेव सर्वर मोड में प्रिंट करना चाहता हूं, तो मुझे बंडल के लिए 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(), ], });
इसके अलावा, मैं प्लगइन्स की एक श्रृंखला वापस कर सकता हूं; यह डेव सर्वर और बंडल के लिए कार्यक्षमता को अलग करने के लिए उपयोगी है:
// 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 स्प्राइट्स की एक स्ट्रिंग लौटाता है। मैं इसके बारे में अधिक गहराई में नहीं जाऊंगा; आप एसवीजी स्प्राइट जेनरेशन की पूरी प्रक्रिया को समझाने वाला मेरा दूसरा लेख देख सकते हैं;
फिर, मैं एसवीजी स्प्राइट सामग्री को path.resolve()
के साथ डालने के लिए sprite.svg
के लिए पूर्ण पथ बनाता हूं, सुनिश्चित करता हूं कि फ़ाइल fs.ensureFileSync
के साथ मौजूद है (या एक बनाएं), और उसमें SVG स्प्राइट सामग्री लिखें। .
अब, सबसे दिलचस्प भाग के लिए - डेव सर्वर चरण। मैं यहां writeBundle
उपयोग नहीं कर सकता, और जब डेव सर्वर चल रहा हो तो मैं फ़ाइलों को होस्ट नहीं कर सकता, इसलिए हमें 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); }); }; }, }; }
जैसा कि आप देख सकते हैं, प्लगइन निर्माण की एपीआई वास्तव में जटिल नहीं है। आपको बस वाइट या रोलअप से ऐसे हुक ढूंढने की ज़रूरत है जो आपके कार्यों में फिट हों। मेरे उदाहरण में, मैं रोलअप.जेएस से writeBundle
उपयोग कर रहा हूं (जैसा कि मैंने कहा, इसका उपयोग बंडल उत्पन्न करने के लिए किया जाता है), और वाइट से configureServer
कर रहा हूं क्योंकि रोलअप.जेएस में मूल देव सर्वर समर्थन नहीं है।
writeBundle
के मामले में यह बहुत सरल था, हमने एसवीजी स्प्राइट सामग्री ली और इसे एक फ़ाइल में डाल दिया। डेव सर्वर के मामले में, इसने मुझे भ्रमित कर दिया कि मैं ऐसा क्यों नहीं कर सका; मैंने अन्य लेखकों के प्लगइन्स को देखा, और वे सभी भी लगभग ऐसा ही करते हैं।
इसलिए, मैं configureServer
का उपयोग करता हूं और server
तर्क के माध्यम से, मैं मिडलवेयर जोड़ता हूं जो sprite.svg
अनुरोध को रोककर देव सर्वर पर हर अनुरोध को ट्रिगर करता है।
जैसा कि मैंने पहले उल्लेख किया है, अधिक उपयोगी प्लगइन बनाने के लिए, आपको हुक का पता लगाने की आवश्यकता है। उन्हें दस्तावेज़ीकरण में विस्तार से समझाया गया है:
https://vitejs.dev/guide/api-plugin#universal-hooks
https://vitejs.dev/guide/api-plugin#vite-special-hooks
नामकरण के संदर्भ में, Vite में प्लगइन्स के लिए कुछ परंपराएं हैं, इसलिए बेहतर होगा कि आप इसे समाप्त करने से पहले जांच लें। यहां कुछ प्रमुख बिंदु दिए गए हैं:
vite-plugin-
उपसर्ग के साथ एक अद्वितीय नाम होना चाहिए;
vite-plugin
कीवर्ड शामिल करें;
vite-plugin-vue-
, vite-plugin-react-
, vite-plugin-svelte-
)।यदि आप अपने प्लगइन को एनपीएम में प्रकाशित करने का निर्णय लेते हैं, जिसकी मैं अनुशंसा करता हूं क्योंकि ज्ञान और विशेषज्ञता साझा करना आईटी समुदाय का एक बुनियादी सिद्धांत है, जो सामूहिक विकास को बढ़ावा देता है। अपने पैकेज को प्रकाशित करने और बनाए रखने का तरीका जानने के लिए, मेरी मार्गदर्शिका देखें → एनपीएम पैकेज बनाने का सबसे आसान तरीका ।
मैं आपके प्लगइन को वाइट की समुदाय सूची - अमेजिंग-वाइट में सबमिट करने की भी अत्यधिक अनुशंसा करता हूं। बहुत से लोग वहां सबसे उपयुक्त प्लगइन्स की तलाश में हैं, और यह वाइट पारिस्थितिकी तंत्र में योगदान करने का एक शानदार अवसर होगा! वहां अपना प्लगइन सबमिट करने की प्रक्रिया सरल है - बस सुनिश्चित करें कि आप शर्तों को पूरा करते हैं और एक पुल अनुरोध बनाएं। आप शर्तों की सूची यहां पा सकते हैं।
कुल मिलाकर, इसे Vite (रोलअप नहीं) के लिए विशिष्ट होना चाहिए, खुला स्रोत होना चाहिए, और अच्छे दस्तावेज़ होने चाहिए। आपके प्लगइन्स के लिए शुभकामनाएँ!