133 lines
11 KiB
Markdown
133 lines
11 KiB
Markdown
|
|
## 是否支持自定义安全策略?
|
|||
|
|
|
|||
|
|
是的。交互式API不使用 [`eval()`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/eval) 或 [`Function()`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/Function) 构造函数,因此不会违反 [`unsafe-eval`](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Content-Security-Policy#unsafe_keyword_values) 内容安全策略。该API在设计上可与任何[自定义内容安全策略](https://developer.wordpress.org/apis/security/)协同工作。
|
|||
|
|
|
|||
|
|
## 能否使用指令发起AJAX/REST-API请求?
|
|||
|
|
|
|||
|
|
当然可以。通过指令调用的操作和回调函数可以执行任何JavaScript函数能实现的功能,包括发起API请求。
|
|||
|
|
|
|||
|
|
## 交互性API能否在区块之外使用?
|
|||
|
|
|
|||
|
|
当然可以,它不仅限于区块。虽然你会看到许多关于交互性API如何为创建交互式区块提供标准的讨论,但这只是因为那是最常见的用例。更广义地说,交互性API标准可用于为WordPress任何部分的前端添加“交互行为”。
|
|||
|
|
|
|||
|
|
有关在区块外使用任意HTML的交互性API的详细信息,请参阅[`wp_interactivity_process_directives`函数](https://developer.wordpress.org/reference/functions/wp_interactivity_process_directives/)。
|
|||
|
|
|
|||
|
|
## 这是否意味着我必须将所有交互式区块迁移到此API?
|
|||
|
|
|
|||
|
|
不需要。未使用交互性API的区块可以与使用该API的区块共存。但如前所述,请注意使用该API的区块具有以下优势:
|
|||
|
|
|
|||
|
|
- **区块间可轻松通信**:采用标准后,这种通信默认即可实现。当不同区块使用不同方法实现前端交互时,区块间通信会变得复杂,尤其在由不同开发者创建区块时几乎无法实现。
|
|||
|
|
- **可组合性与兼容性**:你可以组合交互式区块,将其嵌套在具有定义行为的结构中,并且由于遵循相同标准,它们完全跨兼容。如果每个区块采用不同的交互方法,很可能会导致功能冲突。
|
|||
|
|
- **减少向浏览器传输的数据量**:如果每个插件作者使用不同的JS框架,前端将加载更多代码。如果所有区块使用同一框架,代码可实现复用。
|
|||
|
|
- 若页面所有区块都采用此标准,则可启用站点级功能(如客户端导航)。
|
|||
|
|
|
|||
|
|
## 使用此API对性能有何影响?对于非常简单的用例,加载交互性API是否值得?
|
|||
|
|
|
|||
|
|
该API在设计时已充分考虑性能因素:
|
|||
|
|
|
|||
|
|
- **指令所需的运行时代码仅约10KB**,且所有区块只需加载一次。
|
|||
|
|
- **所有属于交互性API的脚本模块(包括`view.js`文件)均不会阻塞页面渲染。**
|
|||
|
|
- 目前正在[持续探索](https://github.com/WordPress/gutenberg/discussions/52723)**在区块进入视口后延迟加载脚本**的可能性。通过这种方式,可在不影响用户体验的前提下优化初始加载。
|
|||
|
|
|
|||
|
|
## 是否与核心翻译API兼容?
|
|||
|
|
|
|||
|
|
由于交互性API与服务器端渲染完美配合,你可以使用所有WordPress API,包括[`__()`](https://developer.wordpress.org/reference/functions/__/)和[`_e()`](https://developer.wordpress.org/reference/functions/_e/)。你可以用它翻译HTML中的文本(就像通常做法),甚至可以在[服务器端使用`wp_interactivity_state()`](https://developer.wordpress.org/block-editor/reference-guides/interactivity-api/api-reference/#setting-the-store)时在存储库中使用。示例如下:
|
|||
|
|
|
|||
|
|
```php
|
|||
|
|
// render.php
|
|||
|
|
wp_interactivity_state( 'favoriteMovies', array(
|
|||
|
|
"1" => array(
|
|||
|
|
"id" => "123-abc",
|
|||
|
|
"movieName" => __("影片名称", "textdomain")
|
|||
|
|
),
|
|||
|
|
) );
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
目前正在开发与脚本模块(交互性API所需)兼容的翻译API。请关注[#60234](https://core.trac.wordpress.org/ticket/60234)了解进展。
|
|||
|
|
|
|||
|
|
## 我担心XSS攻击;JavaScript能否被注入到指令中?
|
|||
|
|
|
|||
|
|
不会。交互性API只允许将[引用](https://developer.wordpress.org/block-editor/reference-guides/interactivity-api/api-reference/#values-of-directives-are-references-to-store-properties)作为值传递给指令。这种方式无需eval()完整的JavaScript表达式,因此不可能实施XSS攻击。
|
|||
|
|
|
|||
|
|
### 原生 JavaScript
|
|||
|
|
|
|||
|
|
请参阅下方答案。
|
|||
|
|
|
|||
|
|
### 模板领域特定语言
|
|||
|
|
|
|||
|
|
我们还研究了创建用于编写交互式模板的[领域特定语言](https://en.wikipedia.org/wiki/Domain-specific_language)的可能性。使用该模板DSL编写的代码将被编译为JavaScript和PHP。然而,创建生产级的模板编译器十分复杂,需要投入大量精力且存在较高风险。未来仍会考虑采用这种方案,届时指令系统将作为编译目标。
|
|||
|
|
|
|||
|
|
## 作为区块开发者,为何应选择交互式API而非React?
|
|||
|
|
|
|||
|
|
在PHP服务端渲染环境中,前端使用React无法流畅运行。所有基于React渲染区块的方案都需通过客户端JavaScript加载内容。若仅通过客户端渲染区块,通常会导致用户体验不佳——用户需要盯着空白占位符和加载动画等待内容呈现。
|
|||
|
|
|
|||
|
|
虽然可通过PHP扩展(如v8js)运行JS,但遗憾的是PHP扩展不具向后兼容性,且必须存在PHP降级方案时才能使用。
|
|||
|
|
|
|||
|
|
当前虽可实现在PHP中服务端渲染区块,并同时在前端使用React渲染相同区块,但这会导致开发体验恶化——相同逻辑需在PHP和React部分重复实现。更严重的是,您将面临WordPress钩子引发的隐蔽错误!
|
|||
|
|
|
|||
|
|
假设安装的第三方插件通过钩子(过滤器)修改了服务端渲染的HTML,例如为区块HTML添加单个CSS类。该CSS类会存在于服务端渲染的标记中。但在前端,您的区块通过React重新渲染时,由于无法对React渲染内容应用WordPress钩子,最终呈现的内容将缺失这个CSS类!
|
|||
|
|
|
|||
|
|
反观交互式API,其设计理念是通过指令为服务端渲染的HTML增强交互行为,因此能与WordPress钩子完美协同。这也意味着它可以开箱即用地兼容WordPress后端API(如i18n)。
|
|||
|
|
|
|||
|
|
总结而言,选择交互式API而非单纯使用React具有以下优势:
|
|||
|
|
|
|||
|
|
- 使用React时,交互式区块在客户端生成的标记必须与服务端PHP生成的完全一致。而交互式API无此限制,指令可直接附加于服务端渲染的HTML
|
|||
|
|
- 交互式API对PHP更友好,可无缝兼容WordPress钩子及其他服务端功能(如国际化)。例如使用React时,您无法预知服务端应用的钩子,其修改效果将在水合后被覆盖
|
|||
|
|
- 具备[采用标准化方案](/docs/reference-guides/interactivity-api/iapi-about.md#why-a-standard)的所有优势
|
|||
|
|
|
|||
|
|
## 与jQuery或原生JavaScript相比,交互式API的优势何在?
|
|||
|
|
|
|||
|
|
核心差异在于交互式API具备**声明式与响应式特性**,这使得编写和维护复杂交互体验变得更为轻松。此外,它**专为区块开发量身定制**,提供的标准规范具备前述各项优势,包括区块间通信、兼容性以及客户端导航等全站功能。
|
|||
|
|
|
|||
|
|
最后与jQuery对比:**交互式API运行时仅约10kb**,体积更轻量化。实际上,WordPress生态正在持续推进移除jQuery等重型框架的工作,本API将为此提供助力。
|
|||
|
|
|
|||
|
|
## 是否需要同时掌握React、PHP和本交互式API?
|
|||
|
|
|
|||
|
|
若希望使用本API为区块添加前端交互功能,简短答案是肯定的。如果区块无需交互功能,区块创建流程将完全保持不变。
|
|||
|
|
|
|||
|
|
交互式API引入了新的标准方法,以简化WordPress前端交互行为的集成。这意味着您仍需要使用React来处理区块的编辑器部分。
|
|||
|
|
|
|||
|
|
反之,若要创建交互式区块,采用交互式API后您无需处理复杂议题,例如工具链配置、WordPress集成、区块间通信或交互部件的服务端渲染。
|
|||
|
|
|
|||
|
|
# 常见问题解答
|
|||
|
|
|
|||
|
|
## 交互性 API 底层是如何运作的?
|
|||
|
|
|
|||
|
|
其三大核心组件包括:
|
|||
|
|
|
|||
|
|
- 采用 [Preact](https://preactjs.com/) 与 [Preact Signals](https://preactjs.com/guide/v10/signals/) 组合实现水合作用、客户端逻辑及客户端导航功能
|
|||
|
|
- 可被客户端与服务端共同解析的 HTML 指令系统
|
|||
|
|
- 由 [HTML 标签处理器](https://make.wordpress.org/core/2023/03/07/introducing-the-html-api-in-wordpress-6-2/) 处理的服务器端逻辑
|
|||
|
|
|
|||
|
|
## 为何选择 Preact 构建指令系统?为何不采用 React 或其他 JavaScript 框架?
|
|||
|
|
|
|||
|
|
在前端应用场景中(这也是交互性 API 的核心定位),Preact 相较于 React 及 Vue、Svelte、Solid 等框架具有显著优势:
|
|||
|
|
|
|||
|
|
- 体积轻量:包含 [钩子函数](https://preactjs.com/guide/v10/hooks/) 与 [信号系统](https://preactjs.com/blog/introducing-signals/) 仅 8kB
|
|||
|
|
- 开箱即用的 DOM 差异化比较功能
|
|||
|
|
- 通过可选钩子实现高度可扩展性,该特性被广泛应用于钩子函数、React 兼容层 (preact/compat) 及信号系统 (@preact/signals),覆盖除 DOM 差异算法外的所有功能模块
|
|||
|
|
- 核心团队技术实力雄厚且提供强力支持,并对 Preact 的“孤岛架构”应用模式表现出浓厚兴趣
|
|||
|
|
|
|||
|
|
## Gutenberg 编辑器是否会因交互性 API 采用 Preact 而从 React 迁移?
|
|||
|
|
|
|||
|
|
不会。目前暂无迁移计划。作为一个完全交互式应用,编辑器的功能需求与优势考量存在显著差异。虽然 Preact 提供完全兼容 React 生态的 [`@preact/compat`](https://preactjs.com/guide/v10/switching-to-preact/) 套件,且已被众多大型网络应用采纳,但在区块编辑器中使用 Preact 无法获得像交互性 API 在前端场景中的同等优势。
|
|||
|
|
|
|||
|
|
## 除指令系统外,还考虑过哪些替代方案?
|
|||
|
|
|
|||
|
|
我们曾评估多种替代方案,以下是部分方案的简要概述:
|
|||
|
|
|
|||
|
|
### React 及其他 JavaScript 框架
|
|||
|
|
|
|||
|
|
由于 Gutenberg 开发者对 React 更熟悉,该框架成为首要考量对象。其他主流 JS 框架如 Svelte、Vue.js 或 Angular 也在评估之列,但这些框架(包括 React)均存在与 PHP 环境兼容性不足、无法适配 WordPress 钩子系统或国际化需求的局限性。
|
|||
|
|
|
|||
|
|
### Alpine.js
|
|||
|
|
|
|||
|
|
Alpine.js 是优秀的框架方案,其诸多功能设计为交互性 API 带来重要启发。但该框架不支持服务端渲染 [指令](https://github.com/alpinejs/alpine/tree/d7f9d641f7a763c56c598d118bd189a406a22383/packages/docs/src/en/directives),而为 WordPress 区块量身打造专属系统能带来更多收益。
|
|||
|
|
|
|||
|
|
最终选择 Preact 取代 Alpine.js 基于多重考量:更小的体积尺寸、更优的性能表现(特别是集成 [信号系统](https://preactjs.com/guide/v10/signals/) 后)、基于 Preact 声明式语法及工具链(钩子、信号)编写自定义指令、相比 Alpine.js 具有更充分的实战检验与更庞大的开发者社区。同时完美兼容 React(便于共享编辑器中的客户端渲染组件),并为交互性 API 提供开箱即用的最快 DOM 差异算法,包含 UI 状态保持功能。
|
|||
|
|
|
|||
|
|
更重要的是,依托 Preact 的底层支撑,交互性 API 可专注管理“最终呈现层”,从而更好适配 WordPress 的特殊需求。例如:为避免安全风险并确保符合严格的安全策略,指令内部禁止使用 JavaScript 表达式;所有 WordPress 指令均符合 HTML 属性规范标准。
|
|||
|
|
|
|||
|
|
<div class="callout callout-info">
|
|||
|
|
欢迎查阅 <a href="https://github.com/WordPress/gutenberg/discussions/53022#discussioncomment-4696611">《为何选择 Preact 而非 Alpine?》</a> 专题讨论获取更多信息。
|
|||
|
|
</div>
|