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/';

您的每个块(example1example2)都应该有一个 index.jsblock.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()` 注册多个块会在控制台中引发错误的主要内容,如果未能解决你的问题,请参考以下文章

尝试为 Gutenberg 创建 ACF 块时出现“不存在块类型”

wordpress 小部件和块有啥区别

在 Wordpress 中延迟内联脚本

如何使用 Gutenberg 应用平滑滚动

在 Gutenberg 自定义横幅块中使用页面标题

php WordPress - 禁用Gutenberg而不使用插件。