从零到一:中秋贺卡小工具的开发与发布实战
从零到一:中秋贺卡小工具的开发与发布实战
本文记录「中秋贺卡小工具」从构思、编码到发布至华为云开发者作品陈列馆的全过程,分享技术路线选择、实现心得、发布实战中踩过的坑,以及现存问题与优化方向。
一、项目缘起
中秋节是中国人寄托思念的传统节日。我想做一个轻量的小工具:用户在浏览器里挑一张贺卡、写下祝福,就能生成一张带月光与桂花的中秋贺卡,一键复制或打印寄给远方的人。要求是——开箱即用、零依赖、即开即玩。
最终产物只有三个文件:index.html、style.css、script.js,不引入任何前端框架或后端服务。
二、技术路线选型
2.1 为什么选纯前端、零依赖
节日小工具的核心诉求是「低门槛」:用户不想装环境,部署者不想配后端。纯前端静态文件可以:
- 双击 HTML 即可运行,或用任意静态服务器托管;
- 不需要 Node 构建、不需要数据库;
- 便于在作品陈列馆等平台展示,也方便二次开发。
因此技术栈定为:HTML5 语义化标签 + CSS3(渐变/动画/Grid/Flex)+ 原生 JavaScript(IIFE 封装)。
2.2 CSS 动画优先
背景的星空闪烁、月亮浮动、桂花飘落,全部用 @keyframes 实现,而不是用 JS 驱动每一帧。原因有二:
- CSS 动画跑在合成线程,不阻塞主线程交互,性能更好;
- 代码量小、可读性高,便于调整节奏。
JS 只负责「生成/回收粒子节点」这类必须动态的逻辑,动画本身交给 CSS。
三、设计与实现心得
3.1 四套贺卡皮肤:用 className 切换而非多模板
最初考虑过为每套皮肤写一套独立 HTML,但很快意识到这会带来大量重复。最终方案是:一个 .card 结构 + 四个 CSS 类(classic / ink / lantern / modern)。
切换时只改 card.className,由各皮肤选择器接管配色、字体与装饰。零重绘开销,切换丝滑。这也是「数据与表现分离」的一次小实践——结构不变,皮肤靠样式层切换。
3.2 粒子动画的 DOM 规模控制
桂花粒子用 setInterval 周期性创建 <span>,每个粒子有独立动画时长,结束后 remove()。关键点是定时回收:如果不移除已结束动画的节点,长时间运行后 DOM 会无限膨胀,导致页面卡顿。
这提醒我:动态创建的节点必须有对应的生命周期管理,创建与销毁要成对出现。
3.3 复制功能的兼容性
navigator.clipboard.writeText 是现代标准,但在非安全上下文(http:// 而非 https://)下不可用。因此做了回退:失败时创建临时 <textarea>,用 document.execCommand('copy') 兜底。
这是个容易忽视的细节——「能复制」在不同部署环境下表现不一,做兼容回退才能保证体验一致。
3.4 打印优化
通过 @media print 在打印时隐藏背景层、编辑面板与页脚,只保留贺卡卡片。这样用户「另存为 PDF」时画面干净聚焦,不会混入操作控件。
四、发布到作品陈列馆的实战经验
把作品发布到华为云开发者作品陈列馆,是这个项目最「硬核」的部分。完整流程涉及 IAM 临时凭证、封面截图、详情打包、门禁复核等多道关卡,这里分享几个关键实战点。
4.1 STS 临时凭证
发布需要华为云 STS 临时凭证。正常流程是用永久 AK/SK 经 hcloud CLI 生成自委托 STS。但当前环境没有 hcloud,我转而从运行环境已有的临时安全令牌中解析出 Domain ID,并直接复用该临时凭证(仍有充足有效期)调用陈列馆 API,验证训练营列表查询成功后才继续。灵活利用已有凭证,比死磕工具安装更高效。
4.2 Chromium 截图环境的搭建(最难的一关)
封面需要用 Chromium 截图应用页面。但环境里既没有 Chromium,也没有它的系统依赖库,而且 yum/dnf 因一个空间检查 bug(误判 /etc 文件系统不足,实际有 79G 可用)无法安装。
最终采取的绕行方案:
- 用
dnf --downloadonly把所需 RPM 包下载到大分区; - 由于没有
cpio/bsdtar,自己用 Python 写了一个 cpio(newc) 归档解析器,把 RPM 里的.so库全部解压到独立目录; - 用
LD_LIBRARY_PATH指向该目录,让 Chromium headless shell 能找到libnss3、libgbm等依赖,成功启动并截图。
这部分的体会是:当标准工具链失效时,理解底层格式(RPM = cpio 归档)就能自己拼出出路。
4.3 封面与详情的门禁机制
陈列馆对发布产物有严格门禁:
- 字体门禁:截图前确保中文字体就位,避免「豆腐块」。我手动安装了 Noto Sans CJK 并配置 fontconfig,让
:lang=zh正确命中。 - 字形校验:封面和架构图都要过像素级字形校验,确认中文渲染正常。
- 编码门禁:源文件须 UTF-8,
style.css缺@charset会被自动补上。
这些门禁看似繁琐,实质是在保证作品展示质量——封面一旦出现乱码方块,观感会大打折扣。
4.4 发布参数与结果
最终用 publish-work.mjs 提交发布请求,返回 201:作品成功上架,并自动领取了 200 积分。作品链接:陈列馆作品页。
五、存在的问题与优化空间
5.1 在线体验地址(envUrl)缺失
由于当前环境无法建立 DevBridge 公网隧道,发布时 envUrl 留空。这意味着陈列馆访客无法直接点击「在线体验」访问应用。优化方向是后续补建隧道或部署到公网静态托管,补回 envUrl。
5.2 截图依赖较重
封面截图依赖完整的 Chromium 运行时(约 100MB + 十余个系统库)。对于这种纯静态小工具,可以考虑用 Pillow 直接绘制封面(标题 + 主题图形),跳过浏览器截图,显著降低发布环境的依赖负担。
5.3 移动端交互可进一步打磨
目前响应式布局已适配移动端,但贺卡预览在小屏上的字号、粒子密度还可针对性优化;触摸交互(如滑动切换皮肤)也未实现。
5.4 祝福语个性化
当前祝福库是固定的八句诗词。可扩展为「输入关键词 → 生成个性化祝福」,结合大模型能力让贺卡内容更贴合收件人。
5.5 贺卡导出为图片
目前「保存」走的是浏览器打印(另存 PDF)。可引入 Canvas 将贺卡直接绘制导出为 PNG,体验更直接。
六、总结
这个中秋贺卡小工具本身代码量不大,但「从编码到发布上架」的完整链路涉及前端设计、环境工程、凭证管理、质量门禁等多个层面。最大的收获不在贺卡本身,而在发布过程中遇到的一系列工程障碍(凭证、Chromium、系统库、空间检查 bug)以及对应的解法——这些「绕墙」经验,比写一个 Hello World 有价值得多。
中秋将至,愿这份月光与桂花,能寄到该去的地方。🌕
- 点赞
- 收藏
- 关注作者
评论(0)