está se tornando cada vez mais popular entre os desenvolvedores, mas como a comunidade não é tão grande (como no ), pode ser necessário criar seu próprio plugin personalizado para resolver seus problemas. Neste artigo, discutiremos como criar um plugin para e detalharei meu próprio plugin. O Vite Webpack Vite Como funcionam os plug-ins no Vite Para criar um plugin, é importante saber que o Vite utiliza diferentes sistemas de build para o servidor de desenvolvimento (comando ) e o bundle (comando ). vite vite build Para o servidor de desenvolvimento, ele usa com módulos ES nativos, que são suportados por navegadores modernos, e não precisamos agrupar o código em um único arquivo, e isso nos fornece HRM (Hot Module Replacement) rápido. esbuild Para o pacote, ele usa porque é flexível e possui um grande ecossistema; permite a criação de pacotes de produção altamente otimizados com diferentes formatos de saída. rollup.js A interface do plugin do Vite é baseada no Rollup, mas com opções e ganchos adicionais para trabalhar com o servidor de desenvolvimento. Criando um plugin básico Ao criar um plug-in, você pode incorporá-lo em seu . Não há necessidade de criar um novo pacote para isso. Depois de perceber que um plugin foi útil em seus projetos, considere compartilhá-lo com a comunidade e contribuir com o ecossistema Vite. vite.config.js Além disso, como rollup.js tem uma comunidade e um ecossistema maiores, você pode considerar a criação de um plugin para rollup.js, e ele funcionará perfeitamente no Vite. Portanto, se a funcionalidade do seu plugin funcionar apenas para o pacote, você pode usar o plugin rollup.js em vez do Vite, e os usuários podem usar o plugin rollup em seus projetos Vite sem problemas. Se você criar um plug-in para rollup, abrangerá mais usuários que usam apenas rollup.js. Se o seu plugin afetar o servidor de desenvolvimento, você deve usar o plugin Vite. Vamos começar a criar o plugin diretamente em : 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(), ], }); Neste exemplo, criei um plugin chamado que imprime a configuração do Vite assim que for resolvido no console em ambos os estágios: dev server e bundle. Se eu quiser imprimir a configuração apenas no modo de servidor de desenvolvimento, devo adicionar e para pacote. myPlugin 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(), ], }); Além disso, posso retornar uma série de plugins; é útil para separar funcionalidades do servidor de desenvolvimento e do pacote: // 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(), ], }); E é basicamente isso; você pode facilmente adicionar pequenos plug-ins à configuração do Vite. E se um plugin ficar muito grande, prefiro movê-lo para outro arquivo ou até mesmo criar um pacote. Se você precisar de algo mais complexo, há muitos ganchos úteis que você pode explorar na documentação do Vite. Mas, como exemplo, vamos detalhar meu próprio plugin abaixo. Quebrando um plugin real Então, eu tenho um plugin para criar sprites SVG baseados em arquivos de ícones - . vite-plugin-svg-spritemap O objetivo é pegar todos os ícones na pasta e coletar seu conteúdo em um único arquivo chamado SVG sprite. Vamos começar pelo estágio de pacote: .svg src/icons .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 nos permite obter a configuração quando for resolvido para usá-la nos próximos ganchos; configResolved O gancho é chamado após a conclusão do processo de empacotamento e, aqui, criarei o arquivo ; writeBundle sprite.svg A função retorna uma string de sprites SVG preparados com base no padrão . Não vou me aprofundar nisso; você pode conferir meu outro ; getSpriteContent src/icons/*.svg artigo explicando todo o processo de geração de sprites SVG Em seguida, eu crio o caminho absoluto para para colocar o conteúdo do sprite SVG com , certifico-me de que o arquivo existe (ou crio um) com ., e gravo o conteúdo do sprite SVG nele . sprite.svg path.resolve() fs.ensureFileSync Agora, a parte mais interessante – o estágio do servidor de desenvolvimento. Não posso usar aqui e não posso hospedar arquivos quando o servidor de desenvolvimento está em execução, então precisamos usar o middleware do servidor para capturar a solicitação para . 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); }); }; }, }; } é um gancho para configurar o servidor de desenvolvimento. Ele é acionado antes que o middleware interno do Vite seja instalado; no meu caso, preciso adicionar middleware customizado após o middleware interno, então retorno uma função; configureServer Para adicionar middleware personalizado para capturar todas as solicitações ao servidor de desenvolvimento, eu uso . Preciso dele para detectar solicitações com a URL , para poder emular o comportamento do arquivo; server.middlewares.use() [localhost:3000/sprite.svg](http://localhost:3000/sprite.svg) Se a URL da solicitação não for - pule para o próximo middleware (ou seja, passe o controle para o próximo manipulador na cadeia); /sprite.svg Para preparar o conteúdo do arquivo, coloco o resultado de na variável e envio como resposta com cabeçalhos configurados (tipo de conteúdo e status HTTP 200). getSpriteContent sprite Como resultado, simulei o comportamento do arquivo. Mas se os arquivos em forem alterados, excluídos ou adicionados, devemos reiniciar o servidor para gerar novo conteúdo de sprite via ; para isso, usarei a biblioteca de observação de arquivos - . Vamos adicionar manipuladores chokidar ao código: src/icons getSpriteContent chokidar 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); }); }; }, }; } Como você pode ver, a API de criação de plugins não é muito complicada. Você só precisa encontrar ganchos do Vite ou Rollup que se adaptem às suas tarefas. No meu exemplo, estou usando do Rollup.js (como eu disse, ele é usado para gerar o pacote) e do Vite porque Rollup.js não tem suporte nativo ao servidor de desenvolvimento. writeBundle configureServer No caso do foi muito simples, pegamos o conteúdo do sprite SVG e colocamos em um arquivo. No caso do servidor de desenvolvimento, fiquei confuso porque não pude fazer o mesmo; Eu olhei para plug-ins de outros autores e todos eles fazem a mesma coisa. writeBundle Então, eu uso e, por meio do argumento , adiciono middleware que aciona todas as solicitações ao servidor de desenvolvimento, interceptando a solicitação . configureServer server sprite.svg Usando ganchos Vite Como mencionei antes, para criar plugins mais úteis, você precisa explorar os ganchos. Eles são explicados em detalhes na documentação: https://vitejs.dev/guide/api-plugin#universal-hooks https://vitejs.dev/guide/api-plugin#vite-specific-hooks Como nomear um plug-in Em termos de nomenclatura, o Vite possui algumas convenções para plugins, então é melhor você conferir antes de terminar. Aqui estão alguns pontos-chave: Os plug-ins Vite devem ter um nome exclusivo com um prefixo ; vite-plugin- Inclua a palavra-chave em package.json; vite-plugin Inclua uma seção na documentação do plugin explicando por que ele é um plugin somente do Vite (por exemplo, ele usa ganchos de plugin específicos do Vite); Se o seu plugin funcionar apenas para uma estrutura específica, inclua seu nome como parte do prefixo ( , , ). vite-plugin-vue- vite-plugin-react- vite-plugin-svelte- Como publicar e compartilhar seu plugin Se você decidir publicar seu plugin no NPM, recomendo porque compartilhar conhecimento e expertise é um princípio fundamental da comunidade de TI, fomentando o crescimento coletivo. Para saber como publicar e manter seu pacote, confira meu guia → . A maneira mais fácil de criar um pacote NPM Eu também recomendo enviar seu plugin para a lista da comunidade do vite - . Muitas pessoas procuram os plugins mais adequados por lá, e seria uma ótima oportunidade de contribuir com o ecossistema Vite! O processo de envio do seu plugin é simples - apenas certifique-se de cumprir os termos e criar uma solicitação pull. Você pode encontrar a lista de termos . awesome-vite aqui No geral, ele precisa ser específico para Vite (não rollup), código aberto e ter boa documentação. Boa sorte com seus plug-ins!