Vite HMR Integration
A Wordpress plugin that allows for easy setup of Vite hot module reloading
by Your Name · github.com/jack-sandeman/vite-hmr-for-wordpress · website
Install
No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:
wp plugin install https://github.com/jack-sandeman/vite-hmr-for-wordpress/archive/refs/heads/master.zipA must-use plugin that enables Vite Hot Module Replacement (HMR) for WordPress plugins and themes. Once installed, other plugins can easily integrate Vite with zero configuration.
Features
- ✨ Zero Config HMR: Automatically detects dev vs production mode
- 🔥 Hot Module Replacement: Instant updates without page refresh
- ⚛️ React Fast Refresh: Built-in support for React projects
- 📦 Smart Asset Loading: Loads from dev server or production manifest
- 🎯 Simple API: Single function call to enqueue Vite assets
- 🔧 Flexible Configuration: Customize dev server URL, port, and more
Installation
This is a must-use plugin, which means it's automatically activated when placed in the mu-plugins directory.
For Bedrock-based WordPress installations:
# Already installed at: web/app/mu-plugins/vite-hmr/
For standard WordPress installations:
# Copy the vite-hmr folder to wp-content/mu-plugins/
Usage
Quick Start
- In your plugin/theme directory, copy the example Vite config:
cp web/app/mu-plugins/vite-hmr/vite.config.example.js vite.config.js
- Install Vite (and React plugin if using React):
npm install --save-dev vite
# If using React:
npm install --save-dev @vitejs/plugin-react
- Create your entry point (e.g.,
src/main.tsxorsrc/main.js):
// src/main.tsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import './style.css'
function App() {
return <h1>Hello from Vite + React + WordPress!</h1>
}
ReactDOM.createRoot(document.getElementById('root')!).render(<App />)
- Enqueue the asset in your plugin:
<?php
// your-plugin.php
add_action('wp_enqueue_scripts', function() {
// Simple usage - auto-detects plugin directory
\ViteHMR\vite_enqueue_asset('my-app', 'src/main.tsx');
});
- Start the dev server:
npm run dev
- Build for production:
npm run build
API Reference
vite_enqueue_asset()
Enqueue a Vite asset in development or production mode.
\ViteHMR\vite_enqueue_asset(string $handle, string $entry, array $options = [])
Parameters
$handle(string, required): Unique identifier for this asset$entry(string, required): Entry point file relative to plugin root (e.g.,src/main.tsx)$options(array, optional): Configuration options
Options
[
'plugin_dir' => null, // Auto-detected if not provided
'plugin_url' => null, // Auto-detected if not provided
'dev_server' => 'http://localhost:5173', // Dev server URL
'dev_port' => 5173, // Dev server port
'dependencies' => [], // Script dependencies
'in_footer' => true, // Load script in footer
]
Examples
Basic Usage
// Enqueue with default options
add_action('wp_enqueue_scripts', function() {
\ViteHMR\vite_enqueue_asset('my-app', 'src/main.tsx');
});
Admin Scripts
// Enqueue in admin area
add_action('admin_enqueue_scripts', function() {
\ViteHMR\vite_enqueue_asset('my-admin-app', 'src/admin.tsx');
});
With Dependencies
// Enqueue with jQuery dependency
add_action('wp_enqueue_scripts', function() {
\ViteHMR\vite_enqueue_asset('my-app', 'src/main.js', [
'dependencies' => ['jquery'],
]);
});
Custom Dev Server
// Use custom dev server port
add_action('wp_enqueue_scripts', function() {
\ViteHMR\vite_enqueue_asset('my-app', 'src/main.tsx', [
'dev_server' => 'http://localhost:3000',
'dev_port' => 3000,
]);
});
Multiple Entry Points
add_action('wp_enqueue_scripts', function() {
// Frontend app
\ViteHMR\vite_enqueue_asset('frontend-app', 'src/frontend/main.tsx');
// Widget app
\ViteHMR\vite_enqueue_asset('widget-app', 'src/widget/main.tsx');
});
add_action('admin_enqueue_scripts', function() {
// Admin app
\ViteHMR\vite_enqueue_asset('admin-app', 'src/admin/main.tsx');
});
How It Works
Development Mode
When Vite dev server is running (npm run dev):
- Plugin detects dev server at
http://localhost:5173 - Injects Vite client for HMR
- Injects React Refresh runtime (for
.tsx/.jsxfiles) - Loads assets directly from dev server
- Hot module replacement works automatically
Production Mode
When Vite dev server is NOT running:
- Plugin reads
.vite/manifest.json(generated bynpm run build) - Loads hashed production assets from
dist/directory - Automatically enqueues associated CSS files
- Uses versioned assets for cache busting
Project Structure
your-plugin/
├── src/
│ ├── main.tsx # Entry point
│ ├── App.tsx # React components
│ └── style.css # Styles
├── dist/ # Production build (generated)
│ ├── .vite/
│ │ └── manifest.json # Asset manifest
│ └── assets/ # Compiled assets
├── vite.config.js # Vite configuration
├── package.json # Dependencies
├── tsconfig.json # TypeScript config (optional)
└── your-plugin.php # WordPress plugin file
Vite Configuration
The example config (vite.config.example.js) includes:
- React plugin support
- HMR configuration
- Build optimization
- Manifest generation
- Code splitting
- CSS processing
Key Configuration Options
export default defineConfig({
server: {
port: 5173, // Dev server port
cors: true, // Enable CORS for WordPress
hmr: {
host: 'localhost', // HMR host
protocol: 'ws', // WebSocket protocol
},
},
build: {
manifest: true, // Generate manifest.json
outDir: 'dist', // Output directory
rollupOptions: {
input: {
main: './src/main.tsx', // Entry points
},
},
},
})
TypeScript Support
For TypeScript projects, create a tsconfig.json:
{
"compilerOptions": {
"target": "ES2020",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src"]
}
Troubleshooting
HMR Not Working
-
Check dev server is running:
npm run dev -
Verify dev server URL:
- Default:
http://localhost:5173 - Check console for connection errors
- Default:
-
Check firewall/ports:
- Ensure port 5173 is accessible
- Try accessing
http://localhost:5173in browser
Assets Not Loading in Production
-
Build the project:
npm run build -
Verify manifest.json exists:
ls dist/.vite/manifest.json -
Check file permissions:
chmod -R 755 dist/
React Refresh Not Working
-
Ensure React plugin is installed:
npm install --save-dev @vitejs/plugin-react -
Enable in vite.config.js:
import react from '@vitejs/plugin-react' export default defineConfig({ plugins: [react()], })
CORS Issues
If you see CORS errors in the console:
-
Check Vite config:
server: { cors: true, } -
Verify WordPress headers are being sent (handled by plugin)
Advanced Usage
Custom Dev Server Detection
// Override dev server detection
add_filter('vite_hmr_is_dev', function($is_dev) {
return defined('VITE_DEV_MODE') && VITE_DEV_MODE;
});
Custom Manifest Path
// Use custom manifest location
add_filter('vite_hmr_manifest_path', function($path, $plugin_dir) {
return $plugin_dir . 'build/.vite/manifest.json';
}, 10, 2);
Multiple Vite Projects
// Different dev servers for different plugins
add_action('wp_enqueue_scripts', function() {
// Plugin 1 on port 5173
\ViteHMR\vite_enqueue_asset('plugin1', 'src/main.tsx', [
'dev_server' => 'http://localhost:5173',
'dev_port' => 5173,
]);
// Plugin 2 on port 5174
\ViteHMR\vite_enqueue_asset('plugin2', 'src/main.tsx', [
'dev_server' => 'http://localhost:5174',
'dev_port' => 5174,
]);
});
License
MIT
Credits
Built for WordPress developers who want modern development tools without the hassle.