Plate 中的调试。

使用 DebugPlugin

当你创建 Plate 编辑器时,DebugPlugin 会自动包含在内。你可以通过编辑器的 API 访问其方法:

const editor = createPlateEditor({
  plugins: [/* your plugins */],
});
 
editor.api.debug.log('This is a log message');
editor.api.debug.info('This is an info message');
editor.api.debug.warn('This is a warning');
editor.api.debug.error('This is an error');

日志级别

DebugPlugin 支持四种日志级别:

  1. log:用于一般日志记录
  2. info:用于信息性消息
  3. warn:用于警告
  4. error:用于错误

你可以设置最小日志级别来控制显示哪些消息:

const editor = createPlateEditor({
  plugins: [
    DebugPlugin.configure({
      options: {
        logLevel: 'warn', // 仅显示警告和错误
      },
    }),
  ],
});

配置选项

DebugPlugin 可以使用以下选项进行配置:

  • isProduction:设置为 true 以在生产环境中禁用日志记录。
  • logLevel:设置最小日志级别('error''warn''info''log')。
  • logger:为每个日志级别提供自定义日志记录函数。
  • throwErrors:设置为 true 以抛出错误而不是记录它们(默认:true)。

配置示例:

const editor = createPlateEditor({
  plugins: [
    DebugPlugin.configure({
      options: {
        isProduction: process.env.NODE_ENV === 'production',
        logLevel: 'info',
        logger: {
          error: (message, type, details) => {
            // 自定义错误日志记录
            console.error(`Custom Error: ${message}`, type, details);
          },
          // ... 其他级别的自定义日志记录器
        },
        throwErrors: false,
      },
    }),
  ],
});

错误处理

默认情况下,当调用 error 时,DebugPlugin 会抛出错误。你可以捕获这些错误并按需处理:

try {
  editor.api.debug.error('An error occurred', 'CUSTOM_ERROR', { details: 'Additional information' });
} catch (error) {
  if (error instanceof PlateError) {
    console.debug(error.type); // 'CUSTOM_ERROR'
    console.debug(error.message); // '[CUSTOM_ERROR] An error occurred'
  }
}

要记录错误而不是抛出它们,请在配置中将 throwErrors 设置为 false

最佳实践

  1. 为不同类型的消息使用适当的日志级别。
  2. 在生产环境中,将 isProduction 设置为 true 以禁用非必要的日志记录。
  3. 使用自定义日志记录器与您首选的日志记录服务集成。
  4. 在记录时包含相关详细信息,以便于调试。
  5. 使用错误类型来分类和处理不同的错误场景。

其他调试策略

除了使用 DebugPlugin,还有其他有效的方法来调试你的 Plate 编辑器:

1. 使用日志覆盖编辑器方法

你可以使用 extendEditor 选项来覆盖编辑器方法并添加日志记录:

const LoggingPlugin = createPlatePlugin({
  key: 'logging',
}).overrideEditor(({ editor, tf: { apply } }) => ({
  transforms: {
    apply(operation) {
      console.debug('Operation:', operation);
      apply(operation);
    },
  },
}));
 
const editor = createPlateEditor({
  plugins: [LoggingPlugin],
});

这种方法允许你记录操作、选择或任何你想要检查的编辑器行为。

2. 移除可疑插件

如果你遇到问题,尝试逐个移除插件以隔离问题:

const editor = createPlateEditor({
  plugins: [
    // 注释或移除可疑插件
    // HeadingPlugin,
    // BoldPlugin,
    // ...其他插件
  ],
});

逐步添加插件,直到找出导致问题的那个。

3. 使用 React DevTools

React DevTools 对于调试 Plate 组件非常有用:

  1. 安装 React DevTools 浏览器扩展。
  2. 打开你的应用和 DevTools。
  3. 导航到 Components 标签页。
  4. 检查 Plate 组件、它们的 props 和状态。

4. 使用浏览器 DevTools 断点

使用浏览器 DevTools 在代码中设置断点:

  1. 在浏览器中打开你的应用并打开 DevTools。
  2. 导航到 Sources 标签页。
  3. 找到你的源文件并点击你想要设置断点的行号。
  4. 与编辑器交互以触发断点。
  5. 检查变量并逐步执行代码。

5. 创建最小可重现示例

如果你遇到复杂问题:

  1. 选择一个模板
  2. 仅添加必要的插件和组件来重现问题。
  3. 如果问题仍然存在,在 GitHub 上提交问题或在 Discord 上分享你的示例。

6. 使用 Redux DevTools 进行 zustand 存储

Zustand 以及 zustand-x 可以与 Redux DevTools 浏览器扩展一起使用。它对于跟踪 zustand 存储中的状态变化非常有用。

按照 zustand 文档 开始使用 Redux DevTools 和 zustand。

调试错误类型

Plate 使用几个预定义的错误类型来帮助识别开发过程中的特定问题。以下是这些错误类型及其描述的列表:

DEFAULT

一个不适合其他特定类别的一般错误。当没有其他错误类型适用于该情况时使用。

OPTION_UNDEFINED

当尝试访问未定义的插件选项时抛出。这发生在尝试使用尚未设置或未定义的插件选项时。

OVERRIDE_MISSING

表示插件配置中缺少预期的覆盖。当插件期望提供某些覆盖但它们不在配置中时,会发生这种情况。

PLUGIN_DEPENDENCY_MISSING

当找不到必需的插件依赖项时发生。当插件依赖于尚未注册或包含在编辑器配置中的另一个插件时,会抛出此错误。

PLUGIN_MISSING

表示尝试使用尚未注册的插件。这发生在尝试访问或使用不属于当前编辑器配置的插件时。

USE_CREATE_PLUGIN

当插件不是使用 createSlatePlugincreatePlatePlugin 函数创建时抛出。当插件被添加到编辑器中但未使用指定函数正确创建时,会发生此错误。

USE_ELEMENT_CONTEXT

表示 useElement hook 在适当的 element 上下文之外使用。这发生在尝试在正确的组件上下文之外访问 element 特定的数据或功能时。

PLUGIN_NODE_TYPE

当插件被错误地配置为既是 element 又是 leaf 时抛出。当插件的配置通过同时将 isElementisLeaf 设置为 true 而自相矛盾时,会发生此错误。