This package gives you a fast, modern front‑end build for a WordPress theme using Vite.
It keeps the theme root clean by placing configs in /vite, emits hashed assets for cache busting, and supports Sass, Autoprefixer, ESLint, Stylelint, and image compression on production builds.
- Vite dev server
- Instant CSS/SCSS HMR (no PHP reload wired by default)
- Sourcemaps in development
- Sass (
sass/ Dart Sass) compiled with@use/@import - PostCSS with Autoprefixer (targets come from
browserslistinpackage.json) - Stylelint with
stylelint-config-standard-scss
- ES modules with Rollup under the hood
- Entry points for
frontendandbackend - ESLint with a simple recommended config
- Fonts and images are emitted with hashed filenames
assets/public/manifest.jsonmaps logical entries to the hashed files- Image compression via
vite-plugin-imageminon production:- JPEG (mozjpeg ~75 quality, progressive)
- PNG (pngquant ~70–85 quality)
- GIF (gifsicle, interlaced)
- SVG (SVGO safe defaults, keeps viewBox)
- WebP (~75 quality)
/vite
vite.config.ts
postcss.config.cjs
.eslintrc.cjs
stylelint.config.cjs
/assets
/src
/js
frontend.js # imports ../sass/frontend.scss
backend.js # imports ../sass/backend.scss
/sass
frontend.scss
backend.scss
/images # source images
/fonts # source fonts
/public # build output (hashed files + manifest.json)
package.json
README.md
npm run dev # Vite dev server with CSS/SCSS HMR
npm run build # Production build to assets/public (hashed assets + manifest.json)
npm run preview # Preview the production build locally
npm run lint # ESLint + Stylelint
npm run lint:fix # Auto-fix where possibleOn npm run build, Vite writes assets/public/manifest.json. Use it to enqueue the right hashed CSS/JS for your entries.
Minimal approach in PHP:
$manifest = json_decode( file_get_contents( get_theme_file_path( 'assets/public/manifest.json' ) ), true );
$entries = [
'frontend' => 'assets/src/js/frontend.js',
'backend' => 'assets/src/js/backend.js',
];
foreach ( $entries as $handle => $source ) {
if ( empty( $manifest[ $source ] ) ) continue;
$entry = $manifest[ $source ];
if ( ! empty( $entry['file'] ) ) {
wp_enqueue_script( "brevity-$handle", get_theme_file_uri( 'assets/public/' . $entry['file'] ), [], null, true );
}
if ( ! empty( $entry['css'] ) ) {
foreach ( $entry['css'] as $i => $css_file ) {
wp_enqueue_style( "brevity-$handle" . ( $i ? "-$i" : '' ), get_theme_file_uri( 'assets/public/' . $css_file ), [], null );
}
}
}If you prefer a tidy helper, drop inc/enqueue.php into your theme and require it from functions.php.
- Configs under
/vite: scripts inpackage.jsoncall Vite with--config vite/vite.config.ts. PostCSS path is set to./vite/postcss.config.cjs. Linters use configs in/viteas well. - Image quality: tweak the
vite-plugin-imageminoptions invite/vite.config.ts. - Adding entries: add to
rollupOptions.inputinvite.config.tsand create the matchingassets/src/js/*.jsfile. - Browser targets: edit
browserslistinpackage.json. Autoprefixer reads from there. - Optional extras:
- PHP template reloads: add
vite-plugin-full-reloadand watch**/*.php. - TypeScript: rename files to
.tsand install the TS ESLint setup if you want TS linting.
- PHP template reloads: add
You get fast startup, instant CSS HMR, simpler config, and smaller dependency surface than a loader-heavy Webpack setup, while keeping the WordPress theme layout you like. This README mirrors the intent of your original Webpack workflow docs but reflects the Vite-based approach and the tools we actually ship here.
- 1.1.0 — Added image compression, tidy
/viteconfigs, manifest enqueue guidance - 1.0.0 — Initial Vite setup (Sass, Autoprefixer, ESLint, Stylelint, CSS HMR)