开发的区块越多,我就越希望插件的结构不要成为阻碍。我不想每添加一个新功能,都重新思考目录结构、改写同样的注册逻辑,或者与构建流程较劲。
在如何构建多区块插件一文中,我介绍了在一个插件中管理多个区块的简单基础方案。那篇指南着重讲解文件组织、区块注册以及快速让插件运转起来等核心概念;它采用将所有内容打包为单个文件的构建策略。这种方式适合通过CDN分发,却没有体现WordPress中单个区块理想的加载方式。
本文在上述方案的基础上,结合实际使用经验与反馈,将其改进为更强大的结构。我会介绍如何创建可扩展的配置,支持静态区块、动态区块和交互式区块,分离全局资源,兼顾编码规范,并通过模块化结构让插件不断增长时仍然易于管理。
前置条件
本文假定你已有运行WordPress的本地开发环境,可以使用WordPress Studio、wp-env,也可以使用官方WordPress镜像创建自定义Docker容器。
使用@wordpress/create-block还需要较新的Node.js和npm。
查看所需版本:
npm view @wordpress/create-block engines
检查当前环境:
node -v
npm -v
如果系统版本低于要求,可以使用nvm更新:
nvm install 20
nvm use 20
这样可确保兼容性,避免后续构建出现问题。
如果希望跟着操作,或参考可工作的示例,本文构建的完整插件已发布到GitHub,文章各节都有对应分支。
插件基础配置
首先,我会生成一个新插件,再调整其结构,以清晰、有序的方式支持多个区块。我会通过@wordpress/create-block添加一个静态区块和一个动态区块,各自放在独立目录中。我还会更新注册函数,让它自动发现新增区块:不必逐个手动注册,只需将区块放入正确的目录。
创建插件基础结构
第一步是在本地WordPress环境的plugins目录中运行npx @wordpress/create-block@latest advanced-multi-block,生成新插件。此时得到的是包含单个静态区块的插件。
调整插件结构
接下来,我会快速重构默认结构,使多区块插件组织清晰,并能随项目一起扩展。
我把区块移到顶层的src/blocks目录,而不再将它们嵌套在单个文件夹内。这既便于查看区块结构,也为后续扩展留出空间。以后添加全局JavaScript或编辑器样式等其他全局资源时,从一开始就明确分离各部分,有助于保持结构整洁、易于维护。
在src目录中做以下调整:
- 删除
src/advanced-multi-block文件夹。 - 在
src内创建名为blocks的文件夹。
创建静态区块和动态区块
现在目录结构已清晰有序,可以开始添加区块。我使用@wordpress/create-block配合--no-plugin参数,在现有目录布局中生成各个区块,而不是创建独立的新插件。
根据区块类型,还会添加--variant参数。为保持国际化设置一致,我指定相同的--textdomain。
在src/blocks目录中运行以下命令,分别创建一个静态区块和一个动态区块:
// Create a static block
npx @wordpress/create-block@latest slider --textdomain advanced-multi-block --no-plugin
// Create a dynamic block
npx @wordpress/create-block@latest banner --textdomain advanced-multi-block --no-plugin --variant dynamic
更新区块注册函数
@wordpress/create-block生成的函数已经为注册多个区块提供了可靠基础。该函数名为create_block_advanced_multi_block_block_init,我会为了清晰而重命名它。为了适配所有区块均放在src/blocks下的新结构,只需做很小的改动:在三个位置更新区块路径,加入新的目录层级。
以下是采用更短名称后的函数:
function register_blocks() {
$build_dir = __DIR__ . '/build/blocks';
$manifest = __DIR__ . '/build/blocks-manifest.php';
// WP 6.8+: one-call convenience.
if ( function_exists( 'wp_register_block_types_from_metadata_collection' ) ) {
wp_register_block_types_from_metadata_collection( $build_dir, $manifest );
return;
}
// WP 6.7: index the collection, then loop and register each block from metadata.
if ( function_exists( 'wp_register_block_metadata_collection' ) ) {
wp_register_block_metadata_collection( $build_dir, $manifest );
$manifest_data = require $manifest;
foreach ( array_keys( $manifest_data ) as $block_type ) {
register_block_type_from_metadata( $build_dir . '/' . $block_type );
}
return;
}
// WP 5.5-6.6: no collection APIs; just loop the manifest directly.
if ( function_exists( 'register_block_type_from_metadata' ) ) {
$manifest_data = require $manifest;
foreach ( array_keys( $manifest_data ) as $block_type ) {
register_block_type_from_metadata( $build_dir . '/' . $block_type );
}
return;
}
}
add_action( 'init', 'register_blocks' );
采用这一结构后,可以在src/blocks中运行npx create-block命令添加新区块。清单文件会自动处理注册,不必再更新注册逻辑。
测试基础配置
一切就绪后,我运行npm run build。
构建完成后,便能在区块插入器的“小工具”(Widgets)分组中找到Slider和Banner区块。

添加交互式区块
添加静态区块和动态区块后,下一步是加入交互式区块。交互式区块的构建方式略有不同,需要对注册函数和构建流程做一些调整才能正常工作。
创建交互式区块
与动态区块不同,交互式区块不使用--variant参数,而是使用--template选项指向WordPress提供的起始模板。这样会生成客户端交互式区块所需的文件。
在src/blocks中运行:
// Create an interactive block
npx @wordpress/create-block@latest toggle --textdomain advanced-multi-block --template @wordpress/create-block-interactive-template --no-plugin
修改构建流程
交互式区块还需要对构建配置做一个小改动。我在package.json中的build和start命令里加入--experimental-modules参数,确保脚本能够正确编译:
// Updated build command
"build": "wp-scripts build --experimental-modules --blocks-manifest"
// Updated start command
"start": "wp-scripts start --experimental-modules --blocks-manifest"
测试三种区块类型
三种区块都就绪后,我运行npm run build。
构建完成后,便能在区块插入器的“小工具”(Widgets)分组中看到Slider、Banner和Toggle区块。

加载额外资源
这个插件不只是注册区块。区块编辑器提供了很大的灵活性,我经常希望加入超越单个区块的增强功能,例如注册区块变体、定义样式选项,或者为编辑器添加与当前上下文相关的工具。
我编译两个独立脚本:一个用于编辑器,另一个用于前端。它们放在各区块目录之外,为跨多个区块的功能提供集中管理方式。每个脚本都有配套的.asset.php文件,在构建时自动处理依赖与版本。
添加资源加载类
为了注册这些共享资源,我为每个脚本创建一个简单的加载函数,分别用于区块编辑器与前端。这些函数独立于区块注册逻辑,有助于在插件持续演进时维持模块化结构。
我将它们放在functions.php文件中,位于区块注册函数之后:
/**
* Enqueues the block assets for the editor
*/
function enqueue_block_assets() {
$asset_file = include plugin_dir_path( __FILE__ ) . 'build/editor-script.asset.php';
wp_enqueue_script(
'editor-script-js',
plugin_dir_url( __FILE__ ) . 'build/editor-script.js',
$asset_file['dependencies'],
$asset_file['version'],
false
);
}
add_action( 'enqueue_block_editor_assets', 'enqueue_block_assets' );
/**
* Enqueues the block assets for the frontend
*/
function enqueue_frontend_assets() {
$asset_file = include plugin_dir_path( __FILE__ ) . 'build/frontend-script.asset.php';
wp_enqueue_script(
'frontend-script-js',
plugin_dir_url( __FILE__ ) . 'build/frontend-script.js',
$asset_file['dependencies'],
$asset_file['version'],
true
);
}
add_action( 'wp_enqueue_scripts', 'enqueue_frontend_assets' );
添加脚本资源
编辑器脚本
我在src目录中创建名为editor-script.js的文件。区块编辑器启用时,该文件会被编译并加载到编辑器中。
/**
* Block Editor Script Functionality
*
* The following scripts are compiled into a single asset and loaded into the block editor.
*
*/
// import editor scripts here.
前端脚本
我还在src目录中创建名为frontend-script.js的文件,用于前端专属行为。显示需要这些行为的区块或页面时,该文件会被编译并在前端加载。
/**
* Frontend Script Functionality
*
* The following scripts are compiled into a single asset and loaded into the frontend.
*
*/
// import frontend scripts here.
添加Webpack配置文件
为了独立于核心区块构建流程编译全局脚本,我在插件根目录创建自定义Webpack配置文件webpack.config.js。这样可以复用并扩展@wordpress/scripts提供的默认配置,而不干扰WordPress构建交互式区块的方式。
文件内容如下:
const [ scriptConfig, moduleConfig, ] = require('@wordpress/scripts/config/webpack.config');
const path = require('path');
module.exports = [
{
...scriptConfig,
entry: {
...scriptConfig.entry(),
'editor-script': path.resolve(__dirname, 'src/editor-script.js'),
'frontend-script': path.resolve(__dirname, 'src/frontend-script.js'),
},
},
moduleConfig,
];
这个文件导出一个包含两份配置的数组:
- 第一份配置
scriptConfig是WordPress用于传统(非交互式)脚本的标准Webpack配置。这里添加两个新入口来扩展它:一个用于编辑器端JavaScript,另一个用于前端行为。这些脚本会编译到build目录,文件名固定可预测。 - 第二份配置
moduleConfig用于支持ES模块输出。使用--experimental-modules参数构建交互式区块时,WordPress会使用这种输出。虽然当前文件主要处理非交互式资源,但包含这份配置可确保兼容现代模块系统。
扩展默认Webpack配置并加入编辑器和前端脚本后,就能在单次流程中同时构建全局资源与区块。这样既保留了模块化组织,也通过moduleConfig确保与WordPress交互式区块系统兼容。
结语
构建多区块插件不意味着每次都要从零开始。通过改进默认结构、简化注册,并支持不同区块类型和共享资源,可以创建随需求扩展的配置,无论开发的是一个区块还是二十个区块。
这种方法来自实际使用、迭代与社区反馈。它足够灵活,可以支持自定义工作流;也足够强大,能让不断增长的插件保持井然有序。
如果你有问题、想法或改进建议,我很乐意听到。开源工作的美妙之处就在于,我们都在彼此的成果之上继续构建。
感谢@meszarosrob和@milana_cap审阅本文并提供反馈。
原文:Refactoring the multi-block plugin: Build smarter, register cleaner, scale easier,Troy Chaplin,2025年8月27日,WordPress Developer Blog。按转载授权汉化。截图来自原文;示例插件仓库声明采用GPL-2.0-or-later许可证。文中的执行与构建结果为原作者叙述。











暂无评论内容