## 进阶阅读

-   [软件包参考](/docs/reference-guides/packages.md)

# 模块化设计

WordPress 区块编辑器的核心理念在于通过组合独立区块来撰写文章或构建页面。区块之间能够相互调用与交互，这种设计赋予了系统高度的模块化特性与灵活性。

但区块编辑器的模块化不仅体现在功能与输出层面。古腾堡项目仓库本身也是由多个可复用独立模块（即程序包）构建而成，这些模块共同构成了我们熟悉的应用程序与交互界面。这些模块被称为 [WordPress 程序包](https://www.npmjs.com/org/wordpress)，会定期发布并更新至 npm 包仓库。

这些程序包不仅为区块编辑器提供核心支持，也可用于增强 WordPress 管理后台或外部环境的任何页面。

## 设计理念

采用模块化架构为所有参与者带来多重优势：

-   每个程序包都是独立单元，拥有明确定义的公共 API 用于与其他程序包及第三方代码交互。这使得**核心贡献者**能更清晰地理解代码库，可专注于单个程序包的开发维护，并在明确知晓变更影响范围的前提下进行更新
-   模块化架构对**终端用户**同样有益。通过在不同管理页面选择性加载脚本，有效控制资源包体积。例如当使用组件包构建插件设置页面时，就无需额外加载区块编辑器包
-   这种架构允许**第三方开发者**通过 npm 或 WordPress 脚本依赖的方式，在 WordPress 内外环境中复用这些程序包

## 程序包分类

古腾堡仓库中的几乎所有功能都被构建为程序包。这些程序包可分为两大类型：

### 生产环境包

这类程序包以 JavaScript 脚本形式随 WordPress 核心发布，构成在浏览器中运行的实际生产代码。例如：
- `components` 程序包提供可复用的 React 组件集合，用于快速原型设计与界面构建
- `api-fetch` 程序包可用于调用 WordPress REST API

第三方开发者可通过两种方式使用这些生产环境包：

- 若在 WordPress 环境外构建 JavaScript 应用、网站或页面，可像使用常规 npm 包那样调用：

```
npm install @wordpress/components
```

```js
import { Button } from '@wordpress/components';

function MyApp() {
	return <Button>精美按钮</Button>;
}
```

- 若开发 WordPress 插件，建议直接调用 WordPress 内置程序包。这样可实现多插件共享同一程序包，避免代码重复。在 WordPress 中，这些程序包以后缀为 `wp-包名称`（如 `wp-components`）的脚本句柄形式提供。只需将脚本添加到插件依赖中，即可通过全局变量 `wp` 调用：

```php
// myplugin.php
// 注册依赖 "components" 和 "element" 程序包的示例
wp_register_script( 'myscript', 'pathtomyscript.js', array ('wp-components', "react" ) );
```

```js
// 在脚本中使用程序包
const { Button } = wp.components;

function MyApp() {
	return <Button>精美按钮</Button>;
}
```

手动定义脚本依赖对开发者而言可能繁琐易错。若需了解如何自动化此流程，请参阅 [@wordpress/scripts](https://developer.wordpress.org/block-editor/packages/packages-scripts/#build) 与 [@wordpress/dependency-extraction-webpack-plugin](https://developer.wordpress.org/block-editor/packages/packages-dependency-extraction-webpack-plugin/) 文档。

#### 包含样式文件的功能包

部分生产环境功能包需依赖样式文件才能正常运行。

-   若通过 npm 依赖形式使用功能包，样式文件将存放于功能包的 `build-style` 目录。请确保在应用中加载该样式文件。
-   若在 WordPress 环境中使用，需通过 wp_enqueue_style 函数加载样式文件，或将其添加至现有样式依赖中。样式文件句柄命名规则与脚本句柄保持一致。

在现有 WordPress 页面环境中，若未正确定义脚本或样式依赖，当这些资源已被 WordPress 或其他插件加载时，您的插件仍可能正常运行。但为规避未来版本可能出现的兼容性问题，强烈建议完整定义所有依赖项。

#### 包含数据存储的功能包

部分 WordPress 生产环境功能包通过数据存储机制管理状态。这些存储空间也可被第三方插件和主题调用，用于数据获取与操作。数据存储命名遵循 `core/功能包名称` 的标准化格式（例如 `@wordpress/block-editor` 功能包定义并使用 `core/block-editor` 数据存储）。

若在插件中通过此类存储空间访问或操作 WordPress 数据，请务必将对应的 WordPress 脚本添加至插件脚本依赖中以确保正常运行（例如：若从 `core/block-editor` 存储获取数据，应按前文示例将 `wp-block-editor` 包添加至脚本依赖）。

### 开发环境功能包

此类功能包用于开发模式，协助开发者完成 JavaScript 应用、WordPress 插件及主题的开发、构建和发布等日常任务。包含代码规范检查、项目构建、测试验证等开发工具。

## 编辑器功能包

![文章编辑器模块架构](https://raw.githubusercontent.com/WordPress/gutenberg/HEAD/docs/explanations/architecture/assets/modules.png)

### 不同编辑器功能包有何区别？各自承担什么职责？

新贡献者往往会对文章编辑器由三个独立功能包（`@wordpress/edit-post`、`@wordpress/editor` 和 `@wordpress/block-editor`）分层构建的架构感到惊讶。

前文[设计初衷](#why)章节已说明单个功能包如何满足特定需求的设计理念，这同样适用于以下功能包：

-   `@wordpress/block-editor` 提供用于实现区块编辑器的组件，其操作对象为区块对象数组的基础数据。该包不预设数据保存方式，且无需感知（或依赖）WordPress 环境。
-   `@wordpress/editor` 是 WordPress 文章专用的增强版区块编辑器。它在 `@wordpress/block-editor` 组件基础上构建，具备 WordPress 文章概念感知能力，将表征区块的数据加载保存机制与文章及其内容相关联。同时提供在编辑器环境中处理文章对象的相关组件（如文章标题输入组件）。该功能包支持编辑任何文章类型的文章，且不限定渲染环境必须位于特定 WordPress 界面或布局中。
-   `@wordpress/edit-post` 是 WordPress 后台“新建文章”（“编辑文章”）界面的具体实现。它负责对 `@wordpress/editor` 和 `@wordpress/block-editor` 提供的各类组件进行布局编排，完全掌控其在 WordPress 管理后台特定界面中的呈现方式。

通过这样的结构设计，这些功能包可在“新建文章”界面之外实现多样化组合应用：

-   `@wordpress/edit-site` 或 `@wordpress/edit-widgets` 功能包可分别实现“站点编辑器”或“小工具编辑器”，其实现方式与 `@wordpress/edit-post` 高度相似。
-   `@wordpress/editor` 可应用于“可重用区块”功能的实现，因其本质上是与 `wp_block` 文章类型关联的嵌套区块编辑器。
-   `@wordpress/block-editor` 可独立于 WordPress 环境使用，或采用完全不同的保存机制。例如：可用于构建网站文章的评论区编辑器。