资讯动态

深入解析 create-block 外部项目模板:用 npm 包或本地目录定制 WordPress 块脚手架

发布时间:2026/9/18 5:26:35 来源:尧图企业网站定制
深入解析 create-block 外部项目模板用 npm 包或本地目录定制 WordPress 块脚手架【免费下载链接】gutenbergThe Block Editor project for WordPress and beyond. Plugin is available from the official repository.项目地址: https://gitcode.com/GitHub_Trending/gu/gutenbergGutenberg 的wordpress/create-block是官方推荐用于快速搭建 WordPress 插件与块项目的脚手架工具而外部项目模板External Project Templates则进一步将其扩展为可复用的工程化能力。通过本文你将掌握如何编写一个返回配置对象的 npm 模板包或本地模板目录用自定义.mustache文件替换工具默认的插件与块文件、覆盖脚手架过程中的全部默认配置值并通过--template与--variant参数实现模板变体variants与条件渲染。文章会结合 Gutenberg 仓库中 create-block 包 的真实源码实现逐项印证配置项行为。外部项目模板解决了什么问题wordpress/create-block默认提供standard与es5两套内置模板其定义可见于 packages/create-block/lib/templates.js可生成一套包含 PHP、JS、CSS 与构建配置的完整插件骨架。但当团队需要统一的命名规范、固定的依赖集合、私有化的插件头信息时重复修改默认输出既不高效也不易维护。外部项目模板允许你将整套脚手架配置发布为npm 包或保存在本地目录中通过--template参数直接引用用自定义的.mustache文件替换默认的插件模板plugin shell与块模板block文件嵌套文件夹同样支持覆盖脚手架过程中的全部默认配置值defaultValues包括插件头、块元数据、npm 依赖、package.json 脚本等通过variants变体在同一套模板中提供多种输出形态并使用--variant参数选择。在命令行中模板的指定方式与内置模板完全一致见 packages/create-block/lib/index.js# 使用发布到 npm 的外部模板包 $ npx wordpress/create-blocklatest --template my-template-package # 使用本地目录作为模板 $ npx wordpress/create-blocklatest --template ./path/to/template-directory模板包的基本结构index.js 是唯一硬性要求外部模板在本质上是一个 CommonJS 模块包或本地目录中必须提供主入口文件默认为index.js该文件导出一个配置对象。脚手架流程只要求这一个文件其余模板文件、资源文件均通过配置对象中的路径字段定位。配置对象支持四个顶层字段pluginTemplatesPath、blockTemplatesPath、assetsPath与defaultValues。从源码看getProjectTemplatepackages/create-block/lib/templates.js解析模板的流程如下若模板名是内置的standard/es5直接读取内置配置否则检查resolve( templateName )指向的本地路径是否存在存在则require该路径再尝试将模板名作为 npm 包require若仍失败则通过npm view校验该包是否存在于 npm registry存在则下载到临时目录mkdtemp创建的wp-create-block-*临时目录执行npm install --no-save加载其index.js后在finally中清理临时目录。这意味着你既可以把index.js作为 npm 包入口发布也可以直接放在某个本地目录中让--template ./some-dir引用。加载到的配置随后由configToTemplate处理递归扫描.mustache文件生成模板映射并据此计算最终输出文件。核心配置项详解pluginTemplatesPath替换插件外壳模板该字段可选指向一个包含.mustache模板文件的目录用于覆盖 WordPress 插件外壳plugin shell即插件主 PHP 文件与 readme 等。目录支持嵌套文件夹。未设置时使用工具内置的插件模板集仓库中位于 packages/create-block/lib/templates/plugin/。const { join } require( path ); module.exports { pluginTemplatesPath: join( __dirname, plugin-templates ), };模板文件名会去掉.mustache后缀后作为输出文件名文件名中的$slug占位符会被替换为实际的块 slug——这一点从 packages/create-block/lib/output.js 的writeOutputTemplate实现可以确认outputFilePath.replace( /\$slug/g, view.slug )。内置的$slug.php.mustache即展示了这一约定其输出即为插件主文件的 PHP 头注释与register_block_type注册逻辑Plugin Name: {{title}} * Version: {{version}} * Text Domain: {{textdomain}}blockTemplatesPath替换单个块的模板该字段可选指向包含块级.mustache文件的目录用于覆盖单个块的模板文件如edit.js、save.js、index.js、样式文件、render.php等。未设置时使用内置块模板集仓库中位于 packages/create-block/lib/templates/block/。const { join } require( path ); module.exports { blockTemplatesPath: join( __dirname, block-templates ), };块模板文件会输出到由folderName配置项指定的目录默认src下即block.json与块级源码的存放位置。需要特别注意--no-plugin模式依赖模板支持blockTemplatesPath属性如果仅传入插件模板而没有块模板脚手架会报错No block files found in the template. Please ensure that the template supports the blockTemplatesPath property.见 packages/create-block/lib/scaffold.js。assetsPath原样拷贝静态资源当模板生成的插件需要使用图片、字体等不应被构建处理的静态资源时用该字段指向资源目录。目录中的文件会被原样拷贝到生成插件的assets子目录下见 packages/create-block/lib/output.js 中writeOutputAsset对view.rootDirectory/assets的写入逻辑不会经过 mustache 渲染。const { join } require( path ); module.exports { assetsPath: join( __dirname, plugin-assets ), };defaultValues覆盖脚手架默认值模板作者可以通过defaultValues修改用户未显式提供时的默认值。用户在交互模式下的每次输入、以及所有命令行选项的优先级都会高于这些默认值。module.exports { defaultValues: { slug: my-fantastic-block, title: My fantastic block, dashicon: palmtree, version: 1.2.3, }, };从 packages/create-block/lib/templates.js 的getDefaultValues可以看到默认值的合并顺序是内置全局默认 → 模板的defaultValues→ 当前 variant 的配置。内置全局默认值与文档所列完全一致$schema为https://schemas.wp.org/trunk/block.json、apiVersion为3当前源码中已升级到 API 3、namespace为create-block、category为widgets、textdomain默认为 slug、version为0.1.0、requiresAtLeast为6.8、requiresPHP为7.4、testedUpTo为6.8、author为The WordPress Contributors、license为GPL-2.0-or-later、licenseURI指向 GNU GPL 2.0 全文、wpScripts为true、wpEnv为false、customScripts为空对象、npmDependencies为空数组、folderName为./src、editorScript为file:./index.js、editorStyle为file:./index.css、style为file:./style-index.css。可覆盖变量全表以下变量可用于模板文件中模板作者可修改默认值以适应用户未提供数据时的场景。项目级Project变量默认值说明wpScriptstrue启用与wordpress/scripts的集成向package.json添加常用脚本wpEnvfalse启用与wordpress/env的集成向package.json添加env脚本customScripts{}要添加到package.json的自定义脚本列表也允许覆盖默认脚本npmDependencies[]wpScripts启用时通过npm install安装的远程 npm 依赖列表npmDevDependencies[]wpScripts启用时通过npm install --save-dev安装的远程 npm 依赖列表customPackageJSON无默认允许为生成的package.json定义额外属性其中npmDependencies与npmDevDependencies的行为在 packages/create-block/lib/init-package-json.js 中有完整实现每个依赖项会经npmPackageArg解析并校验其类型必须为git、tag、version、range、remote或alias之一解析成功后被写入dependencies/devDependencies随后在wpScripts开启时执行一次npm install。customScripts则在脚本合并阶段以展开运算符覆盖同名默认脚本。customPackageJSON会被展开到 package.json 的最外层实现对生成结果的完全定制。插件头与 readme 字段Plugin header and readme fields变量默认值说明pluginURI无默认插件主页version0.1.0插件当前版本号requiresAtLeast6.8插件可工作的最低 WordPress 版本requiresPHP7.4插件所需的最低 PHP 版本testedUpTo6.8插件测试过的最高 WordPress 版本authorThe WordPress Contributors插件作者名licenseGPL-2.0-or-later插件许可证简称licenseURIhttps://www.gnu.org/licenses/gpl-2.0.html许可证全文链接domainPath无默认翻译的自定义域路径updateURI无默认插件的自定义更新 URI块元数据Block metadata变量默认值说明folderNamesrcblock.json及由blockTemplatesPath指定的块模板所生成文件的位置$schemahttps://schemas.wp.org/trunk/block.json用于块校验的 schema URLapiVersion2当前源码为3块 API 版本slug无默认块名称中用于标识的 slugnamespacecreate-block块名称的内部命名空间title无默认块的显示标题description无默认块的简短描述dashicon无默认便于识别块的图标属性categorywidgets块的分类核心分类为text、media、design、widgets、theme、embedtextdomain默认取slug值用于字符串翻译的文本域attributes无默认块属性supports无默认可选的块扩展支持特性editorScriptfile:./index.js编辑器脚本定义editorStylefile:./index.css编辑器样式定义stylefile:./style-index.css前端与编辑器共用的样式定义render无默认服务端渲染块类型时使用的 PHP 文件路径customBlockJSON无默认允许为生成的block.json定义额外属性transformer( view ) view接收 create-block 工具生成的所有变量、返回新值对象的函数可修改既有值并新增变量关于folderName源码中还有一处细节在getDefaultValues中其默认值为./src但在scaffold.js的transformer调用阶段会执行folderName.replace( /\$slug/g, slug )因此模板作者可以在defaultValues中使用$slug占位符实现按 slug 命名的子目录例如内置standard模板使用的folderName: ./src/$slug。transformer与customBlockJSON/customPackageJSON的差异值得强调后两者只能往block.json/package.json中追加静态属性而transformer是一个函数运行时机位于模板渲染之前scaffold.js中先调用transformer( {...} )得到transformedValues再与namespaceSnakeCase、namespacePascalCase、slugSnakeCase、slugPascalCase等派生变量合并成最终的view渲染上下文。它可以读取全部变量、做任意计算并影响模板文件的内容。transformer使用示例为 slug 追加一个动态生成的后缀transformer: ( view ) { const hex getRandomHexCode(); return { ...view, slug: ${ view.slug }-${ hex }, }; },创建可在 mustache 模板中以{{customVariable}}引用的全新自定义变量transformer: ( view ) { return { ...view, customVariable: Custom Value, }; },注意transformer返回的slug会被用于文件夹名、插件名与块标识因此在此处修改 slug 会连锁影响整个脚手架输出。variants一套模板多种形态variants用于为模板创建变体每个变体可以覆盖任意defaultValues。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参数访问例如--variant secondary。如果模板定义了变体而用户未指定则默认使用第一个变体。getDefaultValues中...projectTemplate.variants?.[ variant ]的合并顺序也证实了这一点变体配置的优先级高于模板级defaultValues。变体的用途非常广泛——内置模板本身就是最佳范例standard模板定义了static与dynamic两个变体动态变体通过render: file:./render.php生成服务端渲染块见 packages/create-block/lib/templates.js 中predefinedPluginTemplates的定义。变体条件变量{{isVARIANT_NAMEVariant}}对于每个已定义的变体工具会自动生成一个 mustache 布尔变量命名格式为{{isVARIANT_NAMEVariant}}变体名首字母大写其余保持原样用于在模板文件中条件输出内容{{#isPrimaryVariant}} This content is only rendered if --variant primary is passed. {{/isPrimaryVariant}} {{#isSecondaryVariant}} This content is only rendered if --variant secondary is passed. {{/isSecondaryVariant}}该机制的实现在getVariantVarspackages/create-block/lib/templates.js中它遍历所有变体名为每个变体生成变量名 currentVariant variantName的布尔值再通过...variantVars合并进渲染上下文。仓库内置的块模板大量使用这一约定例如 packages/create-block/lib/templates/block/index.js.mustache 中{{#isStaticVariant}} import save from ./save; {{/isStaticVariant}}而 packages/create-block/lib/templates/block/render.php.mustache 整个文件都被{{#isDynamicVariant}}包裹——当渲染结果为空字符串时writeOutputTemplate会跳过该文件的写入if ( renderedFile.trim().length )这正是变体能够按需产出不同文件集合的实现原理。变体专属模板路径与null跳过机制变体还可以定义自己的pluginTemplatesPath、blockTemplatesPath或assetsPath。一旦定义它们会覆盖项目模板中定义的路径。如果某个变体不需要模板定义的某些文件可以向对应变量传入null来跳过这些文件的脚手架生成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, blockTemplatesPath: join( __dirname, custom-path, block-templates ), assetsPath: null, // Will not scaffold any assets files even if defined by the main template. }, }, };这一行为在configToTemplate与scaffold.js两处都有完整处理模板加载阶段会针对每个变体预取模板/资源内容并存入variantTemplates脚手架执行阶段再根据是否为null决定清空输出{}、使用变体路径还是沿用主模板路径。完整实战从零构建一个外部模板包综合以上知识点一个完整的外部模板包目录结构如下my-block-template/ ├── index.js # 必须导出配置对象 ├── plugin-templates/ # pluginTemplatesPath 指向 │ └── $slug.php.mustache # 自定义插件主文件 └── block-templates/ # blockTemplatesPath 指向 ├── edit.js.mustache ├── index.js.mustache ├── save.js.mustache └── style.scss.mustacheindex.js的完整示例const { join } require( path ); module.exports { pluginTemplatesPath: join( __dirname, plugin-templates ), blockTemplatesPath: join( __dirname, block-templates ), assetsPath: join( __dirname, plugin-assets ), defaultValues: { slug: my-fantastic-block, title: My fantastic block, dashicon: palmtree, version: 1.2.3, namespace: my-company, category: media, pluginURI: https://example.com/my-plugin, npmDependencies: [ wordpress/block-editor, lodash ], wpEnv: true, }, variants: { static: { title: My fantastic static block, }, dynamic: { title: My fantastic dynamic block, render: file:./render.php, }, }, transformer: ( view ) ( { ...view, author: Built by ${ view.author }, } ), };将模板包发布到 npm 后即可全局复用$ npx wordpress/create-blocklatest my-block --template my-block-template $ npx wordpress/create-blocklatest my-block --template my-block-template --variant dynamic若尚未发布本地目录同样可以直接使用npx wordpress/create-blocklatest my-block --template ./my-block-template。脚手架完成后若wpScripts为true生成的插件目录内可直接运行npm start开发构建、npm run build生产构建、npm run format、npm run lint:css、npm run lint:js、npm run plugin-zip、npm run packages-update等脚本若启用了wpEnv还可通过npm run env start一键拉起基于 Docker 的本地 WordPress 环境上述脚本由 packages/create-block/lib/init-package-json.js 生成并在 packages/create-block/lib/init-wp-scripts.js 中完成wordpress/scripts的安装与首次构建。使用要点与常见坑index.js必须存在外部模板无论 npm 包还是本地目录的入口文件默认是index.js加载失败时工具会抛出Invalid plugin template type name或Invalid block template loaded错误。模板文件扩展名必须是.mustachegetOutputTemplates通过fast-glob扫描**/*.mustache嵌套文件夹会被保留为输出相对路径。文件名中的$slug会被替换利用这一点可以实现按 slug 动态命名的输出文件如$slug.php。--no-plugin模式需要块模板仅包含pluginTemplatesPath而缺少blockTemplatesPath的模板在该模式下会直接报错。空渲染结果不产生文件变体条件为假时模板渲染为空字符串该输出文件将被跳过这是按变体裁剪文件集合的官方机制。依赖版本字段本文档所列表格中的默认值以当前仓库源码为准其中apiVersion的运行时默认值已是3文档原始记录为2说明内置默认会随 Gutenberg 版本演进模板作者在使用时应以自身目标 WordPress 版本为依据显式设置。通过外部项目模板create-block不再只是开箱即用的脚手架而是可以沉淀为团队工程规范的可编程基础设施。结合defaultValues、transformer与variants三者你完全可以维护一套随项目演进而持续升级的块开发模板体系。延伸阅读create-block 包使用说明CLI 选项、快速开始与内置命令模板加载与变体解析源码getProjectTemplate、getDefaultValues、getVariantVars的实现脚手架主流程源码transformer调用与变体路径覆盖逻辑内置插件模板 与 内置块模板官方.mustache文件可作为自定义模板的起点package.json 生成源码npmDependencies、customScripts、customPackageJSON的落盘行为【免费下载链接】gutenbergThe Block Editor project for WordPress and beyond. Plugin is available from the official repository.项目地址: https://gitcode.com/GitHub_Trending/gu/gutenberg创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价