第25次:代码调试器功能

本文讲解 entry/src/main/ets/pages/CodePlayground.ets。它不是一个完整的 JS/TS 运行时,而是一个教学型代码调试器:支持编辑、预览、复制和重置,重点是帮助用户理解示例代码,而不是执行完整 React 工程。


先理解它的定位

这个页面更准确的定位如下:

  • 一个轻量代码练习与预览页面
  • 适合承接课程中的可编辑代码示例
  • 通过简单的 JSX 解析器生成预览结果

这样理解很重要,因为只有定位准了,你写出来的文档和用户预期才不会错位。

LessonDetail 点击 在调试器中打开

CodePlayground 接收 title/code/language/explanation

展示说明区 + 编辑器区

编辑代码

runCode

parseJSX

RenderParsedContent

显示预览


一、这个页面是怎么接收代码的

CodePlayground 会从路由参数中读取:

  • title
  • code
  • language
  • explanation

如果没有传参,就会使用默认示例代码。

这种设计非常适合教学场景,因为它意味着:

  • 课程页可以按需把某段示例代码送进来
  • 页面本身不依赖某一门具体课程
  • 同一个调试器可以服务很多课时

这就是典型的“页面通用能力组件化”思路:调试器不关心它来自哪一节课,它只关心接收到什么代码。

页面初始化时用到的真实代码如下:

aboutToAppear(): void {
  const params = router.getParams() as PlaygroundParams;
  if (params) {
    this.title = params.title ?? '代码调试';
    this.originalCode = params.code ?? this.getDefaultCode();
    this.currentCode = this.originalCode;
    this.language = params.language ?? 'jsx';
    this.explanation = params.explanation ?? '';
  } else {
    this.originalCode = this.getDefaultCode();
    this.currentCode = this.originalCode;
  }
}

二、编辑器区域为什么分“只读”和“编辑中”两种状态

当前页面用 isEditing 控制编辑状态:

  • false:显示带行号的只读代码视图
  • true:切换成 TextArea 进行编辑

这个设计很合理,因为教学场景下用户并不一定每次都要修改代码。很多时候他只是想先看一眼示例。默认只读能保证信息更整洁,真正想改的时候再切到编辑模式即可。

另外,只读模式中每行代码都有:

  • 行号
  • 等宽字体
  • 简单语法着色

这虽然不是专业编辑器级别,但已经足够支撑教学体验。


三、所谓“运行”,实际上做了什么

runCode() 并不会真的执行一段 React 代码,而是做了三件事:

  1. 退出编辑状态
  2. 调用 parseJSX(this.currentCode) 解析当前代码
  3. 打开预览区域并提示“代码已运行”

这里的关键在于 parseJSX()。它不是完整编译器,而是一个教学友好的解析器,会尝试:

  • 判断当前代码类型
  • 提取组件名
  • 提取 JSX 中的 h1h2pbuttoninput 等元素
  • 提取部分字符串文本
  • 生成简单可视的预览内容

所以这套页面的目标从来不是“把 React 真跑起来”,而是“帮助学习者理解这段 JSX 最终大概会长成什么样”。

点击“运行”时,页面执行的真实代码如下:

private runCode(): void {
  this.isEditing = false;
  this.parsedElements = this.parseJSX(this.currentCode);
  this.showPreview = true;
  this.showToast('代码已运行');
}

四、为什么这种轻量预览方式反而更适合教程应用

你可能会问:既然不能真正执行完整 React 逻辑,那这个调试器还有价值吗?答案是有,而且很适合当前项目。

原因有三点:

  1. 当前应用是鸿蒙 ArkTS 项目,不适合在本地直接跑完整 React 运行时。
  2. 教学场景里,很多示例只需要让用户看懂结构和渲染结果,不一定要完整执行所有逻辑。
  3. 轻量预览比真正嵌入复杂 Web 运行环境更稳定,维护成本也更低。

这说明一个很重要的产品思路:不要一味追求“最强功能”,而要追求“最适合当前项目目标的功能”。


五、预览区是怎样渲染出来的

预览区域主要由下面几层组成:

  • 标题栏“预览效果”
  • 模拟浏览器窗口
  • 地址栏视觉
  • 渲染内容容器

RenderParsedContent() 会遍历 parsedElements,再交给 RenderElement() 根据标签类型生成对应 UI。比如:

  • h1 显示大标题
  • p 显示正文
  • button 生成按钮
  • input 生成输入框

这种写法非常适合作为教学演示。用户改动一段 JSX 后,可以立刻看到一个近似结果,而不是只盯着代码本身。


六、四个操作按钮分别解决什么问题

底部按钮区是这个页面体验最完整的部分,一共四个动作:

  • 编辑
  • 运行
  • 重置
  • 复制

每个动作都非常有针对性:

编辑

让用户从观察者切换成尝试者。

运行

把当前代码转成可视化预览。

重置

方便用户做实验后回到原始状态。

复制

方便用户把代码带走,继续在别处研究。

这套按钮组合很经典,几乎就是一个轻量教学调试器应该具备的最小闭环。


七、实操步骤

  1. 从课程详情页点击“在调试器中打开”进入。
  2. 先观察顶部标题、语言标签和说明区。
  3. 点击“编辑”,改一段标题文字或按钮文案。
  4. 点击“运行”,观察预览是否同步变化。
  5. 再点击“重置”,确认能回到原始代码。
  6. 最后点击“复制”,测试剪贴板和提示是否正常。

只要这一套走完,你就会非常清楚这个调试器页面的能力边界。


八、本篇常见坑

1. 把它理解成完整 React 执行环境

当前实现不是完整运行时,而是轻量 JSX 解析预览器。

2. 预览器和编辑器耦合过深

现在的设计已经很好地把“代码编辑”和“结果展示”分开了。

3. 没有重置功能

教学场景中,重置非常重要,因为用户经常会尝试到一半想回退。

4. 只支持课时调用,不支持默认示例

当前页面有默认代码,是一个很好的兜底设计。


八、本篇常见坑

1. 把它理解成完整 React 执行环境

当前实现不是完整运行时,而是轻量 JSX 解析预览器。

2. 预览器和编辑器耦合过深

现在的设计已经很好地把“代码编辑”和“结果展示”分开了。

3. 没有重置功能

教学场景中,重置非常重要,因为用户经常会尝试到一半想回退。

4. 只支持课时调用,不支持默认示例

当前页面有默认代码,是一个很好的兜底设计。


本篇小结

这页的价值,不在于把代码真正跑成一个生产级应用,而在于为课程示例提供一个轻量、稳定、可交互的实验空间。对当前这个鸿蒙教程项目来说,这种取舍非常合理。

你应该重点记住:

  • 它是教学调试器,不是完整 IDE。
  • 它通过路由参数承接课程代码。
  • 它通过轻量解析与可视化预览帮助用户理解 JSX。

课后练习

  1. 观察 parseJSX() 目前识别了哪些标签,思考如果要新增 imga 支持该怎么扩展。
  2. 想一想为什么“代码运行”前要先把 isEditing 设为 false
  3. 如果你要增加“保存为我的示例”功能,最适合新增哪个服务来承接。
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐