零框架开发 PWA 优惠券工具站:纯 HTML + JS + YAML 配置驱动

4 阅读4分钟

最近做了一个优惠券聚合工具站,纯前端实现,不用任何框架,部署在 Vercel 上。

在线体验:quan.toppush.cn

本文分享整个技术方案和踩坑记录。

项目背景

需求很简单:做一个页面,聚合美团、京东、淘宝的每日优惠券,用户点击后自动复制口令并跳转到对应 App。

要求:

  • 加载快(用户从搜索引擎或社交平台进来,3 秒内必须可用)
  • 可以添加到手机桌面(PWA)
  • 运维成本趋近于零
  • 非技术人员能更新优惠内容

技术选型:为什么不用框架?

考虑过 Next.js、Nuxt,最终决定用纯 HTML + Vanilla JS,原因:

  1. 页面就一个:单页应用,没有路由需求
  2. 交互极简:点击复制 + 跳转,不需要状态管理
  3. SEO 友好:纯 HTML 对爬虫最友好,不存在 SSR/CSR 的问题
  4. 构建零配置:不需要 Webpack/Vite,Vercel 直接托管静态文件

唯一引入的外部依赖是 js-yaml(CDN 引入),用来解析配置文件。

架构设计

index.html          # 单文件应用(HTML + CSS + JS 全部内联)
config.yaml         # 优惠数据配置(非技术人员可编辑)
manifest.json       # PWA 配置
icons/              # 应用图标

核心思路:配置驱动渲染。页面加载时 fetch config.yaml,解析后动态生成 DOM。

config.yaml 结构

updated_at: "2026-03-31 08:00"
platforms:
  meituan:
    name: 美团外卖
    color: meituan
    items:
      - name: 天天神券
        code: "复制这段口令打开美团..."
        type: daily
        source: 美团官方活动
  jd:
    name: 京东外卖
    color: jd
    items:
      - name: 新人立减券
        code: "https://..."
        type: once
        source: 京东外卖新人活动

YAML 比 JSON 的优势:支持注释、可读性好、非技术人员编辑门槛低。

关键实现

1. 三种跳转模式

不同平台的优惠有不同的领取方式,抽象为三种模式:

// URL 模式:直接跳转链接
window.location.href = item.url;

// Deep Link 模式:优先调起 App,失败回退 URL
const schemes = {
  meituan: 'imeituan://',
  jd: 'openapp.jdmobile://',
  taobao: 'taobao://'
};

// 口令模式:复制到剪贴板 → 调起 App
await copyToClipboard(item.code);
window.location.href = schemes[platform];

2. 剪贴板兼容处理

移动端浏览器对 Clipboard API 的支持参差不齐,做了双重降级:

async function copyToClipboard(text) {
  // 方案一:现代 Clipboard API
  if (navigator.clipboard?.writeText) {
    try {
      await navigator.clipboard.writeText(text);
      return true;
    } catch (e) {
      // Safari 在非用户交互上下文中会拒绝
    }
  }
  // 方案二:传统 execCommand
  const textarea = document.createElement('textarea');
  textarea.value = text;
  textarea.style.position = 'fixed';
  textarea.style.left = '-9999px';
  document.body.appendChild(textarea);
  textarea.select();
  document.execCommand('copy');
  document.body.removeChild(textarea);
  return true;
}

关键踩坑:iOS Safari 要求 clipboard.writeText 必须在用户手势回调栈内执行,不能放在 async 中间等待其他异步操作之后。

3. PWA 配置

{
  "name": "值得推 · 全平台精选优惠",
  "short_name": "值得推",
  "display": "standalone",
  "start_url": "/",
  "theme_color": "#06070f",
  "background_color": "#06070f",
  "icons": [
    { "src": "/icons/icon-192.png", "sizes": "192x192", "type": "image/png" },
    { "src": "/icons/icon-512.png", "sizes": "512x512", "type": "image/png" }
  ]
}

iOS 还需要额外的 meta 标签:

<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<link rel="apple-touch-icon" href="/icons/apple-touch-icon.png">

4. 骨架屏加载态

配置文件通过网络加载,为了避免白屏,做了 CSS 骨架屏:

.skeleton {
  background: linear-gradient(90deg, #1a1a2e 25%, #2a2a4e 50%, #1a1a2e 75%);
  background-size: 200% 100%;
  animation: shimmer 1.5s infinite;
  border-radius: 8px;
}

@keyframes shimmer {
  0% { background-position: -200% 0; }
  100% { background-position: 200% 0; }
}

配置加载完成后替换为真实内容,体验很流畅。

5. SEO 优化

<!-- 结构化数据 -->
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "WebApplication",
  "name": "值得推",
  "description": "每日精选优惠券聚合工具",
  "url": "https://quan.toppush.cn",
  "applicationCategory": "ShoppingApplication",
  "operatingSystem": "All"
}
</script>

<!-- Open Graph -->
<meta property="og:title" content="值得推 - 每日精选优惠">
<meta property="og:type" content="website">
<meta property="og:url" content="https://quan.toppush.cn">

部署方案

选择 Vercel 的原因:

  • 免费额度完全够用(个人项目月 100GB 带宽)
  • 全球 CDN,国内也能访问(非 vercel.app 域名)
  • Git 推送自动部署
  • 自定义域名免费 HTTPS

部署步骤:

  1. npm i -g vercel
  2. vercel --prod
  3. 在 Vercel 控制台绑定自定义域名,DNS 添加 CNAME 记录

纯静态站,没有构建步骤,部署秒级完成。

CSS 设计细节

深色主题 + 毛玻璃效果:

:root {
  --bg: #06070f;
  --card-bg: rgba(255, 255, 255, 0.05);
}

.platform-card {
  background: var(--card-bg);
  backdrop-filter: blur(20px);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 16px;
}

用 CSS clamp() 做响应式字号,不写媒体查询:

h1 { font-size: clamp(1.5rem, 4vw, 2rem); }

总结

这个项目的技术含量不高,但验证了一个观点:不是所有项目都需要框架

对于单页、轻交互、内容驱动的工具站,纯 HTML + JS + CSS 是最简单高效的方案。配合 YAML 配置文件和 Vercel 部署,运维成本几乎为零。

源码结构很简单,感兴趣的可以直接查看页面源代码学习。

在线体验:quan.toppush.cn


如果你也在做类似的轻量工具站,欢迎交流技术方案。