Here is my vite config.
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from "vite"
import laravel from "laravel-vite-plugin"
import { wordpressPlugin } from '@roots/vite-plugin'
export default defineConfig({
base: "/wp-content/plugins/blocks/public/build",
plugins: [
laravel({
input: [
"src/blocks.ts",
],
refresh: true,
}),
wordpressPlugin()
],
publicDir: "public/build",
build: {
sourcemap: true,
assetsInlineLimit: 0,
rollupOptions: {
external: [/^@wordpress\//],
onwarn(warning, warn) {
if (warning.message.includes('.svg')) return
warn(warning)
},
},
},
server: {
host: true,
https: {
key: "./ssl/localhost.key",
cert: "./ssl/localhost.crt",
},
hmr: {
host: "localhost",
},
},
resolve: {
alias: {
"@src": fileURLToPath(new URL('./src', import.meta.url)),
'@lib': fileURLToPath(new URL('./src/lib', import.meta.url)),
'@store': fileURLToPath(new URL('./src/store', import.meta.url)),
'@t': fileURLToPath(new URL('./src/types', import.meta.url)),
},
},
})
I use similar action like you use in sage
theme to load asset from for dev server, I can compile basic “Hello World” with my setup using hooks from @wordpress/element and it does work without errors.
add_filter('admin_head', function () {
if (! get_current_screen()?->is_block_editor()) {
return;
}
$hotFilePath = __DIR__ . '/public/hot';
Vite::useBuildDirectory('../../../plugins/blocks/public/build');
if (file_exists($hotFilePath)) {
Vite::useHotFile($hotFilePath);
}
$dependencies = json_decode(Vite::content('editor.deps.json'));
foreach ($dependencies as $dependency) {
if (! wp_script_is($dependency, 'enqueued')) {
wp_enqueue_script($dependency);
}
}
$html = Vite::withEntryPoints([
'src/blocks.ts',
])->toHtml();
echo $html;
});
here is what I use in my edit
function which causes an error.
import { create } from 'zustand'
interface PanelBodies {
options: boolean
layout: boolean
dimensions: boolean
borderRadius: boolean
backgroundMedia: boolean
margin: boolean
padding: boolean
}
interface GlobalState {
breakpoint: Breakpoint
viewportLocked: boolean
panelBodies: PanelBodies
setDeviceBreakpoint: (breakpoint: Breakpoint) => void
setViewportLocked: (locked: boolean) => void
setPanelBodies: (panelBody: keyof PanelBodies, value: boolean) => void
}
export const useGlobalStore = create<GlobalState>((set) => ({
panelBodies: {
options: true,
layout: false,
dimensions: false,
borderRadius: false,
backgroundMedia: false,
margin: false,
padding: false,
},
setPanelBodies: (panelBody, value) => {
set((state) => ({
panelBodies: {
...state.panelBodies,
[panelBody]: value,
},
}))
},
breakpoint: 'sm',
viewportLocked: true,
setDeviceBreakpoint: (breakpoint: Breakpoint) =>
set(() => ({ breakpoint })),
setViewportLocked: (locked: boolean) =>
set(() => ({ viewportLocked: locked })),
}))
export default useGlobalStore
import useGlobalStore from "@src/store"
const {
panelBodies,
setPanelBodies,
breakpoint: currentBreakpoint,
} = useGlobalStore()
load-scripts.php?c=0&load%5Bchunk_0%5D=jquery-core,jquery-migrate,utils,wp-dom-ready,wp-hooks&ver=6.8.1:5 JQMIGRATE: Migrate is installed, version 3.4.1
@wordpress_icons.js?v=f42ce3a1:21613 Download the React DevTools for a better development experience: https://reactjs.org/link/react-devtools
effects.ts:4 Warning: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
printWarning @ chunk-CANBAPAS.js?v=f42ce3a1:136
error @ chunk-CANBAPAS.js?v=f42ce3a1:120
resolveDispatcher @ chunk-CANBAPAS.js?v=f42ce3a1:1045
useEffect @ chunk-CANBAPAS.js?v=f42ce3a1:1077
useSetBlockIdEffect @ effects.ts:4
edit @ ContainerEdit.tsx:83
ht @ react-dom.min.js?ver=18.3.1.1:10
Qs @ react-dom.min.js?ver=18.3.1.1:10
wl @ react-dom.min.js?ver=18.3.1.1:10
bl @ react-dom.min.js?ver=18.3.1.1:10
yl @ react-dom.min.js?ver=18.3.1.1:10
fl @ react-dom.min.js?ver=18.3.1.1:10
Nn @ react-dom.min.js?ver=18.3.1.1:10
(anonymous) @ react-dom.min.js?ver=18.3.1.1:10
effects.ts:4 Warning: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
printWarning @ chunk-CANBAPAS.js?v=f42ce3a1:136
error @ chunk-CANBAPAS.js?v=f42ce3a1:120
resolveDispatcher @ chunk-CANBAPAS.js?v=f42ce3a1:1045
useEffect @ chunk-CANBAPAS.js?v=f42ce3a1:1077
useSetBlockIdEffect @ effects.ts:4
edit @ ContainerEdit.tsx:83
ht @ react-dom.min.js?ver=18.3.1.1:10
Qs @ react-dom.min.js?ver=18.3.1.1:10
wl @ react-dom.min.js?ver=18.3.1.1:10
bl @ react-dom.min.js?ver=18.3.1.1:10
yl @ react-dom.min.js?ver=18.3.1.1:10
il @ react-dom.min.js?ver=18.3.1.1:10
fl @ react-dom.min.js?ver=18.3.1.1:10
Nn @ react-dom.min.js?ver=18.3.1.1:10
(anonymous) @ react-dom.min.js?ver=18.3.1.1:10
react-dom.min.js?ver=18.3.1.1:10 TypeError: Cannot read properties of null (reading 'useEffect')
at useEffect (chunk-CANBAPAS.js?v=f42ce3a1:1078:29)
at useSetBlockIdEffect (effects.ts:4:5)
at edit (ContainerEdit.tsx:83:5)
at ht (react-dom.min.js?ver=18.3.1.1:10:45677)
at Qs (react-dom.min.js?ver=18.3.1.1:10:120133)
at wl (react-dom.min.js?ver=18.3.1.1:10:88341)
at bl (react-dom.min.js?ver=18.3.1.1:10:88269)
at yl (react-dom.min.js?ver=18.3.1.1:10:88132)
at il (react-dom.min.js?ver=18.3.1.1:10:84984)
at fl (react-dom.min.js?ver=18.3.1.1:10:85364)
ar @ react-dom.min.js?ver=18.3.1.1:10
a.componentDidCatch.t.callback @ react-dom.min.js?ver=18.3.1.1:10
at @ react-dom.min.js?ver=18.3.1.1:10
Jr @ react-dom.min.js?ver=18.3.1.1:10
Zr @ react-dom.min.js?ver=18.3.1.1:10
Gr @ react-dom.min.js?ver=18.3.1.1:10
(anonymous) @ react-dom.min.js?ver=18.3.1.1:10
xl @ react-dom.min.js?ver=18.3.1.1:10
fl @ react-dom.min.js?ver=18.3.1.1:10
Nn @ react-dom.min.js?ver=18.3.1.1:10
(anonymous) @ react-dom.min.js?ver=18.3.1.1:10
package.json
{
"name": "modules",
"version": "1.0.0",
"private": true,
"type": "module",
"scripts": {
"prod": "bud clean && bud build",
"dev": "bud clean && bud dev",
"vite": "vite",
"vite-build": "vite build",
"watchTsxFiles": "bun run task.ts",
"clean": "bud clean"
},
"dependencies": {
"fast-average-color": "^9.5.0",
"react-tabs": "^6.1.0",
"zustand": "^5.0.3"
},
"devDependencies": {
"@rollup/plugin-inject": "^5.0.5",
"@roots/bud": "^6.24.0",
"@roots/bud-api": "^6.24.0",
"@roots/bud-build": "^6.24.0",
"@roots/bud-cache": "^6.24.0",
"@roots/bud-client": "^6.24.0",
"@roots/bud-compiler": "^6.24.0",
"@roots/bud-dashboard": "^6.24.0",
"@roots/bud-entrypoints": "^6.24.0",
"@roots/bud-extensions": "^6.24.0",
"@roots/bud-framework": "^6.24.0",
"@roots/bud-hooks": "^6.24.0",
"@roots/bud-minify": "^6.24.0",
"@roots/bud-postcss": "^6.24.0",
"@roots/bud-preset-recommend": "^6.24.0",
"@roots/bud-preset-wordpress": "^6.24.0",
"@roots/bud-react": "^6.24.0",
"@roots/bud-sass": "^6.24.0",
"@roots/bud-server": "^6.24.0",
"@roots/bud-support": "^6.24.0",
"@roots/bud-swc": "^6.24.0",
"@roots/bud-tailwindcss": "^6.24.0",
"@roots/bud-wordpress-dependencies": "^6.24.0",
"@roots/bud-wordpress-externals": "^6.24.0",
"@roots/bud-wordpress-theme-json": "^6.24.0",
"@roots/vite-plugin": "^1.0.4",
"@roots/wordpress-hmr": "^6.24.0",
"@svgr/webpack": "^8.1.0",
"@types/jquery": "^3.5.32",
"@types/lodash": "^4.17.16",
"@types/lodash-es": "^4.17.12",
"@types/node": "^22.14.1",
"@types/react": "^18.3.20",
"@types/react-dom": "^18.3.6",
"@types/wordpress__block-editor": "^11.5.16",
"@types/wordpress__blocks": "^12.5.17",
"@types/wordpress__edit-post": "^8.4.2",
"@wordpress/api-fetch": "^7.22.0",
"@wordpress/block-editor": "^14.17.0",
"@wordpress/core-data": "^7.22.0",
"@wordpress/dom-ready": "^4.22.0",
"@wordpress/element": "^6.22.0",
"@wordpress/icons": "^10.22.0",
"@wordpress/plugins": "^7.22.0",
"add": "^2.0.6",
"autoprefixer": "^10.4.21",
"bun": "^1.2.10",
"chokidar": "^4.0.3",
"classnames": "^2.5.1",
"clsx": "^2.1.1",
"css-minimizer-webpack-plugin": "^7.0.2",
"laravel-vite-plugin": "^1.2.0",
"lodash": "^4.17.21",
"lodash-es": "^4.17.21",
"mysql2": "^3.14.0",
"php-unserialize": "^0.0.1",
"postcss": "^8.5.3",
"postcss-loader": "^8.1.1",
"prettier": "^3.5.3",
"prettier-plugin-tailwindcss": "^0.6.11",
"raw-loader": "^4.0.2",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-number-format": "^5.4.4",
"sass": "^1.86.3",
"sass-loader": "^16.0.5",
"swc-loader": "^0.2.6",
"tailwindcss": "^3.4.17",
"terser-webpack-plugin": "^5.3.14",
"typescript": "^5.8.3",
"vite": "^6.3.5",
"workbox-precaching": "^7.3.0"
},
"volta": {
"node": "22.12.0"
}
}