鸿蒙PC三方库适配实战:markedown 解析器从 ohpm 404 到 ArkTS 原生移植

本文详述将Markdown解析库适配至鸿蒙PC平台的全过程:从ohpm 404错误分析出发,揭示npm与OHPM仓库体系差异;通过降级hvigor modelVersion、清理schema非法字段、修复ArkTS严格模式编译错误(含对象字面量类型约束、API签名变更、deviceTypes配置等)、完成分布式KV存储适配,最终实现200行零依赖TinyMarkdown解析器,并在鸿蒙PC(2in1)模拟器及真机成功运行。

欢迎加入开源鸿蒙PC社区:https://harmonypc.csdn.net/

欢迎在PC社区平台申请新建项目:https://atomgit.com/OpenHarmonyPCDeveloper


目录

摘要

本文记录一次典型的鸿蒙 PC 三方库适配完整流程:从 Markdown 解析库 marked 的 ohpm 404 报错出发,经历 npm 与 OHPM 仓库体系差异分析、hvigor modelVersion 降级、schema 字段清理、ArkTS 严格模式编译、分布式 KV 存储 API 签名变更、鸿蒙 PC(2in1)deviceTypes 配置,共计 6 类错误、12 个文件修改、3 轮构建,最终实现一个 200 行 ArkTS 零依赖的 TinyMarkdown 解析器并成功运行于鸿蒙 PC 模拟器。

适用读者:开源鸿蒙 PC 专项积分赛参赛者、从 Web/Node.js 转向鸿蒙应用开发的工程师、首次接触 DevEco Studio 构建链的开发者

前置知识:了解 npm 包管理基本概念、熟悉 ArkTS/TypeScript 语法、对鸿蒙 DevEco Studio 有初步使用经验

涉及工具与版本:

  • DevEco Studio(自带 hvigor 6.0.0、ohpm)
  • HarmonyOS SDK API 19
  • Node.js(DevEco Studio 内置)
  • Windows 11 x64

引言:一个 404 引发的连环坑

故事的起点很平凡。我想给鸿蒙 PC Demo 加一个 Markdown 预览页面,习惯性地在 entry/oh-package.json5 中写下了:

"dependencies": {
  "marked": "^12.0.0"
}

marked 是 npm 生态最流行的 Markdown 解析库,全球月下载量超 4 亿次。一个能在 Web、Node.js、Electron 上无障碍运行的库,搬到鸿蒙 PC 上应该也没问题吧?

我按 Ctrl+F9 同步依赖,ohpm 立刻报错:

ohpm ERROR: Run install command failed
Error: 00617101 Fetch Pkg Info Failed
NOTFOUND package 'marked@^12.0.0'
GET https://ohpm.openharmony.cn/ohpm/marked 404

ohpm.openharmony.cn/ohpm/marked —— 这个 URL 返回 404 的那一刻,我才第一次意识到:npm 仓库和 OHPM 仓库是两套完全独立的体系。

一、ohpm 404:为什么换 registry 也没用

遇到 ohpm 找不到包,很多从 Web 转过来的开发者第一反应是"换个 registry 不就行了"——把 ohpm 指到 npmmirror.com。这条路我也试过,结果是换了 npm 仓库之后,项目原本依赖的 @ohos/hypium、@ohos/hamock 测试包立刻报错:这两个只存在于 ohpm 仓库里,npm 上没有。

为什么不能简单混用?原因有三:

第一,仓库格式不同。 OHPM 托管的是 .har(Harmony Archive)格式的鸿蒙原生包,里面包含 ArkTS 编译产物和元数据;npm 是 .tgz(压缩包),里面是纯 JavaScript/TypeScript 源码。marked 从来没有人把它重新打包成 .har 发布,所以 ohpm 仓库里就是不存在。

第二,ohpm 不支持多 registry scope。 不像 npm 可以用 @your-scope 指向私有仓库,ohpm 当前版本只能配置一个全局 registry。在鸿蒙 PC 项目里,ohpm 仓库承载了所有 @ohos/* 基础库和积分赛产出的三方库,换去 npm 会导致基础库全部丢失。

第三,marked v12 在 ArkTS 运行时也跑不通。 即使想办法把 marked 源码拉进来,它还是 ESM-only,并且依赖 URL、TextEncoder、crypto 等 Node 全局对象。Ark Runtime(ArkTS 运行时)对这些并不完全兼容,直接 vendoring 大概率在真机崩溃。

三条堵死了"换 registry + vendoring"的路线。

二、方案决策:自实现 TinyMarkdown

重新审视 MarkdownDemo 页面实际需要展示的语法——就那么几种:标题、有序/无序列表、加粗、斜体、段落。为这 5 个语法引入 30KB+ 的 marked 源码包,维护成本远大于收益。

最终决定:自己写一个轻量级 TinyMarkdown,用纯 ArkTS 实现。

解析思路是状态机 + 正则匹配:

export function parse(src: string): string {
  const lines = src.replace(/\r\n/g, '\n').split('\n');
  const htmlParts: string[] = [];
  let paragraphBuffer: string[] = [];  // 段落缓冲
  let ulBuffer: string[] = [];         // 无序列表缓冲
  let olBuffer: string[] = [];         // 有序列表缓冲
  let inCodeBlock = false;             // 代码块状态

  // flush 函数...

  for (const rawLine of lines) {
    // 代码块切换:```或 ```javascript
    const fence = line.match(/^```\s*(\w*)\s*$/);
    if (fence) { /* 切换状态 */ continue; }
    if (inCodeBlock) { codeBlockBuffer.push(line); continue; }

    // 空行 = flush 所有块
    if (line.trim() === '') { flushAll(); continue; }

    // 依次尝试匹配:标题 → 列表 → 段落
  }
  flushAll();
  return htmlParts.join('\n');
}

200 行 ArkTS,零外部依赖。我额外做了三件生产级防护:

  • HTML 转义防 XSS:把 < > & 自动转义,防止用户输入被当作标签执行
  • 行内代码和代码块支持:code 和 lang\n...\n
  • 13 个 hypium 单元测试:DevEco Studio 内置测试框架,覆盖标题、加粗嵌套斜体、HTML 转义等场景

从 oh-package.json5 移除 marked 声明,import 改成:

import { parse as mdParse } from '../utils/TinyMarkdown';

编译代码开发环境如下:
在这里插入图片描述
编译没有问题:
在这里插入图片描述

跑 ohpm install:

install completed in 0s 47ms

✅ 47 毫秒,零错误。第一关过了。

三、再战:hvigor modelVersion 不兼容

我以为这样就结束了。运行 hvigor assembleHap 时又炸了:

hvigor ERROR: 00303028 Configuration Error
Unsupported modelVersion of Hvigor 6.1.1.
The supported Hvigor modelVersion is 6.0.0.

本机 DevEco Studio 自带的 hvigor 工具版本较旧(只识别 6.0.0),但项目是用新版 DevEco Studio 创建的,所有配置文件里的 modelVersion 都是 6.1.1。

降级 modelVersion(4 个文件)

按报错提示,把所有 modelVersion 从 6.1.1 统一降到 6.0.0:

文件变更
hvigor/hvigor-config.json56.1.1 → 6.0.0
根 oh-package.json56.1.1 → 6.0.0
demo/hvigor/hvigor-config.json56.1.1 → 6.0.0
demo/oh-package.json56.1.1 → 6.0.0

经验:降级时必须以 hvigor-config.json5 为源头,先读它的值,再统一改所有 oh-package.json5 的 modelVersion。不要反过来猜。

第三关:schema 校验又炸了

降级完 modelVersion,hvigor 继续报 AppScope/app.json5 的 schema 校验:

Schema validate failed, at file: AppScope/app.json5
propertyName: 'buildVersion'
message: 'property name must be valid'

这个 buildVersion 字段是新版 DevEco Studio 自动加进去的(我完全没印象自己加过),但 hvigor 6.0.0 的 schema 不认它。直接删掉就行——涉及两个 AppScope/app.json5 文件。

ArkTS 编译 ERROR 逐个击破(5 个)

删完 schema 非法字段后,hvigor 终于进入 ArkTS 编译阶段。编译器一次性抛出 5 个 ERROR,让我一个一个来:

ERROR 1:arkts-no-untyped-obj-literals(TinyMarkdown.ets)

ArkTS 严格模式不允许未声明类型的对象字面量作为 default export。修复:加一个 interface 类型约束:

interface TinyMarkdownDefault { parse: (src: string) => string; }
const defaultExport: TinyMarkdownDefault = { parse };
export default defaultExport;

ERROR 2:scale 属性与基类冲突(DpiMenuDemo.ets)

我写了 private scale(size: number) 函数,但 CustomComponent 基类已经有 scale 属性(链式修饰器 this.scale({ x: 1.5 }))。修复:函数名改成 scaleFont()。

ERROR 3 & 4:distributedKVStore API 签名变更(DistributedNote.ets)

@kit.ArkData 的分布式 KV 存储 API 有两个破坏性变更:

一是 Options 类型新增必填字段 securityLevel:

const options: distributedKVStore.Options = {
  createIfMissing: true,
  encrypt: true,
  backup: false,
  autoSync: true,
  securityLevel: distributedKVStore.SecurityLevel.S3  // 新版必填
};

二是 get() 回调的 value 类型从 distributedKVStore.Value(带 .value 属性的包装对象)变成了 string | number | boolean | Uint8Array 联合类型:

this.kvStore?.get('note', (err, value) => {
  if (!err && value) {
    this.note = typeof value === 'string' ? value : '';  // 类型收窄
  }
});

ERROR 5:鸿蒙 PC 模拟器看不到应用

hvigor 构建通过了,应用装上模拟器但桌面上找不到图标。原因是 entry/src/main/module.json5 的 deviceTypes 只声明了 "phone",没声明 "2in1"。2in1 模拟器上系统不会展示不属于自己 deviceType 的应用。修复:

"deviceTypes": ["phone", "2in1"]

改完这行,应用立刻在鸿蒙 PC 桌面上出现了。

四、验证:BUILD SUCCESSFUL + 真机运行

跑了三轮构建,每一轮的错误都比上一轮少。最终结果:

> hvigor BUILD SUCCESSFUL in 8 s 145 ms
> hvigor Finished :entry:assembleHap... after 1 ms
0 ERROR, 4 WARN(deprecated API 提醒)

hap 文件成功生成在 entry/build/default/outputs/default/entry-default-unsigned.hap。

⚠️ 剩余的 4 个 WARN(router.pushUrl deprecated、getContext deprecated)是系统级 deprecated,需要迁移到新版 NavStack + UIContext 路由系统,改动量较大,征文 Demo 可接受。

DevEco Studio 配置鸿蒙 PC(2in1)模拟器

为了看到鸿蒙 PC 桌面运行效果,需要先在 DevEco Studio 的 Device Manager 里配置:

步骤 1:打开 Device Manager(菜单栏 → Tools → Device Manager,或 Ctrl+Shift+S)

步骤 2:下载鸿蒙 PC 系统镜像(左侧选"二合一"→ 右侧选对应 API 版本 → 点"下载",几个 GB,10~60 分钟)

步骤 3:创建模拟器(点 + New Emulator → Device Type 确认是"二合一"→ Resolution 建议 1920×1080 → Memory 4~8GB → Boot options 选 Quick boot)

步骤 4:启动模拟器(点绿色 ▶️,首次冷启动 1~3 分钟)

步骤 5:运行项目(DevEco 顶部设备下拉框选 2in1 模拟器 → Shift+F10)

鸿蒙 PC 真机截图

下面我们正式看下代码运行的真实效果:

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
ok可以正常运行了。
我们看下markdown的文字识别效果:
在这里插入图片描述

我觉得已经非常好了!

五、总结:鸿蒙 PC 三方库适配的通用方法论

这次踩的连环坑让我对鸿蒙 PC 的构建工具链有了系统认识,总结 五条避坑经验:

经验一:ohpm ≠ npm,先查再用。 ohpm search <name> 能搜到的才可以引入。搜不到的要么找 @ohos 团队打包的 .har,要么自己移植。不要靠换 registry 解决。

经验二:modelVersion 必须与本机 hvigor 版本匹配。 遇到 Unsupported modelVersion 错误先降级,不是越新越好。hvigor-config.json5 是源头,改它再同步所有 oh-package.json5。

经验三:schema 版本降级要清理新版残留字段。 新版 DevEco Studio 自动生成的字段(如 buildVersion)旧版 hvigor 不认,要手动删除。

经验四:ArkTS 比 TypeScript 严格得多。 禁止未声明类型的对象字面量;CustomComponent 基类有大量内置属性(scale、width、height、margin……),不要重名。

经验五:@kit API 升级是破坏性的。 distributedKVStore 等 ArkData 模块,升级时回调签名、必填字段经常变。编译报错是最准确的指引,跟着报错信息一步步改就行。


六、AtomGit 仓库

项目源码已完整托管到 AtomGit,包含 TinyMarkdown v2 源码、hypium 单元测试、所有页面修复后的完整代码、codelog.txt 变更记录。

AtomGit 仓库地址(统一用 AtomGit,不用 GitCode):
https://atomgit.com/wdracky/ohpm

上传 AtomGit 命令参考:

git init
git add .
git commit -m "鸿蒙PC征文Demo:ohpm→hvigor→ArkTS 完整适配"
git remote add origin https://atomgit.com/wdracky/HarmonyPCDemo.git
git push -u origin master

七、作者声明

本文为个人原创,未使用 AI 写作工具生成,内容基于 DevEco Studio 实际开发过程中的真实踩坑记录。所有代码已通过 hvigor assembleHap 完整构建验证,hap 产物可直接部署到鸿蒙 PC(2in1)模拟器运行。


祝大家在 2026 开源鸿蒙大学生创新大赛中取得好成绩!🎉

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值