跨平台前端移动开发OpenHarmony【免费下载链接】flutter_flutter本仓库是 Flutter SDK 与 Flutter Engine 的 OpenHarmony 适配版本由 CPF-Flutter 团队维护。开发者可使用熟悉的 Flutter 技术栈开发 OpenHarmony 应用3.35.7 及以后的适配版本可基于本仓库源码构建支持 OpenHarmony 的 Flutter Engine。项目地址https://gitcode.com/CPF-Flutter/flutter_flutter点击查看免费下载本文面向 flutter_flutterFlutter 的 OpenHarmony 适配版本的贡献者与二次开发者系统讲解flutter工具模板中图片资源的维护机制为什么图片不能直接提交进主仓库、flutter_template_imagesPub 包在其中扮演的角色、以及新增/更新模板图片时需要在flutter/packages与flutter/flutter两个仓库分别执行的完整操作步骤。读完本文你将掌握.img.tmpl占位符与template_manifest.json清单的配合方式并能独立完成一次模板图片的发布与回滚。为什么模板图片不直接入库flutter工具在生成新项目flutter create时会向目标工程写入大量模板文件其中包含各平台的图标、启动图等二进制资源如 iOS 的AppIcon、macOS 的应用图标、Windows 的app_icon.ico、Web 的 maskable icon 等。这些图片资源并没有直接存放在 flutter_flutter 主仓库中而是统一维护在flutter_template_images这个 Pub 包内。这一设计有两个直接原因Presubmit 检查禁止二进制文件入库。主仓库的静态检查verifyNoBinaries见 dev/bots/analyze.dart会逐个读取 Git 跟踪文件并以 UTF-8 解码凡无法解码为合法 UTF-8 的内容都被判定为二进制而报错。该检查的错误提示中明确写着All files in this repository must be UTF-8. In particular, images and other binaries must not be checked into this repository并直接引用本指南作为解决方案。仓库体积与升级成本。二进制文件会显著增大仓库体积且每次更新都会产生巨大的 diff。flutter_flutter 仓库会随版本被广大开发者同步执行flutter upgrade时需要对整个 Git 历史做增量同步体积膨胀会直接拖慢所有人的升级体验。而从 Pub 拉取一个包只需下载对应版本内容不涉及 Git 历史的全量同步明显更轻量。从本仓库的实际结构也能印证这一点以 packages/flutter_tools/templates/app/ios.tmpl/Runner/Assets.xcassets/AppIcon.appiconset 为例目录下只有Contents.json是真实文件而Icon-App-20x201x.png.img.tmpl、Icon-App-1024x10241x.png.img.tmpl等所有图标都只是零字节占位符真正的内容在flutter_template_images包中。双仓库工作流总览新增或更新模板图片需要同时提交两个补丁patch分别落在两个仓库flutter/packages 仓库修改flutter_template_images包把真实图片文件放入其templates目录并发布新版本到 Pub。flutter/flutter 仓库即本仓库把依赖版本提升到新发布的版本同步添加占位符与清单条目让flutter工具在生成项目时能正确解析到新图片。flutter_template_images包内的templates目录布局与 flutter_flutter 仓库中flutter_tools包下的 templates 目录完全一致先向flutter_template_images提交真实图片再回滚进主仓库保证两处路径一一对应。回滚时flutter_tools包中的占位文件只是同名零字节文件文件名含.img.tmpl后缀真实二进制仍留在 Pub 包里。第一步向 flutter_template_images 添加资源1. 分叉 flutter/packages 仓库在 GitHub 上 fork flutter/packages 仓库若未配置 GitHub 亦可参考该仓库的本地镜像流程在本地检出后进入packages/flutter_template_images目录操作。2. 按目标路径放置图片将图片放到templates目录下与 flutter_flutter 主仓库对应的相对路径。命名规则有三点要求文件名必须与flutter工具生成项目后的最终文件名完全一致因为模板渲染时不会做任何改名不要包含.img.tmpl后缀——该后缀只出现在主仓库的占位符中真实图片文件用的是最终名例如主仓库占位符是app_icon.ico.img.tmpl包内真实文件就叫app_icon.ico目录层级要与flutter_tools/templates严格对齐例如 iOS 图标要放在templates/app/ios.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/下。3. 升级 pubspec.yaml 版本号编辑该包的pubspec.yaml版本号为major.minor.patch三段式规则是新增图片资源递增 minor 版本如5.0.0→5.1.0仅更新已有图片递增 patch 版本如5.0.0→5.0.1。这个规则与本仓库中flutter_template_images的 pin 位置相互印证主仓库pubspec.yaml中声明flutter_template_images: 5.0.0见 packages/flutter_tools/pubspec.yaml同时手工 pin 集中在kManuallyPinnedDependencies表中注释写明Must always exactly match flutter_tools template见 packages/flutter_tools/lib/src/update_packages_pins.dart。4. 更新 CHANGELOG.md在包的CHANGELOG.md顶部为本次版本新增一个标题条目并添加一行描述变更内容。格式遵循 docs/ecosystem/contributing/README.md#changelog-style 的规范该目录页同时说明了 packages 仓库采用持续发布模型、绝大多数发布型变更都必须更新版本号与 CHANGELOG 的纪律。5. 提交并发送 Pull Request提交改动建议仅包含图片、版本号、CHANGELOG 三类文件推送后发送 PR。合入后post-submit 作业会自动把新版本发布到 Pub无需手动执行发布命令。你可以在flutter_template_images包页面Pub 上的Versions标签页确认新版本是否已成功发布——只有发布成功后主仓库才能依赖到它。第二步将变更回滚进 flutter_flutter 主仓库新版本在 Pub 发布后开始在 flutter_flutter 仓库中回滚。1. 分叉 flutter/flutter 仓库并更新依赖 pinfork flutter_flutter 仓库后需要修改依赖版本声明。原指南指向update_packages.dart而在当前仓库中手工固定pin的依赖统一集中在 packages/flutter_tools/lib/src/update_packages_pins.dart 的kManuallyPinnedDependencies表中把flutter_template_images的条目从旧版本改为新版本。同时 packages/flutter_tools/pubspec.yaml 中的依赖声明也会随之更新。需要特别强调的是该表中的 pin必须是精确版本而非版本范围源码注释明确指出 ranges 会使 CI 随机失败并可能让用户无法升级 Flutter因此这里必须写入与包版本完全一致的精确版本号。2. 运行依赖更新命令在仓库根目录执行flutter update-packages --force-upgrade该命令会基于kManuallyPinnedDependencies重新解析并锁定额外依赖。从 packages/flutter_tools/lib/src/commands/update_packages.dart 的源码可以看到--force-upgrade是UpdatePackagesCommand的核心旗标之一文件头部的注释还说明Pub 包的例行升级由flutter-pub-roller-bot通过flutter update-packages --force-upgrade自动完成人工执行时同样走这条命令。3. 添加零字节占位文件对于你在flutter_template_images中新增的每一个图片文件都在flutter_tools包的 templates 目录的对应位置放一个零字节文件文件名加上.img.tmpl后缀。例如新增 iOS 启动图就在templates/app/ios.tmpl/Runner/Assets.xcassets/LaunchImage.imageset/下创建LaunchImage.png.img.tmpl。零字节占位的好处是不携带任何二进制内容能通过 UTF-8 检查模板引擎看到.img.tmpl后缀时也不会对其做 mustache 渲染而是从图片包中复制真实文件覆盖它。4. 更新 template_manifest.json编辑 packages/flutter_tools/templates/template_manifest.json在files数组中为每个新增文件添加一条记录路径必须包含.img.tmpl后缀。该清单文件的_comment字段说明了对应关系Files ending in .img.tmpl correspond to files checked in to the flutter_template_images package ... located at the same path, excluding the .img.tmpl suffix.清单的作用在 packages/flutter_tools/lib/src/commands/create_base.dart 中体现_computeTemplateManifest()读取该 JSON把所有files条目解析为绝对路径 URI 集合随后 packages/flutter_tools/lib/src/template.dart 在遍历模板目录时会跳过清单中不存在的文件从而清理掉flutter_tools目录里的过期文件。这保证了清单驱动模板的一致性。5. 测试运行并提交 PR提交改动后先在本仓库内实际执行一次模板生成做冒烟测试确认新图片能被flutter工具正确产出到生成的项目中。验证无误后再发送 PR。若 PR 中缺少占位符或清单条目CI 会拦截集成测试 packages/flutter_tools/test/integration.shard/template_manifest_test.dart 会递归扫描templates目录中的所有文件并与template_manifest.json声明的清单求差集任何存在但未声明的文件都会导致manifest and template directory should be in-sync断言失败。模板引擎如何消费图片资源理解.img.tmpl的语义对排查问题很有帮助。模板渲染的核心实现在 packages/flutter_tools/lib/src/template.dart其类注释定义了整套后缀约定后缀含义.tmpl需要 mustache 渲染后写出.copy.tmpl无需渲染直接按原样复制.img.tmpl从flutter_template_images包复制对应图片.test.tmpl仅当启用--implementation-tests时才包含在渲染流程Template.render见 template.dart中凡源文件以.img.tmpl结尾引擎会遍历imageSourceDirectories找到去掉.img.tmpl后缀后的相对路径对应的真实图片文件直接copySync到目标位置若找不到则抛出Image File not found的 ToolExit。目标文件路径在写出前会把.tmpl、.copy.tmpl、.img.tmpl、.test.tmpl后缀全部剥掉见 template.dart所以最终工程里出现的是干净的真实文件名。图片目录的定位逻辑在TemplatePathProvider.imageDirectory见 template.dart它读取flutter_tools/.dart_tool/package_config.json按包名flutter_template_images找到packageUriRoot取其父目录下的templates目录作为图片根目录。换言之图片解析完全依赖 Dart 包配置——这也解释了为什么主仓库必须先升级依赖并重新执行update-packages否则新图片根本无法被解析。同样的思路也出现在 iOS 打包逻辑中IOSApp注释写明Template assets images are in flutter_template_images package见 packages/flutter_tools/lib/src/ios/application_package.dart。本仓库的适配现状与验证线索作为 OpenHarmony 适配版本flutter_flutter 保留了整套图片资产管理机制同时扩展了 OpenHarmony 模板。可以从以下几处快速验证当前状态依赖 pinflutter_template_images: 5.0.0同时出现在 pubspec.yaml 与 update_packages_pins.dart 中且注释强制要求与模板严格同步。占位符分布find可列出 packages/flutter_tools/templates 下全部.img.tmpl占位符覆盖 iOSIcon-App-*、LaunchImage*、macOSapp_icon_*、Windowsapp_icon.ico.img.tmpl、WebIcon-maskable-*.png.img.tmpl等平台。清单文件template_manifest.json 中templates/app/ohos.tmpl/...、templates/module/ohos/...、templates/plugin/ohos.tmpl/...等 OpenHarmony 模板条目已被纳入files数组与适配版模板共存。渲染过滤在 template.dart 的renderPath中ohos与android、ios、web、linux、macos、windows并列只有创建 OpenHarmony 工程--platformsohos场景时ohos.tmpl目录下的内容才会被展开说明 OpenHarmony 模板已深度融入同一套模板管线。从源码结构还可以看到OpenHarmony 模板目录如templates/app/ohos.tmpl/AppScope/resources/base/media/app_icon.png、entry/src/main/resources/base/media/icon.png当前以真实 PNG 文件直接放在templates目录下并由清单直接列出未采用.img.tmpl占位方式与 iOS/macOS 等平台的占位符策略有所不同——这是适配版当前的实际情况后续若要统一管理 OH 图标资源可参照本文工作流迁移到flutter_template_images。小结模板图片资产的维护是一条清晰的包内放真图、仓库放占位的双仓库流水线在flutter_template_imagesflutter/packages按最终文件名放置真实图片按新增 minor / 更新 patch规则升级版本更新 CHANGELOG合入 PR 后由 post-submit 自动发布到 Pub在 flutter_flutter 主仓库更新精确版本 pin集中在kManuallyPinnedDependencies执行flutter update-packages --force-upgrade为每张图片添加同名零字节.img.tmpl占位符并在 template_manifest.json 中登记清单条目依赖template_manifest_test.dart与verifyNoBinaries等 CI 检查兜底确保清单与目录同步、仓库不混入二进制。掌握这套流程后无论是为 flutter_flutter 的 OpenHarmony 模板补充图标还是为既有平台模板替换应用图标都能以最小的仓库体积代价、最快地让flutter create生成出带新资源的工程。赞分享跨平台前端移动开发OpenHarmony【免费下载链接】flutter_flutter本仓库是 Flutter SDK 与 Flutter Engine 的 OpenHarmony 适配版本由 CPF-Flutter 团队维护。开发者可使用熟悉的 Flutter 技术栈开发 OpenHarmony 应用3.35.7 及以后的适配版本可基于本仓库源码构建支持 OpenHarmony 的 Flutter Engine。项目地址https://gitcode.com/CPF-Flutter/flutter_flutter点击查看免费下载相关推荐Espanso资源管理终极指南高效处理图片、模板与资产的完整攻略Espanso资源管理终极指南高效处理图片、模板与资产的完整攻略 Espanso作为一款跨平台文本扩展工具不仅能帮你快速输入常用文本还能高效管理各类资源。桌面应用CLIFlutter 模板镜像资源管理指南flutter_template_images、.img.tmpl 占位符与模板清单机制Flutter 模板镜像资源管理指南flutter_template_images、.img.tmpl 占位符与模板清单机制 flutter create 生跨平台移动开发前端UI组件桌面应用Novu 仓库并行实现工作流基于 Git worktree 的垂直切片Vertical Slice多 Agent 协作指南Novu 仓库并行实现工作流基于 Git worktree 的垂直切片Vertical Slice多 Agent 协作指南 本文讲解 Novu 开源仓库内后端消息路由前端通信AI Agent上一篇Wireshark自动化测试终极指南环境变量配置与CI集成完整教程下一篇Metalsmith环境变量配置开发/生产环境无缝切换方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考