Gutenberg create-block 完全指南:用 @wordpress/create-block 脚手架一键生成 WordPress 区块插件
【免费下载链接】gutenbergThe Block Editor project for WordPress and beyond. Plugin is available from the official repository.项目地址: https://gitcode.com/GitHub_Trending/gu/gutenberg
导读
@wordpress/create-block(仓库路径 packages/create-block)是 WordPress 官方为 Gutenberg 项目提供的区块脚手架工具:它只用一个命令,就能生成一个完整注册区块的 WordPress 插件,包含 PHP、JS、CSS 代码与无需配置的现代构建环境。本文以该包的官方 README(packages/create-block/README.md)为主线,结合仓库内lib/目录的源码实现,系统讲解快速上手、全部 CLI 选项、交互式模式、生成项目的可用命令,以及外部模板定制机制,帮助你掌握从零生成、个性化定制到分享团队模板的完整能力。
快速开始:一分钟生成第一个区块插件
在满足 Node.js 版本要求的环境下,打开终端依次执行:
$ npx @wordpress/create-block@latest todo-list $ cd todo-list $ npm start命令中的slug(示例里是todo-list)同时决定了三件事:
- 区块的 slug(用于识别与注册);
- 脚手架文件的输出目录(文件夹名);
- WordPress 插件的名称。
生成出的插件需要手动安装到 WordPress 站点中(通过后台「插件 → 安装插件 → 上传插件」上传 zip,或放入wp-content/plugins/目录)。运行前请确保node版本为20.10.0或以上——该版本约束定义在包的engines字段中(见 packages/create-block/package.json)。
值得一提的实现细节:启动时 CLI 会调用 check-system-requirements.js 检测 Node 版本。如果版本不满足,会打印「Minimum system requirements not met!」并询问Are you sure you want to continue anyway?,确认后才继续执行,避免在不兼容环境中生成出无法构建的项目。
slug的来源与命名规则在源码中也有明确约束:交互式模式下输入会被^[a-z][a-z0-9\-]*$正则校验,即只能包含小写字母、数字和连字符,且必须以字母开头(见 packages/create-block/lib/prompts.js)。快速模式下的slug同样会经历toLowerCase()归一化处理(见 scaffold.js)。
基本用法与两种运行模式
create-block的命令行入口(由 lib/index.js 基于commander构建,bin 名为wp-create-block,见 package.json)通用语法为:
$ npx @wordpress/create-block@latest [options] [slug]slug是可选参数,它的有无决定了工具的两种工作模式:
- 提供
slug→ 快速模式(Quick Mode):跳过所有提问,直接按默认值生成,除非用下面的options覆盖默认值。标题会由slug经capitalCase()自动转换得到(源码见 lib/index.js),例如todo-list会得到标题Todo List。 - 不提供
slug→ 交互模式(Interactive Mode):脚本会逐个提示你输入slug、title、namespace等必要信息后再进行生成(详见后文「交互式模式」一节)。
从源码角度理解快速模式,实际上是完成了「默认值 + slug + 显式传入的 options」这三者的合并(lib/index.js),随后直接进入scaffold()生成流程。
两个关键概念:block name 与 namespace
- Block Name是识别区块的唯一字符串,结构为
namespace/slug,其中namespace通常是你的插件名或主题名。 - Namespace默认是
create-block。官方强烈建议你指定自己独有的 namespace,避免与你站点上其他插件冲突:
$ npx @wordpress/create-block@latest my-block --namespace=my-namespace这样生成的 block name 是my-namespace/my-block,而不是create-block/my-block。
如果你已经创建了区块并想改 namespace,需要更新block.json中的name属性。源码中 init-block.js 正是把namespace + '/' + slug写入block.json的name字段,而namespace默认值create-block定义在 templates.js 的getDefaultValues()中。
实践建议:官方文档推荐把区块与插件(而非主题)搭配使用——只有插件才能保证更换主题后区块依然可用。
全部 CLI 选项详解
运行npx @wordpress/create-block@latest --help可以查看完整的参数列表:
-V, --version output the version number -t, --template <name> project template type name; allowed values: "standard" (default), "es5", the name of an external npm package, or the path to a local directory --variant choose a block variant as defined by the template --no-plugin scaffold block files only --target-dir <directory> the directory where the files will be scaffolded, defaults to the slug --namespace <value> internal namespace for the block name --title <value> display title for the block and the WordPress plugin --short-description <value> short description for the block and the WordPress plugin --category <name> category name for the block --wp-scripts enable integration with `@wordpress/scripts` package --no-wp-scripts disable integration with `@wordpress/scripts` package --wp-env enable integration with `@wordpress/env` package --textdomain <value> text domain for internationalization -h, --help output usage information这些选项在 lib/index.js 中逐一注册,其中几个值得深入展开。
--template:指定项目模板
默认模板是standard,此外还内置了es5模板。你也可以指向一个外部 npm 包或本地目录作为模板:
$ npx @wordpress/create-block@latest --template my-template-package $ npx @wordpress/create-block@latest --template ./path/to/template-directory从源码看,模板解析逻辑在 templates.js 的getProjectTemplate()中:先查内置模板表(standard、es5,定义于同文件 [L14-L70]),再检查本地路径是否可解析,最后尝试用npm view探测 npm 包是否存在,若都不命中则抛出Invalid plugin template type name错误。对于外部 npm 模板,工具会先下载到临时目录、require其配置文件后立即清理临时目录。
--variant:模板变体(动态块 / 静态块)
内置的standard与es5模板都提供了static(静态块)和dynamic(动态块)两种变体:
$ npx @wordpress/create-block@latest --variant dynamic- 静态块:编辑与前台渲染均由 JS 完成(
save.js返回的 HTML 直接存入数据库); - 动态块:前台输出由服务端 PHP 模板(
render.php)渲染,更加灵活。
变体机制在源码中有两层体现:其一,standard/es5模板在variants字段中定义了static与dynamic两组覆盖值——dynamic变体额外引入了render: 'file:./render.php',并把默认 slug 改为example-dynamic(templates.js);其二,scaffold会为每个变体生成{{isStaticVariant}}、{{isDynamicVariant}}这类 Mustache 布尔变量(templates.js),模板文件据此做条件渲染——例如标准块入口模板 index.js.mustache 中,save只在isStaticVariant时导入并传给registerBlockType。
如果你指定的--variant名称在所选模板中不存在,CLI 会直接报错并列出可用变体(lib/index.js)。
--no-plugin:纯区块模式
只把区块文件生成到当前目录,不生成插件外壳:
$ npx @wordpress/create-block@latest --no-plugin适用场景是为已有插件添加新区块。源码中,--no-plugin会把plugin置为false,此时生成流程跳过$slug.php插件主文件、package.json等插件级文件(见 scaffold.js),block.json直接生成在根目录而非src/$slug子目录(init-block.js)。需要注意的是,--no-plugin依赖模板提供blockTemplatesPath属性,若自定义模板没有该属性,CLI 会提示No block files found in the template并中止(scaffold.js)。
--wp-env:一键搭建本地 WordPress 环境
$ npx @wordpress/create-block@latest --wp-env该选项会在生成的插件中加入@wordpress/env的配置与脚本,让你能通过 Docker 快速搭建本地 WordPress 环境来构建和测试插件。从源码看,init-wp-env.js 会执行npm install @wordpress/env --save-dev,并写入一份.wp-env.json:
{ "core": "WordPress/WordPress", "plugins": [ "." ] }生成完成后,在插件目录运行npm run env start即可启动 WordPress 环境。
--textdomain:国际化文本域
$ npx @wordpress/create-block@latest --textdomain my-custom-domain指定翻译文本域;不指定时,默认使用区块的slug作为 textdomain(这一默认逻辑在 scaffold.js 中实现:textdomain: textdomain || slug)。
--help:查看帮助
$ npx @wordpress/create-block@latest --help除了列出全部选项外,还会在末尾展示几个示例命令(源码见 lib/index.js):
$ wp-create-block $ wp-create-block todo-list $ wp-create-block todo-list --template es5 --title "TODO List" $ wp-create-block todo-list --no-plugin --textdomain=my-plugin交互式模式:逐步引导配置
不提供slug时,工具进入交互模式,依次向你提问slug、namespace、title、description、dashicon、category,以及(未传入textdomain时)textdomain;之后还会询问是否自定义 WordPress 插件信息(pluginURI、version、author、license、licenseURI、domainPath、updateURI),见 lib/index.js。
每个提问都带有输入校验与默认值(定义于 prompts.js):
| 提示项 | 类型 | 校验/说明 |
|---|---|---|
slug | input | 小写字母、数字、连字符,以字母开头 |
namespace | input | 同样限定小写字母/数字/连字符 |
title | input | 自动首字母大写 |
description | input | 可选,自动首字母大写 |
dashicon | input | 可选,自动去除dashicons-前缀 |
category | select | 从text、media、design、widgets、theme、embed中选择 |
textdomain | input | 可选,格式同 slug |
pluginURI | input | 可选,插件主页 URL |
version | input | 使用 SemVer 正则校验版本号 |
author/license/licenseURI/domainPath/updateURI | input | 可选插件头信息 |
生成项目的内部结构与可用命令
生成的插件目录本身就是一个「零配置」的 Node 包,带有现代化的构建环境。你无需自行安装或配置 webpack、Babel、ESLint——它们都已预配置并被隐藏,让你专注于写代码。
生成流程与产物
scaffold()是生成流程的核心(scaffold.js),执行顺序如下:
- 归一化
slug与namespace,计算rootDirectory(默认process.cwd()/slug,可用--target-dir覆盖); - 应用模板的
transformer(默认恒等函数),把namespaceSnakeCase、slugPascalCase等派生变量注入视图; - 渲染并写出插件级模板文件(
$slug.php、readme.txt); - 复制模板的静态资源;
- 渲染区块级模板(
edit.js、save.js、index.js、style.scss、editor.scss、view.js、render.php等,见 lib/templates/block),并生成block.json; - 若启用
wpScripts:生成package.json、安装@wordpress/scripts并执行npm run format与npm run build(见 init-wp-scripts.js)——这解释了为什么生成过程会花上几分钟; - 若启用
wpEnv:安装@wordpress/env并写入.wp-env.json。
生成的block.json(由 init-block.js 写出)包含了$schema、apiVersion(当前仓库默认3,见 templates.js)、name、version、title、category、icon、description、textdomain、editorScript、style等字段,name为namespace/slug拼接而成。
插件主文件 templates/plugin/$slug.php.mustache 展示了有趣的分支逻辑:当启用wp-scripts时使用 WordPress 6.8 引入的新 APIwp_register_block_types_from_metadata_collection()结合blocks-manifest.php批量注册区块;未启用时则退回经典的register_block_type( __DIR__ . '/build/' . $slug )。
可用 npm scripts
生成目录内提供了一系列由@wordpress/scripts提供的命令,常用的有:
| 命令 | 作用 |
|---|---|
npm start | 启动开发模式构建(watch) |
npm run build | 生产环境构建 |
npm run format | 格式化代码 |
npm run lint:css | 检查 CSS 文件 |
npm run lint:js | 检查 JS 文件 |
npm run plugin-zip | 打包 WordPress 插件 zip 文件 |
npm run packages-update | 将 WordPress 相关包更新到最新版本 |
npm run env start | (启用--wp-env时)启动本地 WordPress 环境 |
这些脚本在 init-package-json.js 中写入package.json。注意:若使用dynamic变体,start与build脚本会追加--webpack-copy-php与--blocks-manifest参数,以确保render.php被复制到构建产物并生成 blocks manifest。
init-package-json.js还负责处理模板声明的npmDependencies/npmDevDependencies(通过npm-package-arg校验包类型后写入依赖,并在wpScripts开启时自动执行npm install),以及customScripts/customPackageJSON的合并。
外部项目模板:把配置沉淀为可复用包
如果你希望分享团队的项目配置,可以将模板发布为 npm 包,或放在本地目录中。外部模板用.mustache文件替换工具默认的插件/区块模板,并可以覆盖脚手架过程中的默认配置值。配置细节参见仓库内 packages/create-block/docs/external-template.md。
模板包必须在入口文件(默认为index.js)导出一个配置对象,以下是可配置字段。
模板路径类字段
pluginTemplatesPath:覆盖插件外壳相关模板,指向存放.mustache文件的目录(支持嵌套目录)。不设置时使用工具内置模板。
const { join } = require( 'path' ); module.exports = { pluginTemplatesPath: join( __dirname, 'plugin-templates' ), };blockTemplatesPath:覆盖单个区块相关模板,同样指向含.mustache文件的目录。不设置时使用内置模板。这是--no-plugin模式能够工作的前提。
module.exports = { blockTemplatesPath: join( __dirname, 'block-templates' ), };assetsPath:当模板要携带图片、字体等不应被构建处理的静态资源时使用。该目录下的文件会被复制到生成插件的assets子目录。
module.exports = { assetsPath: join( __dirname, 'plugin-assets' ), };defaultValues:覆盖默认配置
module.exports = { defaultValues: { slug: 'my-fantastic-block', title: 'My fantastic block', dashicon: 'palmtree', version: '1.2.3', }, };可用于模板的完整变量清单如下(与内置getDefaultValues()的取值相互印证,见 templates.js):
项目级配置
| 变量 | 默认值 | 说明 |
|---|---|---|
wpScripts | true | 是否集成@wordpress/scripts并写入常用 scripts |
wpEnv | false | 是否集成@wordpress/env并写入envscript |
customScripts | {} | 追加到package.json的自定义脚本,可覆盖默认脚本 |
npmDependencies | [] | 启用wpScripts时随npm install安装的依赖 |
npmDevDependencies | [] | 以--save-dev安装的开发依赖 |
customPackageJSON | 无 | 向生成的package.json追加任意属性 |
插件头与 readme 字段
| 变量 | 默认值 | 说明 |
|---|---|---|
pluginURI | 无 | 插件主页 |
version | 0.1.0 | 插件版本号 |
requiresAtLeast | 6.8 | 兼容的最低 WordPress 版本 |
requiresPHP | 7.4 | 最低 PHP 版本 |
testedUpTo | 6.8 | 已测试的最高 WordPress 版本 |
author | The WordPress Contributors | 作者名 |
license | GPL-2.0-or-later | 许可证短名 |
licenseURI | https://www.gnu.org/licenses/gpl-2.0.html | 许可证全文链接 |
domainPath | 无 | 翻译的自定义域路径 |
updateURI | 无 | 自定义更新 URI |
区块元数据字段
| 变量 | 默认值 | 说明 |
|---|---|---|
folderName | src | block.json与其他区块文件的位置(standard 模板下为./src/$slug) |
$schema | https://schemas.wp.org/trunk/block.json | block.json 校验 schema |
apiVersion | 3(当前仓库源码值) | 区块 API 版本 |
slug | 无 | 区块 slug |
namespace | create-block | 区块名命名空间 |
title | 无 | 区块显示标题 |
description | 无 | 区块简介 |
dashicon | 无 | 区块图标 |
category | widgets | 区块分类(text/media/design/widgets/theme/embed) |
textdomain | 默认为slug | 翻译文本域 |
attributes | 无 | 区块属性 |
supports | 无 | 区块扩展支持特性 |
editorScript | file:./index.js | 编辑器脚本 |
editorStyle | file:./index.css | 编辑器样式 |
style | file:./style-index.css | 前台与编辑器共用样式 |
render | 无 | 服务端渲染 PHP 文件路径(动态块) |
customBlockJSON | 无 | 追加到block.json的任意属性 |
transformer | ( view ) => view | 接收全部生成变量的函数,可改值、加变量 |
transformer的两个典型用法:给slug追加随机后缀;或新增一个可在.mustache模板中以{{customVariable}}使用的自定义变量:
transformer: ( view ) => { const hex = getRandomHexCode(); return { ...view, slug: `${ view.slug }-${ hex }`, }; },transformer: ( view ) => { return { ...view, customVariable: `Custom Value`, }; },variants:为模板定义变体
变体可以覆盖任何defaultValues,通过--variant旗标访问:
module.exports = { defaultValues: { slug: 'my-fantastic-block', title: 'My fantastic block', dashicon: 'palmtree', version: '1.2.3', }, variants: { primary: {}, secondary: { title: 'My fantastic block - secondary variant', }, }, };规则要点:
- 通过
--variant secondary选择变体;未指定时若模板定义了变体,默认使用第一个; - 每个变体会自动生成
{{isVARIANT_NAMEVariant}}形式的 Mustache 布尔变量,用于条件输出内容:
{{#isPrimaryVariant}} This content is only rendered if `--variant primary` is passed. {{/isPrimaryVariant}} {{#isSecondaryVariant}} This content is only rendered if `--variant secondary` is passed. {{/isSecondaryVariant}}- 变体也可以定义自己的
pluginTemplatesPath、blockTemplatesPath或assetsPath来覆盖主模板的路径;如果某个变体不需要模板中的某些文件,把对应字段设为null即可跳过:
module.exports = { defaultValues: { slug: 'my-fantastic-block', title: 'My fantastic block' }, variants: { primary: {}, secondary: { blockTemplatesPath: join( __dirname, 'custom-path', 'block-templates' ), assetsPath: null, // 即使主模板定义了资源,也不生成任何资源文件 }, }, };提示:官方对内置
--variant dynamic的说明是「基于内置模板生成动态块」,而模板作者定义的任意变体则通过上述variants机制接入,二者共用同一套渲染管线。
总结:从脚手架到自定义模板的完整路径
create-block的价值在于把「从零手写 WordPress 区块插件」的重复劳动压缩成一个命令:快速模式下slug驱动一切,交互模式提供完整引导,--template/--variant/--no-plugin/--wp-env等选项覆盖了从「纯静态块」「动态块」「为现有插件追加区块」到「一键 Docker 环境」的常见开发场景;而外部模板机制(pluginTemplatesPath、blockTemplatesPath、assetsPath、defaultValues、variants、transformer)则把团队的工程规范沉淀为可复用、可发布的 npm 包。
若想进一步研究源码,建议按以下顺序阅读:
- CLI 入口与选项注册:packages/create-block/lib/index.js
- 模板解析与默认值:packages/create-block/lib/templates.js
- 生成流程编排:packages/create-block/lib/scaffold.js
- 内置插件模板:packages/create-block/lib/templates/plugin/$slug.php.mustache
- 内置区块模板:packages/create-block/lib/templates/block
- 外部模板配置手册:packages/create-block/docs/external-template.md
【免费下载链接】gutenbergThe Block Editor project for WordPress and beyond. Plugin is available from the official repository.项目地址: https://gitcode.com/GitHub_Trending/gu/gutenberg
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考