Plugins e Processamento CSS
Aula 2 de 4
Plugin API
Vite possui um sistema de plugins baseado na API de plugins do Rollup, com hooks específicos do Vite.
Estrutura de um Plugin
// plugins/my-plugin.ts
import type { Plugin, ResolvedConfig } from 'vite';
export function myPlugin(options?: { prefix?: string }): Plugin {
let config: ResolvedConfig;
return {
name: 'my-plugin',
// Hook de configuração
config(userConfig, { command, mode }) {
return {
// Modificar config aqui
define: {
__PLUGIN_VERSION__: JSON.stringify('1.0.0')
}
};
},
// Hook de resolução de ID
resolveId(id) {
if (id === 'virtual:module') {
return '\0virtual:module';
}
},
// Hook de load (módulos virtuais)
load(id) {
if (id === '\0virtual:module') {
return `export const version = '1.0.0'`;
}
},
// Hook de transformação de código
transform(code, id) {
if (id.endsWith('.special.ts')) {
return {
code: code.replace(/console\.log/g, 'console.warn'),
map: null
};
}
},
// Hooks específicos Vite
configureServer(server) {
server.middlewares.use((req, res, next) => {
console.log(`Request: ${req.url}`);
next();
});
},
handleHotUpdate({ file, server }) {
console.log(`Hot update: ${file}`);
},
closeBundle() {
console.log('Build finalizado');
}
};
}
Módulos Virtuais
// plugins/virtual-config.ts
import type { Plugin } from 'vite';
export function virtualConfig(): Plugin {
const virtualModuleId = 'virtual:config';
const resolvedVirtualModuleId = '\0' + virtualModuleId;
return {
name: 'virtual-config',
resolveId(id) {
if (id === virtualModuleId) return resolvedVirtualModuleId;
},
load(id) {
if (id === resolvedVirtualModuleId) {
return `
export const appConfig = {
version: '1.0.0',
environment: '${process.env.NODE_ENV}',
features: ['auth', 'dashboard', 'analytics']
};
`;
}
}
};
}
// Uso no código
import { appConfig } from 'virtual:config';
console.log(appConfig.version); // 1.0.0
Plugins Essenciais
React
npm install @vitejs/plugin-react
// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [
react({
jsxRuntime: 'automatic',
babel: {
plugins: ['@emotion/babel-plugin']
},
fastRefresh: true
})
]
});
Vue
npm install @vitejs/plugin-vue
import vue from '@vitejs/plugin-vue';
export default defineConfig({
plugins: [vue()]
});
ESLint
npm install -D vite-plugin-eslint
import eslint from 'vite-plugin-eslint';
export default defineConfig({
plugins: [
eslint({
cache: false,
fix: true
})
]
});
SVGR
npm install -D @svgr/rollup
import svgr from '@svgr/rollup';
export default defineConfig({
plugins: [svgr()]
});
import Logo from './logo.svg?react';
function App() {
return <Logo width={100} height={100} />;
}
tsconfig-paths
npm install -D vite-tsconfig-paths
import tsconfigPaths from 'vite-tsconfig-paths';
export default defineConfig({
plugins: [tsconfigPaths()] // Lê paths do tsconfig.json
});
CSS
PostCSS
npm install -D postcss autoprefixer
// postcss.config.js
export default {
plugins: {
autoprefixer: {
overrideBrowserslist: ['> 1%', 'last 2 versions']
},
'postcss-nesting': {},
'postcss-preset-env': {
stage: 2,
features: {
'nesting-rules': true
}
}
}
};
CSS Modules
/* src/components/Button.module.css */
.button {
padding: 8px 16px;
border-radius: 4px;
}
.primary {
background: #646cff;
color: white;
}
// src/components/Button.tsx
import styles from './Button.module.css';
export function Button({ primary }: { primary?: boolean }) {
return (
<button
className={`${styles.button} ${primary ? styles.primary : ''}`}
>
Click me
</button>
);
}
Tailwind CSS
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
// tailwind.config.js
export default {
content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
theme: {
extend: {
colors: {
primary: '#646cff'
}
}
},
plugins: []
};
/* src/index.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
Lightning CSS
// vite.config.ts
export default defineConfig({
css: {
transformer: 'lightningcss',
lightningcss: {
drafts: {
nesting: true,
customMedia: true
}
}
}
});
@import Inlining
Vite inlineia automaticamente arquivos CSS importados.
/* src/styles/base.css */
@import './reset.css';
@import './variables.css';
@import './typography.css';
body {
font-family: system-ui;
}
// vite.config.ts
export default defineConfig({
css: {
// Desabilitar inlining (se necessário)
preprocessorOptions: {
css: {
additionalData: ''
}
}
}
});
Lab: Exercício - Configuração com Plugins e CSS
// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import tsconfigPaths from 'vite-tsconfig-paths';
import svgr from '@svgr/rollup';
import eslint from 'vite-plugin-eslint';
export default defineConfig({
plugins: [
react(),
tsconfigPaths(),
svgr(),
eslint({ fix: true })
],
css: {
modules: {
localsConvention: 'camelCaseOnly'
},
preprocessorOptions: {
scss: {
additionalData: `
@import "@/styles/variables";
@import "@/styles/mixins";
`
}
}
}
});
npm install -D sass
npm run dev
Sistema de plugins do Vite é flexível (baseado no Rollup). Plugins podem criar módulos virtuais, transformar código e modificar configuração. CSS Modules, PostCSS, Tailwind e Lightning CSS são suportados nativamente. SCSS/Less precisam de preprocessor instalado.