Vite
Modern és gyors frontend build eszköz WordPress témákhoz és bővítményekhez.
A Vite egy modern, rendkívül gyors frontend build eszköz, amely natív ES modulokat használ fejlesztés közben. WordPress témákhoz és bővítményekhez ideális választás a gyors HMR (Hot Module Replacement) és az optimalizált production build miatt.
Miért Vite?
Szekció neve “Miért Vite?”- Villámgyors - Native ES modules fejlesztéshez
- HMR - Azonnali módosítások böngészőben
- Modern - ES6+, TypeScript, JSX támogatás
- Optimalizált build - Rollup alapú production build
- Plugin rendszer - Bővíthető funkcionalitás
- CSS kezelés - PostCSS, Sass, Less támogatás
Telepítés
Szekció neve “Telepítés”Új projekt
Szekció neve “Új projekt”# npmnpm create vite@latest my-wordpress-theme
# yarnyarn create vite my-wordpress-theme
# pnpmpnpm create vite my-wordpress-themeMeglévő projektbe
Szekció neve “Meglévő projektbe”cd my-wordpress-pluginnpm init -ynpm install -D viteWordPress téma integráció
Szekció neve “WordPress téma integráció”Projekt struktúra
Szekció neve “Projekt struktúra”my-theme/├── src/│ ├── js/│ │ └── main.js│ ├── css/│ │ └── style.css│ └── images/├── dist/ # Build output├── vite.config.js├── package.json├── functions.php└── style.cssvite.config.js
Szekció neve “vite.config.js”import { defineConfig } from 'vite';import { resolve } from 'path';
export default defineConfig({ build: { // Output könyvtár outDir: 'dist',
// Manifest fájl generálása (PHP integrációhoz) manifest: true,
// Rollup beállítások rollupOptions: { input: { main: resolve(__dirname, 'src/js/main.js'), admin: resolve(__dirname, 'src/js/admin.js'), }, output: { entryFileNames: 'js/[name].[hash].js', chunkFileNames: 'js/[name].[hash].js', assetFileNames: (assetInfo) => { if (assetInfo.name.endsWith('.css')) { return 'css/[name].[hash][extname]'; } return 'assets/[name].[hash][extname]'; }, }, }, },
// Development server server: { // CORS engedélyezése WordPress-hez cors: true, // Port port: 5173, // Strict port (ne váltson másikra) strictPort: true, // HMR beállítások hmr: { host: 'localhost', }, },});package.json scripts
Szekció neve “package.json scripts”{ "scripts": { "dev": "vite", "build": "vite build", "preview": "vite preview" }}PHP integráció
Szekció neve “PHP integráció”Vite helper függvények
Szekció neve “Vite helper függvények”inc/vite.php:
<?php/** * Vite integration for WordPress */
namespace MyTheme\Vite;
/** * Get Vite dev server status */function is_dev_server_running(): bool { if ( ! defined( 'WP_DEBUG' ) || ! WP_DEBUG ) { return false; }
$dev_server_url = 'http://localhost:5173';
$response = @file_get_contents( $dev_server_url ); return $response !== false;}
/** * Get asset URL from manifest */function get_asset_url( string $entry ): string { $manifest_path = get_template_directory() . '/dist/.vite/manifest.json';
if ( ! file_exists( $manifest_path ) ) { return ''; }
$manifest = json_decode( file_get_contents( $manifest_path ), true );
if ( ! isset( $manifest[ $entry ] ) ) { return ''; }
return get_template_directory_uri() . '/dist/' . $manifest[ $entry ]['file'];}
/** * Get CSS files from manifest entry */function get_css_files( string $entry ): array { $manifest_path = get_template_directory() . '/dist/.vite/manifest.json';
if ( ! file_exists( $manifest_path ) ) { return []; }
$manifest = json_decode( file_get_contents( $manifest_path ), true );
if ( ! isset( $manifest[ $entry ]['css'] ) ) { return []; }
return array_map( function( $css ) { return get_template_directory_uri() . '/dist/' . $css; }, $manifest[ $entry ]['css'] );}
/** * Enqueue Vite assets */function enqueue_assets(): void { if ( is_dev_server_running() ) { // Development mode - Vite dev server wp_enqueue_script( 'vite-client', 'http://localhost:5173/@vite/client', [], null, false );
wp_enqueue_script( 'theme-main', 'http://localhost:5173/src/js/main.js', [], null, true );
// Module típus beállítása add_filter( 'script_loader_tag', function( $tag, $handle ) { if ( in_array( $handle, [ 'vite-client', 'theme-main' ], true ) ) { return str_replace( '<script ', '<script type="module" ', $tag ); } return $tag; }, 10, 2 ); } else { // Production mode - built assets $js_url = get_asset_url( 'src/js/main.js' );
if ( $js_url ) { wp_enqueue_script( 'theme-main', $js_url, [], null, true ); }
// CSS betöltése foreach ( get_css_files( 'src/js/main.js' ) as $index => $css_url ) { wp_enqueue_style( 'theme-style-' . $index, $css_url, [], null ); } }}add_action( 'wp_enqueue_scripts', __NAMESPACE__ . '\\enqueue_assets' );functions.php
Szekció neve “functions.php”<?php// Vite helper betöltéserequire_once get_template_directory() . '/inc/vite.php';JavaScript és CSS
Szekció neve “JavaScript és CSS”Entry point (src/js/main.js)
Szekció neve “Entry point (src/js/main.js)”// CSS importálásaimport '../css/style.css';
// JavaScriptdocument.addEventListener('DOMContentLoaded', () => { console.log('Theme loaded!');
// WordPress REST API példa fetch('/wp-json/wp/v2/posts') .then(response => response.json()) .then(posts => { console.log('Posts:', posts); });});
// HMR támogatásif (import.meta.hot) { import.meta.hot.accept();}CSS (src/css/style.css)
Szekció neve “CSS (src/css/style.css)”/* Modern CSS */:root { --color-primary: #0073aa; --color-secondary: #23282d;}
body { font-family: system-ui, -apple-system, sans-serif; line-height: 1.6; color: var(--color-secondary);}
.button { background: var(--color-primary); color: white; padding: 0.5rem 1rem; border: none; border-radius: 4px; cursor: pointer; transition: background 0.2s;
&:hover { background: color-mix(in srgb, var(--color-primary) 80%, black); }}Sass támogatás
Szekció neve “Sass támogatás”Telepítés
Szekció neve “Telepítés”npm install -D sassHasználat
Szekció neve “Használat”import '../scss/style.scss';@use 'variables';@use 'mixins';
body { font-family: variables.$font-family;}PostCSS
Szekció neve “PostCSS”Telepítés
Szekció neve “Telepítés”npm install -D postcss autoprefixer postcss-preset-envpostcss.config.js
Szekció neve “postcss.config.js”export default { plugins: { 'postcss-preset-env': { stage: 2, features: { 'nesting-rules': true, }, }, autoprefixer: {}, },};Tailwind CSS integráció
Szekció neve “Tailwind CSS integráció”Telepítés
Szekció neve “Telepítés”npm install -D tailwindcss postcss autoprefixernpx tailwindcss init -ptailwind.config.js
Szekció neve “tailwind.config.js”/** @type {import('tailwindcss').Config} */export default { content: [ './**/*.php', './src/**/*.{js,jsx,ts,tsx}', ], theme: { extend: {}, }, plugins: [],};@tailwind base;@tailwind components;@tailwind utilities;React támogatás
Szekció neve “React támogatás”Telepítés
Szekció neve “Telepítés”npm install react react-domnpm install -D @vitejs/plugin-reactvite.config.js
Szekció neve “vite.config.js”import { defineConfig } from 'vite';import react from '@vitejs/plugin-react';
export default defineConfig({ plugins: [react()], // ... többi konfiguráció});React komponens
Szekció neve “React komponens”import { useState } from 'react';
export default function App() { const [count, setCount] = useState(0);
return ( <div className="my-app"> <h1>WordPress + Vite + React</h1> <button onClick={() => setCount(count + 1)}> Count: {count} </button> </div> );}WordPress block integráció
Szekció neve “WordPress block integráció”import { registerBlockType } from '@wordpress/blocks';import Edit from './edit';import Save from './save';
registerBlockType('my-theme/my-block', { edit: Edit, save: Save,});TypeScript támogatás
Szekció neve “TypeScript támogatás”Telepítés
Szekció neve “Telepítés”npm install -D typescripttsconfig.json
Szekció neve “tsconfig.json”{ "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "module": "ESNext", "lib": ["ES2020", "DOM", "DOM.Iterable"], "skipLibCheck": true, "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"]}TypeScript használata
Szekció neve “TypeScript használata”interface Post { id: number; title: { rendered: string }; content: { rendered: string };}
async function fetchPosts(): Promise<Post[]> { const response = await fetch('/wp-json/wp/v2/posts'); return response.json();}
fetchPosts().then(posts => { posts.forEach(post => { console.log(post.title.rendered); });});Plugin fejlesztés
Szekció neve “Plugin fejlesztés”vite.config.js (plugin)
Szekció neve “vite.config.js (plugin)”import { defineConfig } from 'vite';import { resolve } from 'path';
export default defineConfig({ build: { outDir: 'assets/dist', manifest: true, rollupOptions: { input: { frontend: resolve(__dirname, 'assets/src/js/frontend.js'), admin: resolve(__dirname, 'assets/src/js/admin.js'), 'block-editor': resolve(__dirname, 'assets/src/js/block-editor.js'), }, }, },});Plugin asset betöltés
Szekció neve “Plugin asset betöltés”<?phpclass My_Plugin_Assets { private static $manifest = null;
public static function init() { add_action( 'wp_enqueue_scripts', [ __CLASS__, 'enqueue_frontend' ] ); add_action( 'admin_enqueue_scripts', [ __CLASS__, 'enqueue_admin' ] ); add_action( 'enqueue_block_editor_assets', [ __CLASS__, 'enqueue_block_editor' ] ); }
private static function get_manifest() { if ( self::$manifest === null ) { $manifest_path = plugin_dir_path( __FILE__ ) . 'assets/dist/.vite/manifest.json'; if ( file_exists( $manifest_path ) ) { self::$manifest = json_decode( file_get_contents( $manifest_path ), true ); } else { self::$manifest = []; } } return self::$manifest; }
private static function get_asset_url( $entry ) { $manifest = self::get_manifest(); if ( isset( $manifest[ $entry ] ) ) { return plugins_url( 'assets/dist/' . $manifest[ $entry ]['file'], __FILE__ ); } return ''; }
public static function enqueue_frontend() { $url = self::get_asset_url( 'assets/src/js/frontend.js' ); if ( $url ) { wp_enqueue_script( 'my-plugin-frontend', $url, [], null, true ); } }
public static function enqueue_admin( $hook ) { if ( 'toplevel_page_my-plugin' !== $hook ) { return; }
$url = self::get_asset_url( 'assets/src/js/admin.js' ); if ( $url ) { wp_enqueue_script( 'my-plugin-admin', $url, [], null, true ); } }
public static function enqueue_block_editor() { $url = self::get_asset_url( 'assets/src/js/block-editor.js' ); if ( $url ) { wp_enqueue_script( 'my-plugin-blocks', $url, [ 'wp-blocks', 'wp-element' ], null, true ); } }}
My_Plugin_Assets::init();Hasznos pluginek
Szekció neve “Hasznos pluginek”vite-plugin-static-copy
Szekció neve “vite-plugin-static-copy”npm install -D vite-plugin-static-copyimport { viteStaticCopy } from 'vite-plugin-static-copy';
export default defineConfig({ plugins: [ viteStaticCopy({ targets: [ { src: 'src/images/*', dest: 'images', }, ], }), ],});vite-plugin-compression
Szekció neve “vite-plugin-compression”npm install -D vite-plugin-compressionimport viteCompression from 'vite-plugin-compression';
export default defineConfig({ plugins: [ viteCompression({ algorithm: 'gzip', }), ],});Production build
Szekció neve “Production build”# Buildnpm run build
# Output ellenőrzésels -la dist/Build output
Szekció neve “Build output”dist/├── .vite/│ └── manifest.json├── js/│ └── main.[hash].js├── css/│ └── style.[hash].css└── assets/ └── images/