Gutenberg Blocks:使用 `register_block_type_from_metadata()` 注册多个块会在控制台中引发错误
Posted
技术标签:
【中文标题】Gutenberg Blocks:使用 `register_block_type_from_metadata()` 注册多个块会在控制台中引发错误【英文标题】:Gutenberg Blocks: registering more than one block with `register_block_type_from_metadata()` throws errors in the console 【发布时间】:2021-09-23 00:20:26 【问题描述】:我正在练习如何创建 Gutenberg blocks 插件。我使用@wordpress/create-block 来创建一个块插件。
编辑:我并没有像我最初所说的那样使用 wp-cli 脚手架,我的意思是我使用了@wordpress/create-block。
脚手架上只有一个块,所以,如果你想要多个块,你必须修改结构,这并不难,但是,我希望块使用 block.json 注册我实现了register_block_type_from_metadata()
的块,但问题是如果我在主插件的 php 文件中使用此代码(register_block_type_from_metadata 两次):
function blocks_boilerplate_block_init()
register_block_type_from_metadata( __DIR__ . '/src/blocks/example');
register_block_type_from_metadata( __DIR__ . '/src/blocks/example2');
add_action( 'init', 'blocks_boilerplate_block_init' );
要注册块,块会被注册并且它们可以正常工作,但 Chrome 控制台显示两个错误。
块“create-block/boilerplate-example”已经注册。
块“create-block/guten-block-example2”已经注册。
如果我使用register_block_type_from_metadata()
只使用一次,错误就会消失。
关于如何使错误消失的任何想法?
【问题讨论】:
【参考方案1】:在使用 wp-cli scaffold 设置您的 Gutenberg 块项目并添加两个新块后,您的项目结构可能类似于:
- myblockname
> build
> node_modules
- src
- blocks
- example1
- index.js
- block.json
> example2
index.js
myblockname.php
在使用block.json
时加载多个块而不会发生冲突的一种方法是通过src/index.js
创建的主src/index.js
导入每个块,例如:
src/index.js:
import './blocks/example1/';
import './blocks/example2/';
您的每个块(example1 和 example2)都应该有一个 index.js
和 block.json
文件来定义块,例如:
src/blocks/example1/index.js:
import registerBlockType from '@wordpress/blocks';
import metadata from './block.json';
const title = metadata;
registerBlockType(name,
title, // required
edit()...
save()...
);
现在,当您构建项目时,每个示例块都会编译成单个 build/index.js
和相关资产。
如果您随后使用从wp-cli
脚手架创建的原始 PHP 主文件(例如 myblockname.php),它将加载预期的单个构建的 index.js、index.asset.php、index.css 等 并使您能够将许多块捆绑为一个。
我在过去的几个 Gutenberg 项目中使用了这种方法,从 wp-cli
开始快速捆绑多个块。我还查看了WordPress Gutenberg 如何加载块库,发现最近更新的WordPress Block API Documentation 有助于解决这种方法。
注意: 这种将所有块捆绑到一个 javascript 文件中的方法有一个潜在的缺点——即使不使用它们也会全部加载。在我的项目中,我的块是相互依赖的(innerBlocks),所以它是有益的。文件大小和加载时间可能是一个问题,具体取决于您捆绑了多少块。
对于许多区块,更好的方法是让每个区块构建自己的资产文件,然后通过 block.json
中的“editorScript”和“脚本”捆绑这些资产,但仍使用主 index.js
作为入口点。
如果您仍然看到名称已注册的错误,请检查 block.json
【讨论】:
注意:wp-cli
的较新版本确实支持添加多个块,请参阅:developer.wordpress.org/cli/commands/scaffold/block/#examples【参考方案2】:
问题是,当你使用@wordpress/create-block
创建一个包含块的插件,然后你使用npm start
运行所有内容时,webpack 将所有块 JavaScript 代码编译到一个文件中,这很好,并且实际上是需要的,这样您就不必将一堆文件排入队列。 block.json 文件包含一行"editorScript": "file:../build/index.js"
(或类似的东西)来将主编译的 JS 文件排入队列,如果你只有一个块,那一行在 block.json 文件中是可以的,但是当你修改结构时插件包含更多块,每个块都有自己的 block.json 文件,包括editorScript
行,然后块被注册多次,每个 block.json 文件一个,所以,作为一个临时解决方案,我从除一个之外的所有block.json
文件中删除了editorScript
行,错误消失了,我不喜欢该解决方案,因为它破坏了一致性,因此,我将以下代码放在插件主php 文件中:
function qas_enqueue_blocks_scripts()
$asset_file = require plugin_dir_path( __FILE__ ) . 'build/index.asset.php';
wp_enqueue_script( 'qas-main', plugins_url( '/build/index.js', __FILE__ ), $asset_file['dependencies'], 1.0, false);
add_action( 'enqueue_block_editor_assets', 'qas_enqueue_blocks_scripts');
上面的代码将主要的index.js
文件排入块编辑器并从/build/index.asset.php
获取文件依赖项,当您运行初始命令来创建插件和初始块时会自动生成该文件依赖项。使用该代码,您无需在任何地方使用 editorScript
行,因此您可以从所有 block.json 文件中删除它。
解决这个问题的其他方法是修改webpack配置,只将特定块的代码编译到主JS文件中,然后在每个block.json
中继续使用editorScript
,但我还没有尝试过.
【讨论】:
以上是关于Gutenberg Blocks:使用 `register_block_type_from_metadata()` 注册多个块会在控制台中引发错误的主要内容,如果未能解决你的问题,请参考以下文章