A WordPress block plugin that demonstrates how to use Script Modules (ES modules via wp_register_script_module) with a custom Webpack configuration and the WordPress Interactivity API.
- Registering external ES modules with
wp_register_script_module()and consuming them via cleanimportstatements (powered by import maps) - Static imports (preloaded via
<link rel="modulepreload">) vs dynamicimport()(loaded on demand) - Using
@wordpress/interactivitystore, state, and actions inside aviewScriptModule - Custom Webpack config that extends
@wordpress/scriptsto support module output andrequestToExternalModulein the dependency extraction plugin - Loading third-party ESM libraries from CDN (
https://esm.run/lodash-es/*) - Fetching WordPress REST API data from a script module using
wp-api-fetch
plugin.php # Registers the block and script modules
webpack.config.js # Custom Webpack config (module output + external modules)
src/
block.json # Block metadata (viewScriptModule: file:./view.js)
index.js # Editor entry point
edit.js # Editor component
save.js # Save component
view.js # Frontend view script module (Interactivity API store)
render.php # Server-side block render
assets/js/
module1.js # Static import example
module2.js # Dynamic import (setTimeout)
module3.js # Dynamic import (on user click)
fetchPosts.js # REST API fetch module
build/ # Compiled output
- WordPress 6.7+
- PHP 7.4+
- Node.js (for building)
npm install
npm run build # Production build
npm run start # Development build with watchCopy the plugin folder into wp-content/plugins/ and activate it. Add the Script Modules View block to any post or page.
Modules are registered in plugin.php using wp_register_script_module(). WordPress generates an import map so the browser can resolve bare specifiers like "module-1" to actual URLs.
The custom webpack.config.js extends the default @wordpress/scripts config to:
- Enable ES module output (
output.module: true,experiments.outputModule: true) - Map registered modules as externals via
requestToExternalModuleinDependencyExtractionWebpackPlugin
| Import type | Example | Behavior |
|---|---|---|
| Static | import { moduleOne } from "module-1" |
Preloaded, available immediately |
| Dynamic | await import("module-3") |
Loaded on demand when the action fires |
| Unregistered URL | import("https://esm.run/lodash-es/camelCase") |
Inlined as a static import by the build |
GPL-2.0-or-later