基于dartle的Flutter构建体系迁移到OpenHarmony的完整实践
如果你也在做鸿蒙化适配应该会遇到一个很尴尬的节点Flutter代码好不容易在鸿蒙设备上跑起来了但工程构建链路还停留在“脚本堆砌”阶段。各种.sh、.bat再加上 CI 平台上的自动化任务项目一多就开始失控。这次我们聊的方案核心是一个叫dartle的 Dart 构建工具它和 Gradle 很像但足够轻量自带任务依赖模型和增量缓存。我花了两周时间把一套基于 dartle 的 Flutter 组件构建体系整体迁移到 OpenHarmony 生态不仅解决了任务编排问题还顺手把 CI/CD 流水线打通了。这篇文章会从整体思路、任务依赖治理、自动化落地到工业级流水线编排完整复盘整个适配过程。如果你正打算把 Flutter 工程迁到鸿蒙或者只是在为“构建脚本越多越难维护”而头疼这篇文章应该能给你一个比较完整的参考方案。1. 鸿蒙化适配的整体思路为什么先从构建工具下手1.1 dartle 在 Flutter 工程中的角色先说说 dartle 是什么。它是用 Dart 写的构建工具核心概念和 Gradle 类似通过声明任务和任务之间的依赖关系构建工具自动推导执行顺序、跳过未变化的任务、并行执行无依赖的任务。对于 Flutter 工程来说默认的flutter build指令只能做最基础的编译打包一旦工程里要生成路由表、解析多环境配置、批量处理平台资源、生成国际化文件就会产生大量“额外能力”的需求。我们团队的 Flutter 组件库原本就是靠 dartle 把这些额外能力串起来的。比如每次构建前要先生成版本文件、自动拉取 pub 依赖、根据配置模板生成不同渠道的 manifest之后再执行flutter build最后归档产物。以前这些都是靠 shell 脚本按顺序跑后来脚本越来越长分支判断越来越多正好用 dartle 做了第一批重构。所以在做鸿蒙化适配之前dartle 已经在我们的 Flutter 构建链路里扮演了“构建调度中枢”的角色。这意味着只要把 dartle 的某个节点替换成鸿蒙编译指令就能让整套构建流水线继续运转而不是另起炉灶。1.2 鸿蒙构建链路的现状与适配切入点OpenHarmony 侧面的构建工具链和 Flutter 原生生态完全不同。Flutter 用flutter build鸿蒙应用要用 hvigor 来做编译打包依赖管理用 ohpm还得处理鸿蒙 SDK 的签名、HAP/HAR 产物路径等逻辑。两边一碰撞最直接的问题是dartle 认识 flutter认识 dart但不认识 hvigor。此时如果只是为了“让代码跑在鸿蒙上”很多人会选择在 dartle 外面再加一层脚本或者干脆在 CI 流水线里写死 hvigor 指令。但这样做的问题是原本 dartle 的任务依赖和增量能力就被绕开了相当于把一个已经治理好的构建系统重新打回脚本堆积的状态。我最后确定了切入点在 dartle 的任务模型里新增一组“鸿蒙原生构建任务”。这些任务内部调用 hvigor 命令行工具但对上层暴露的是 dartle 标准任务接口。上层任务只需要声明依赖关系和输入输出不需要关心底层是调用了flutter build还是调用了hvigor assembleHap。这样一来原有的构建编排能力、缓存能力、日志能力都能无缝覆盖到鸿蒙构建链路也正是这次适配最核心的价值。1.3 方案选型自研脚本、直接调用 hvigor、还是改造 dartle在正式动手前我把可选方案对比了一遍避免一开始就走错方向。第一个方案是自研脚本也就是写一套 Python 或者 Bash 脚本来替代 dartle。这个方案看起来自由度高但我在评估时否掉了。原因很简单脚本难以表达复杂的任务依赖关系一旦并行构建、失败重试、产物缓存这些需求出现脚本会越来越像意大利面条。第二个方案是在 CI 流水线里直接调用 hvigor。优点是实现最快缺点也很明显流水线被具体构建细节污染而且本地开发时依然没有统一的构建入口。团队成员在本地跑一条命令能完成的构建在 CI 上却要拆成三步五步非常容易“本地能过CI 挂了”。第三个方案也就是我最终采用的方案在 dartle 里封装鸿蒙构建任务。dartle 本身是 Dart 生态的工具Flutter 和鸿蒙侧都支持命令行调用所以只需要新增一个任务类型负责把 dartle 的标准输入输出转换成 hvigor 需要的参数。这个方案做得越早后续接入 CI/CD 时就越省事。事实上我在流水线侧就只暴露了一个dart run dartle -Ptargetharmony -Pmoderelease命令流水线根本不需要知道 hvigor 的存在。2. 任务依赖治理构建大坝的基石2.1 “构建大坝”的核心把隐式依赖变成显式依赖标题里用了“构建大坝”这个比喻我很喜欢。大坝的本质是调节水流构建系统的本质则是调度任务流。如果任务之间的先后顺序只靠脚本里的连接那这个顺序就是隐式的、脆弱的。脚本一旦改动很可能某个原本靠“运气顺序”工作的任务就会被破坏。在鸿蒙化适配过程中我做的第一件事就是把所有构建步骤拆成最小任务单元然后用依赖关系重新拼起来。例如在原本的脚本链路里hvigor 打包前必须完成 flutter 依赖拉取、路由表生成、ohpm 依赖安装、SDK 路径设置但脚本只保证了“当时的执行顺序正确”并没有把这些关系固化下来。用 dartle 重构后每个任务节点都显式声明了dependsOn。这样即便将来要调整任务顺序也只需要看依赖声明表而不是读几百行脚本逻辑。更重要的是显式依赖让构建系统具备真正的“调节能力”某个上游任务失败下游任务自动不执行没有依赖关系的任务可以并行任务之间也可以插入缓存校验。2.2 显式声明任务依赖的示例这里给出一个简化版的 dartle 任务声明用来表达核心思路。dartle 的任务定义基于 Dart 代码在setup.dart里配置这段代码虽然我做了简化但依赖关系的写法是核心。import package:dartle/dartle.dart; void main() { task(version) { do { run(dart, args: [run, tool/gen_version.dart]); } }; task(pubGet) { dependsOn(version); do { run(flutter, args: [pub, get]); run(ohpm, args: [install]); } }; task(genRoute) { dependsOn(pubGet); do { run(dart, args: [run, tool/gen_route.dart]); } }; task(compileHarmony) { dependsOn(pubGet, genRoute); do { run(hvigor, args: [assembleHap, --mode, release]); } }; }关键点在于compileHarmony不再关心pubGet内部做了什么只声明依赖它。pubGet自身又依赖version。这样一来哪怕是新加入的鸿蒙编译任务也能直接复用已有的依赖体系。2.3 并行度控制不是任务定义完就万事大吉任务依赖关系建好之后dartle 会自动对无依赖的任务做并行执行。这在提升构建速度时有立竿见影的效果但也带来一个鸿蒙适配阶段特别容易踩的坑并行执行的任务之间可能会互相抢资源。鸿蒙构建工具 hvigor 在编译时会有自己的缓存和锁机制如果多个 hvigor 任务同时跑很容易出现文件锁冲突或者内存占用过高导致构建进程被杀死。这里的经验是要对鸿蒙编译任务单独设置并发限制而不是盲目使用全局的默认并行值。我到最后是把并发数调整为 CPU 核数的一半并且在鸿蒙编译任务内部加了一个“互斥”逻辑确保同一时间只有一个 hvigor 实例在执行。虽然这会让鸿蒙侧的任务并行度下降但换来的是构建稳定性的明显提升。对于需要大内存的编译任务稳定压倒一切。除了并发限制还建议给每个任务标记timeout和retry的次数。特别是依赖安装类任务网络抖动导致的失败非常普遍这时候可以允许重试两次。我一般不会给编译类任务开重试因为编译错误重试多少次都会失败重试反而会掩盖真正的日志线索。3. 全链路自动化落地从编译到产物分发3.1 封装鸿蒙编译任务的参数传递依赖治理只是第一步真正让整套流水线跑起来是把鸿蒙编译指令封装成 dartle 的任务并且处理好参数传递。hvigor 执行时需要知道很多关键参数包括编译模式release 或 debug、目标设备架构、签名文件路径、以及鸿蒙 SDK 的安装位置。在 dartle 里这几个参数可以通过任务输入input声明也可以通过 Dart 的环境变量传入。我的做法是将 SDK 路径放在一个harmony.env配置文件中并在任务里统一读取。CI 流水线的环境变量只负责覆盖默认值这样本地开发和 CI 行为完全一致。这里需要注意一个细节hvigor 默认依赖 node 运行时。在本地开发环境里往往没问题但 CI 的构建镜像里很容易漏掉。所以我在compileHarmony任务执行前加了一步环境检测检查命令node --version能否正常执行如果检测失败就直接输出一条明确的错误提示而不是让 hvigor 自己报一个莫名其妙的错误。3.2 产物、缓存与增量构建构建工具的价值很多时候体现在增量构建上。源代码没变化时跳过不必要的编译这在大项目里能节省大量时间。dartle 支持定义 input 和 output 文件。当一个任务声明了输入文件列表和输出文件列表dartle 会根据文件哈希和时间戳判断是否需要重跑。在鸿蒙适配中我是这样处理产物和缓存的输入是路由配置文件、pubspec.yaml、oh-package.json5、源码目录的代码文件输出是 HAP 产物路径、生成的路由表文件、缓存文件目录每次执行时dartle 会比较输入文件的哈希。如果哈希没变而且输出文件已存在就跳过这个任务。第一版适配的时候我在产物路径上踩了坑。Flutter 构建输出默认在build目录而 hvigor 输出默认在entry/build/default/outputs目录。如果 dartle 的输出声明和实际 hvigor 输出目录不一致缓存判断就会失效——文件已经变了dartle 却认为没变结果 CI 上生成了陈旧产物。解决办法是给 hvigor 增加一个参数把产物输出目录重定向到工程根目录下的harmony_out然后 dartle 的输出声明也指向这个目录。这样两边就能保持同步缓存判断也准确了。3.3 自动化校验与质量门禁全链路自动化不能只停留在“能编译出包”。对我来说构建链路的末端应该有一个质量门禁任务这个任务会把所有质量检查都挂进来只有全部通过才算构建成功。在这个项目里我在 dartle 的任务图上挂了四个质量检查任务单元测试、静态代码检查、路由表完整性检查、签名产物存在性检查。这些任务都作为qualityGate的前置依赖而qualityGate又依赖compileHarmony。这样构建流程结束时如果qualityGate没有执行过或者执行结果不是成功CI 就判定这次构建失败。这比在 CI 流水线里“手动拼步骤”要强得多。因为所有任务都在 dartle 这一层治理质量门禁可以复用同一套依赖和缓存逻辑。比如如果源码没变化静态检查任务会直接跳过而不需要重跑一遍这在 CI 上节省的成本非常明显。4. 工业级 CI/CD 编排方案4.1 流水线接入只暴露一条命令有了 dartle 这一层“构建大坝”CI/CD 编排就变得非常简单了。我在流水线里的核心步骤只有一条dart run dartle -Ptargetharmony -Pmoderelease这里的-P参数会被 dartle 解析成构建参数然后下发到各个任务。流水线不需要关心任务内部是调用flutter build还是hvigor assembleHap也不需要知道路由表怎么生成。这样做的好处是流水线配置和鸿蒙构建细节彻底解耦即使鸿蒙工具链之后发生变化也只需要改 dartle 任务流水线配置可以保持不变。对于多模块项目我建议在流水线里增加一个模块列表的输入参数dartle 接收后会动态创建一组相同模板的构建任务并给每个任务打上模块名标记。这样就能用同一套构建框架支撑多个 Flutter 组件同时构建CI 日志里也更容易区分每个模块的执行情况。4.2 高可用与失败重试机制工业级编排重点不是“能跑通”而是“跑得稳”。在我们实际运行过程中鸿蒙构建任务偶尔会因为下载工具链超时、缓存目录清理不及时等原因失败。对于这类“非代码故障”必须在任务层面做好重试。我在 dartle 里给依赖安装任务设置了重试条件当任务报错信息包含“network timeout”或“ohpm 下载失败”时自动重试最多 3 次每次间隔 5 秒。如果重试后仍然失败再终止整个构建。但要注意重试不能滥用。编译错误、代码格式化问题、资源缺失这些问题重试多少次都一样反而会因为反复执行而浪费时间。我的建议是给每个任务分类纯环境类任务允许重试编译类任务一律不重试而是直接输出完整错误日志。这样流水线的失败率会下降同时也不会因为过度重试而掩盖真正的问题。4.3 可观测性日志聚合与指标监控构建系统一旦接入 CI可观测性就是隐形需求。以前用脚本时出了问题就只能打开 CI 日志一点点翻。现在我用 dartle 的任务模型可以给每个任务输出结构化日志至少包含任务名、任务开始时间、结束时间、耗时、执行结果、输入文件哈希、输出产物大小。有了这些结构化数据就能在 CI 系统里加一个简单的看板每次构建结束后把耗时数据写入时间序列数据库然后展示最近 50 次构建的耗时趋势。哪个任务突然变慢通过趋势图一眼就能看出来。另外依赖图和耗时数据是可以结合分析的。比如有一次我发现compileHarmony任务耗时翻了一倍单独看任务日志看不出异常后来把依赖图拉出来发现上游genRoute任务多生成了一些文件导致 hvigor 的增量缓存失效。如果没有结构化日志这种问题就得靠猜了。5. 常见问题与排雷实录5.1 问题速查表这次鸿蒙化适配过程中我记录了几个高频问题整理成了一份速查表后续团队遇到类似情况可以直接参考问题现象可能原因排查方向与解法hvigor 构建报错提示找不到 HAP 产物hvigor 实际输出目录和 dartle 声明不一致把 hvigor 输出重定向到一个固定目录并同步更新 dartle 的 output 声明dartle 缓存看起来总是不命中input 声明范围太宽把易变文件也纳入了只把真正影响构建结果的源码和配置加入 input排除临时目录CI 执行 hvigor 时提示命令不存在CI 镜像缺失 node 或 hvigor 工具链在任务前增加环境检测输出明确缺失项并行执行时偶发文件锁冲突多个 hvigor 任务同时操作同一缓存目录限制鸿蒙编译任务的并发数或给该任务加互斥锁重试任务后构建日志缺失重试导致同类日志被覆盖输出日志按次数后缀区分保留每次重试的独立日志文件这张表看起来简单但每一条背后都是真实踩过的坑。特别是输出目录不一致那个当时在本地验证没问题上了 CI 就偶尔出现缓存失效排查了一个多小时才发现是 HAP 输出目录没有被稳定重定向。5.2 三个容易踩的坑第一个坑任务依赖声明不全导致“偶发失败”。有一次构建偶尔在genRoute之后直接开始在compileHarmony但有时又正常。最后发现是因为genRoute和compileHarmony之间的依赖关系没有显式声明dartle 默认认为二者互不依赖就并行执行了。由于生成路由文件的速度不稳定hvigor 有时能读到新文件有时读不到。这个问题靠加一行dependsOn就解决了但如果不理解依赖模型排查起来会非常痛苦。第二个坑缓存目录权限问题。dartle 默认会在~/.dartle/cache下保存增量信息CI 平台的沙箱环境有时候没有这个目录的写入权限。刚开始 CI 一直出现“无法更新缓存”的神秘报错后来我直接把缓存目录改到项目工作区下的.dartle_cache并设置.gitignore忽略问题才消失。第三个坑环境变量在本地和 CI 不一致。鸿蒙 SDK 路径我在本地是写死的团队其他人 clone 工程后跑不出来。后来统一改成从OHOS_SDK_ROOT环境变量读取如果没有这个变量再从配置文件读取。这样每个人都只维护一份环境配置构建行为就完全一致了。5.3 我的几点心得体会这次适配下来我最大的感受是鸿蒙化适配不只是让 Flutter 代码跨平台更是让构建链路跨平台。很多团队在移植 Flutter 组件时只关注编译期和运行期的兼容性忽略了构建工具链的差异结果代码层面跑通了交付和集成环节却被脚本拖了后腿。如果让我重来一次我会更早地用 dartle 做统一构建入口甚至在 Flutter 工程创建初期就规划好任务依赖。因为构建工具的迁移成本会随着任务数量增长而快速上升越早治理后续收益越大。最后分享一个实用的扩展思路我在适配完成之后给 dartle 增加了一个“产物聚合任务”它会把 Flutter 生成的增量产物和鸿蒙侧生成的 HAP 产物都拷贝到一个统一归档目录再按版本号和时间戳命名。这样不管是在本地开发还是在 CI 流水线里都能固定路径取到最新产物下游分发和归档环节就不再依赖具体构建工具的输出位置了。这个思路看起来简单但真正解决了多平台构建产物管理混乱的痛点。如果你也要做类似的多端构建适配可以考虑参考这个设计。

相关新闻

WorkBuddy+WebView+Supabase:三周上线跨平台App实战与16个坑

WorkBuddy+WebView+Supabase:三周上线跨平台App实战与16个坑

1. 为什么我选择用 WorkBuddy 从零搭一个能上线的 App去年年底我接了个私活,帮一个做线下活动的小团队搭一套内部用的报名和签到工具。预算不高,工期只有三周,对方的要求却很实在:安卓和 iOS 都要能用,数据要能实时同步…

2026/10/15 7:33:58 阅读更多 →
基于Elasticsearch的高校科研系统:检索架构与实现要点

基于Elasticsearch的高校科研系统:检索架构与实现要点

1. 这个毕业设计题目好在哪:从课题价值说起每年到了毕业设计开题的时候,总有不少同学在选题上纠结很久。说实话,管理系统的题目写烂了,图书馆管理系统、学生选课系统、超市进销存系统这些基本属于“答辩老师看一眼就想翻篇”的类型…

2026/10/15 7:33:58 阅读更多 →
artcraft:本地优先的创作辅助工具,从素材管理到多形态输出

artcraft:本地优先的创作辅助工具,从素材管理到多形态输出

1. 项目缘起与整体设计思路第一次看到“artcraft”这个标题,我脑子里蹦出来的第一反应是“艺术”加“手艺”的组合词。直觉告诉我,这大概率是一个跟创意工具、手工制作、或者数字艺术创作沾边的项目。后来跟几个做独立开发的朋友聊了聊,发现大…

2026/10/15 7:33:58 阅读更多 →

最新新闻

Python期末复习冲刺:高频考点与易错点全梳理

Python期末复习冲刺:高频考点与易错点全梳理

简介:这份Python期末复习资料面向中小学(K12)阶段学习者,将散落教材中的基础语法与常见考点浓缩成一份可快速翻阅的速查手册,既能用于期末冲刺,也适合日常查漏补缺。资源为单份docx格式,共1个文…

2026/10/15 8:06:12 阅读更多 →
微信小程序餐饮订餐系统架构设计与优化实践

微信小程序餐饮订餐系统架构设计与优化实践

1. 项目背景与核心价值最近两年,我观察到身边越来越多的餐饮商家开始从传统电话订餐转向小程序订餐系统。这种转变不仅仅是技术升级,更反映了餐饮行业数字化转型的必然趋势。去年帮朋友改造他的快餐店管理系统时,我深刻体会到微信小程序在餐饮…

2026/10/15 8:06:12 阅读更多 →
artcraft创作工具定位与手工项目工作流搭建指南

artcraft创作工具定位与手工项目工作流搭建指南

1. 从"artcraft"这个名字说起:一个被低估的创作工具定位问题第一次看到"artcraft"这个标题的时候,我脑子里冒出来的第一个念头是:这到底是一个艺术创作工具,还是一个手工艺平台?名字本身把"a…

2026/10/15 8:06:12 阅读更多 →
Blender 5.0核心升级:ACES渲染与Geometry Nodes深度解析

Blender 5.0核心升级:ACES渲染与Geometry Nodes深度解析

1. Blender 5.0核心升级概览作为开源3D创作套件的里程碑版本,Blender 5.0带来了两项革命性更新:ACES/HDR渲染管线重构与Geometry Nodes功能体系全面升级。这两个方向的改进直接解决了影视级流程对接和程序化建模两大行业痛点。在影视动画领域&#xff0c…

2026/10/15 8:06:12 阅读更多 →
鸟哥Linux私房菜第四版基础篇:从CPU内存到SELinux实战避坑

鸟哥Linux私房菜第四版基础篇:从CPU内存到SELinux实战避坑

简介:《鸟哥的Linux私房菜-基础篇》第四版是一份面向Linux初学者的入门电子书,适合具备基本计算机操作能力、希望系统掌握Linux概念与常用工具的读者,也可供有一定经验的IT技术人员查漏补缺。内容从计算机组成与操作系统原理讲起,…

2026/10/15 8:06:12 阅读更多 →
Spring Boot电商库存管理系统设计与优化实践

Spring Boot电商库存管理系统设计与优化实践

1. 项目概述这个库存管理系统是我去年为一家中型电商企业开发的内部管理工具,核心目标是解决他们长期存在的库存数据不准确、人工盘点效率低下问题。系统采用Spring Boot框架开发,前后端分离架构,对接了企业现有的ERP系统,实现了从…

2026/10/15 8:05:10 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →