更新日志
Swift Web 框架的版本发布历史,包含 CLI 工具、框架模块与文档站的所有变更记录。
本文件按月汇总 Swift Web 5 仓重大变更,月内按 framework / starter / standards / cli / docs 5 仓拆分。只记录重要新特性 / 重要重构 / 重要 BUG 修复 / Breaking Change / 跨仓事件。完整变更请查 git log。
2026-09
framework v0.140.0 → v0.155.0 · starter v0.35.13 → v0.37.0 · standards v0.13.27 → v0.13.89 · cli v0.21.1 → v0.23.1
本月聚焦缓存与部署一致性、API 生成可靠性及双工具协作;同步收口时长单位,补齐影视 SEO、认证控制和播放质量埋点。
framework
- ⚠️ 时长与上传 API 收口 — 组件、composable 与模块配置的数字时长统一为毫秒,周期配置改用
Nm/Nh/Nd或always(ISR TTL 仍为秒);上传族isSmall→thumbnail、retryNum→retries、threadNum→concurrency,回顶层级 token 改为--sw-back-top-z - ⚠️ ISR TTL 明确设限 — 禁止
isr: true,声明值限定为 60–3600 的整数秒;对外s-maxage封顶 60 秒,避免多层缓存叠加放大陈旧内容(#394 / #414) - 🚀 影视结构化数据 —
useSeo新增video/media/itemList,输出 VideoObject、Movie / TVSeries / TVEpisode 与 ItemList,并接入视频 sitemap;调用方提供真实业务数据(#381) - ⚠️ 请求配置统一 — 新增
request.transport支持 base64 / binary;nitroApiFetch直接读取 runtimeConfig 并消费全局request.headers,退役swTimeout/apiTransport扁平键及业务桥接插件;明文业务失败保留真实errorCode(#383 / #391 / #392 / #409) - ⚠️ API 生成边界重整 — 文档源配置归入
nuxt.config.ts的swiftConfig.apiDocs,凭证使用API_DOCS_TOKEN;OpenAPI 优先按 tags 分组,生成物标记@generated,手写接口放app/api/manual/并自动注册;YAPI 支持参数模板路径,拉取、解析或命名失败时保留旧产物(#402 / #403 / #404 / #406) - 🚀 认证与系统信息控制 —
auth.deviceLogin可单独关闭设备登录,auth.enabled统一控制自动登录入口;自动重登拆分身份 cookie 与用户资料,客户端系统信息按clientRefreshTtl复用(默认 300 秒)(#410 / #412 / #413) - 🐛 播放异常与签名续播 — 收敛 iOS 全屏和切换异常;SwVideoPlayer 与 SwVideoFeed 的 hls.js 路径在分片签名过期或网络错误时受限重拉同一地址并续播(#398 / #405 / #408)
- 🐛 图片与加密资源容错 — SwImage 缺少地址时降级占位,避免整页 SSR 500;加密资源忽略过期请求结果,缓存读写失败降级到资源加载(#380 / #397 / #421)
- 🚀 会话与播放质量埋点 — 自建通道增加来源、UTM、落地页和设备上下文,30 分钟无活动后换新会话;新增首帧、起播耗时、缓冲累计与
play_id,修复首屏重复 PV,并补记 hls 致命错误(#415 / #417 / #423 / #425) - 🚀 外链与预览控制 — 新增
useExternalRedirect提供安全外链中转逻辑;SwVideoPreview 增加settled汇总终态,useHoverPreview.closeOnScroll支持原位预览场景(#400)
starter
- 🔄 部署统一单进程 — 测试与生产均采用 PM2 fork 单进程,配套进程配置应用与 nginx 缓存探针,避免多实例 ISR 快照交替;页面按类型声明明确 TTL(standards#86 / framework#414)
- 🔄 接口接入模板更新 — 手写接口示例迁入
app/api/manual/,移除运行时环境桥接插件;API / 埋点代理携带X-Site-Id,代理入口跟随项目API_PREFIX
standards
- 🔄 Claude / Codex 共用规则 — 共用入口收敛到 AGENTS.md,补齐 Codex MCP 薄壳;skills 镜像统一为实体目录,消除 Windows symlink 检出差异(#72)
- 🔧 MR 提交与收尾完善 — 提交前核对默认分支基线,阻止复用已合并分支;审核跟踪按实际 reviewed SHA 判定,明确
Closes/Refs与 issue 收尾边界(#70 / #73 / #78)
cli
- ⚠️ 手写 API 命令对齐 —
sw add api改为生成app/api/manual/顶层函数模块,sw_project_apis根据@generated区分生成物 - 🐛 项目创建与配置修复 — 新项目使用 skills 实体镜像,关闭 dev mock 时保留测试夹具;补齐 transport、设备登录与系统信息复用配置,并提示 JSON 配置可能被
nuxt.config.ts覆盖
docs
- 🚀 使用指南补齐 — 新增
useExternalRedirect三语参考,补全组件 CSS token 表;API 生成、渲染 TTL 与部署指南同步新契约 - 🐛 文档站构建配置修复 — catch-all 文档页改用显式 prerender 规则,移除不存在的
~/api自动导入,PWA 名称与描述改从站点配置派生
跨仓事件
- 🔧 核心五仓接入 MR 门禁 — 普通开发统一短期分支 → MR →
dev,接入自动审核及检查;npm 发版保留维护者本机显式操作,docs 保留dev部署(framework#416) - 🔧 Nuxt 安全升级 — framework、starter 与 docs 升级 Nuxt 4.5.2,修复开发工具与 SSR 相关安全问题,并校验消费链兼容性(framework#386)
2026-08
framework v0.95.0 → v0.140.0 · starter v0.32.0 → v0.35.13 · standards v0.4.4 → v0.13.27 · cli v0.16.4 → v0.21.1
特大月(5 仓合计 1000+ commits)。月初收尾 ISR 缓存正确性战役(canonical 策略反转为「默认跟随访问域名」);随后主线转向工程治理三役——规则三层化、e2e 进 CI 门禁、feature-branch flow 迁移(dev/vN 退役);framework 侧完成 PWA 体系大修与移动端播放兼容批。
framework
- ⚠️
SwVideoPreview默认播满 60 秒即停 +loop默认改false(#286,0.101.0)— 两条行为 BC。预览地址的常见形态是「运营没单独配预览资源时,回退正片播放地址」,而组件此前没有任何时长上限且默认循环 ⇒ hover 多久就流多久,等于付费正片能被当预览看完。这个口子对所有 applier 都开着,只能靠每个业务方自己想起来堵。
新增maxDuration(默认 60,0= 不限),按累计播放时长计(暂停 / 缓冲不计入),到点hls.stopLoad()+pause()(保留最后一帧)并 emitcapped。60 的依据:实测业界策展预览片素材本就 55s~2min(腾讯 112s / 优酷 55s),60 秒对它们几乎不触发(走@ended自然收尾);而 60 秒之于 90 分钟正片是 1.1%,靠 hover 累积看完不可能。loop同期翻为false—— 实测两家均不循环,循环本质是「素材太短」的补丁,且它与上限是一对(6 秒素材配 60 秒上限会重播 10 次)。
顺带收口取源为空时的静默:此前三条路径(fetchPlayUrl: null却没传url/id为空 / 拉取结果无可用地址)都是 emit 完loading就再无音讯 ⇒ 消费方只能永远停在 loading 态(cinebay 的加载扫描线因此无限扫)。统一 emit 新事件empty(不用error——「本来就没有预览源」是业务合法态)。
迁移:需要循环显式传loop、需要更长显式传maxDuration;applier 侧自写的「N 秒后v-if卸载播放器」兜底与「超时强解 loading」hack 都可整段删掉 - 🐛
useHoverPreview内置触摸门控(#287,0.101.0)— 源码注释此前写着「触摸设备无 mouseenter,天然不触发(无需额外守卫)」,这是错的:浏览器为兼容只监听鼠标事件的老站点,会在 tap 后补发一串兼容性鼠标事件(mouseover/mouseenter/mousemove/click)。实测(Pixel 7 画像 + 真实触摸输入)还暴露出比"多弹一下"更重的后果:tap 之后根本不会有mouseleave—— 手指离开屏幕不产生「指针移出」,要等下次 tap 别处才补发 ⇒ 移动端点一下卡片,浮层弹出来后一直挂着,而不是「闪一下就被导航冲掉」。
判定优先按PointerEvent.pointerType(判「这一次交互用什么发起」),拿不到才回落matchMedia,并留allowTouchopt-out。别单独用媒体查询判:(hover:hover) and (pointer:fine)判的是「设备主要输入能力」,二合一设备上双向误判 —— iPad + 触控板返回true(手指 tap 照样放行)、触摸主导 + 外接鼠标返回false(鼠标 hover 被误杀,比原 bug 更糟)。调用方建议从@mouseenter="show"改为@pointerenter="show"才能吃到精确判定 - ⚠️
--container-padding加宽屏阶梯(≥1280 → 48px,≥1600 → 96px)(#284,0.100.0)— 视觉变更:宽屏内容区四周出现留白。这是 #283 的续修:把默认上限提到 1920 后,用户在 1920 CSS 视口验收发现「看着没以前好看」——根因是 1920 的容器在 1920 屏上等于满铺,max-width形同虚设,内容只被 24px 的 padding 内缩、观感贴边。
业界实测定案(playwright 在 1920 视口量线上 DOM):与我们同形态(无侧栏、居中容器)的 bilibili,留白不靠 max-width、靠 padding ——max-width: 2260px; padding: 0 140px,且 padding 按断点递增(1440 视口时降到 60px)。YouTube(内容 240→1920)与爱奇艺(192→1897)看着"左边有留白"其实是侧栏占位、内容区本身满铺,与我们非同类,不作对标。
⇒ 职责划分(本次的核心结论):--content-max-width定「最宽到哪封顶」(只对 2K/4K 屏起作用);--container-padding定「任何宽度下边上留多少」。此前一直在调 max-width,方向错了。
顶档取 96 而非 bilibili 的 140:140 是配合其 2260 上限设计的(主场 2560 屏),我们 1920 在 1920 屏即到顶,再留 140 会偏空。
迁移:无需任何 applier 改代码(实测七个 applier 无一覆盖过该变量)。想收窄内容区的站,--content-max-width与--container-padding必须一起调 —— 只改前者会在宽屏被 96px padding 二次挤窄(设 1280 实际只剩 1088)。示例见 starteroverrides.css示例 3。 - ⚠️
--content-max-width默认 1200px → 1920px(#283,0.99.0)— 视觉变更,全站内容区变宽。1200 是「文章站 / 营销站」传统档(Bootstrap.container1320 / Tailwindmax-w-screen-2xl1536 同派),而本生态消费方以内容站为主,宽屏下明显偏窄。
判据是生态自己投的票,不是业界对标:anibay / cinebay / yc001 三站各自独立在 overrides 里收敛到 1920(yc001 写120rem,同值)。默认值站在 1200 等于让每站都记得写那一行 —— 漏写就是 bug(cinebay#7 验收当场才发现)。业界数据只作佐证:内容站无一使用 ≤1536 的窄容器(iQIYI 1808 / bilibili 2260 / YouTube 2864,Netflix 与 Disney+ 干脆不限)。
要理解的语义:1920 在 1920 屏上等于满铺(只剩--container-padding的 24px),2560 屏上才居中留白 —— bilibili / YouTube 在 1920 屏同样满铺,且那三个站都没觉得需要另调 padding。长文本页不受影响:正文行长由页面自己的max-width约束(starter 的 8 个静态页均为44rem),与站级容器无关。
迁移:不想变宽的站在自身overrides.css写回--content-max-width: 1200px(一行)。已写 1920 覆盖的站不必立刻删(同值幂等),下次改 overrides 时顺手清理。 - 🚀 构建期拦下「声明不缓存却被可缓存通配吞掉」(#277,0.98.0)— 存在可缓存通配时,它覆盖的每个路径都被缓存,子路径写
isr: false/cache: false都挡不住(缓存包装在 app 初始化时按「已注册 handler 的路由模式」一次性决定,每请求合并出的 routeRules 不参与该决策)。这类页面 lint / typecheck / build 全绿、显示也正常,只有 curl 响应头看得出来。
按ssr分档,不是一律报错:ssr: false放过(返回构建期生成的 SPA 空壳、按定义与请求无关,实测同一页两个不同 query 的 HTML 字节完全相同 ⇒ 缓存无害);ssr: true(或不声明)报错——它会真 SSR 渲染,且同时骗过 eslintno-query-in-cacheable-ssr(那条规则的前提是「文件声明了 isr/swr/cache/prerender」,而它声明的是isr: false)⇒ 能合法读 query 却被缓存 ⇒ 内容错配。分档让误报为零,故 error 级站得住、不需要 opt-out 机制
0.98.1 修了它自己的一处误报:redirect/proxy规则不渲染页面(前者发 3xx、后者转发上游),被通配缓存不产生内容错配,却被 0.98.0 当成违规拦下。上线当天就在 yc118 的真实构建里撞到(一条/home重定向)。⚠️ 顺带一条教训:0.98.0 发版前我判断「全生态命中 1 处、零误报」,依据是扫各仓nuxt.config的静态routeRules——那看不见页面级defineRouteRules展开成的 glob。判「生态里有没有某种规则形状」只能真跑一次 build - 错误 toast 与上报解耦(#282,0.97.0)—
errorHandler新增toast旋钮:错误时是否给终端用户弹可见 toast。默认false= 静默上报(对齐 Sentry / Bugsnag 业界默认;此前 0.87.0 起启用即无条件弹「系统出现了一个错误」,对内容站沉浸浏览是纯打扰)。要旧行为显式{ "errorHandler": { "enabled": true, "toast": true } }。POST 上报路径不变。消费方背景:湾系四仓升级被此项卡拍板(bay-admin#39 / snapbay#11 / bayverse#4),本条落地后解锁 - ⚠️ origin / canonical 策略反转(#278 续,0.96.0 – 0.96.1)— 上月 0.95.0 的修法是「以
NUXT_PUBLIC_SITE_URL为主路径」,实践中被推翻,理由有三:开发者常不知道正式生产域名、生产域名会换、一个产品往往有多个域名。新策略:L1 显式 useSeo({ siteUrl }) 单页覆盖 L2 NUXT_PUBLIC_SITE_URL 配了它才收敛到该域名(opt-in,属运营决策) L3 useRequestURL().origin 默认:跟随用户实际访问的域名
真正的修复落在 L3 能不能工作上——isr→cache翻译时固定注入varies: ['host', 'x-forwarded-proto'],让被缓存的页面拿回Host。代价是这两个头进缓存 key ⇒ 条目数 ≈ 合法域名个数(对多域名产品正是想要的);「任意 Host 造条目」应在反代层挡(server_name列全 +default_server返 444)。连带把「未配NUXT_PUBLIC_SITE_URL」从告警降为正常状态——只有存在prerender页时才必须配 - ⚠️ SwInput 升级为 wrapper 结构(#305,0.108.x)— 皮肤(边框 / 背景 / focus 态)从内层 input 上移到新增的 wrapper 元素,结构 BC:applier 把
--sw-input-*变量或选择器写在内层 input 上的会退回默认皮肤。适配前先升 ≥0.108.3——0.108.2 及更早存在 class/style 落点错位,变量会落错层 - 🐛 PWA 体系大修:manifest 从来没被 link 进 head(#355 等,0.122.0–0.128.0)— 全生态所有 PWA 站点的 manifest 一直在生成、却从未被页面引用(@vite-pwa/nuxt 只注册组件不挂载,「注册 ≠ 被消费」,只有查线上 DOM 才看得见)。同批:manifest 补
background_color(深色站冷启白闪)/lang/description(#357);iOS 主屏预填名与 standalone 判定修正(#352 / #353);BC:framework.pwa收窄为纯布尔,manifest 内容迁至swift.config.json(#359,0.125.0);SwAddToHomescreenGuide适配 iOS 26 新工具栏 + 默认皮肤重做(0.128.0) - 🔄 裸源发布试验与撤回(#289 → #362,0.124.0–0.126.0)— dist/runtime 曾改发裸 TS/.vue 源(意图让消费方 IDE 直读源码),实测撤回:裸源让部分消费链类型解析劣化、发布产物形态变化牵连既有规则。0.126.0 恢复全编译并加
assert-publish-shape四条发布态守卫,防产物形态再静默漂移 - 🚀 键盘可达性批(#331,0.130.0)— 可排序表头内容包进
<button>(W3C APG 范式,结构 BC:#header-*slot 内容成为 button 后代、只能放 phrasing content,th:hover视觉选择器需改指向button.th-inner);SwTable 挂@row-click但行内无可聚焦元素时 dev 告警(WCAG 2.1.1);贴片按钮 div→button、扫码器 focus ring。9 个 applier 实测零适配 - 🔄 升级 pinia 4 + 删除 ESM alias hack(0.131.0)— Pinia 3.x 时代的 ESM 兼容 alias 整段移除;连带暴露个别 applier 自声明 pinia 的存量违规(重复框架模块构建期护栏会拦)
- 🚀 移动端播放兼容批(#365 等,0.132.0–0.133.0)— iPhone 改为优先原生 HLS:hls.js 默认走 ManagedMediaSource,而 UC 等第三方内核「只推时间轴不渲染画面」(真机实测);补齐内联播放属性(
webkit-playsinline/ x5,防 iOS 强制全屏);新增劫持型浏览器拦截blockHijackingBrowsers(UC / 夸克 / QQ / 百度默认拦截换提示、微信有意不拦,#hijacking-browserslot 可自定义) - 🚀 触屏进度条两态手势(#372,0.138.0)— 播放中可在收起态进度条上横向起手直接拖动 seek,不必先唤出控制条;收起 / 展开两态各自独立的手势语义
- 🐛 可缓存页 Set-Cookie 剥离 + 声明冲突护栏(#374 / #375,0.139.x)— ISR 等可缓存页渲染期写的 Set-Cookie 会进缓存副本、向后续所有访客重放,nitro plugin 统一剥离 + dev 告警;页面级
defineRouteRules与 configrouteRules同 key 冲突改为构建期报错。升级跳过 0.139.0 直上 0.139.1 - 🚀 SwSelect 远程搜索(#376,0.140.0)— 新增
remote/loadingprops 与@search事件,搜索词交由业务侧异步取数
starter
- ⚠️ 模板默认改为「跟随访问域名」 —
(footer)下 8 个静态页prerender: true→isr: true,NUXT_PUBLIC_SITE_URL由必填改为可选。原因是 prerender 在构建期没有真实请求、拿不到Host,origin 只能来自那个变量 ⇒ 只要有一个 prerender 页,就被迫配置、被迫收敛。isr: true(缓存到下次部署)运行时开销差别可忽略,却不需要该变量 - 🔧 CI 模板长出 e2e 门禁(standards#48 配套,0.35.0–0.35.1)— verify 与 e2e 同 stage 并行;e2e 按「改动是否落在适用面」的路径过滤触发(页面 / 布局 / 中间件 / server route / 框架配置 / 依赖),改组件样式的 MR 只跑 verify;发布 MR 必跑全量兜底
- 🐛 0.35.9 事故版与 CI 契约测试(0.35.10)— 一次脚本正则(
re.S贪婪匹配)把.gitlab-ci.yml吞剩 3 个 job 发了出去:ci/lint 合法、单测照绿——「删除型 bug 对『验存在』的测试免疫」。0.35.10 修复并新增ci-jobs-contract.spec.ts(job 逐个在 + 总数 + 行数下限),随模板带给所有 applier
standards
- 🔧 CI 里调 pnpm 必须用
npx --yes pnpm@11,禁止npm i -g pnpm— runner 是共享 shell runner(多项目并发跑在同一台机器、同一个全局 node 环境),全局装等于动全局 bin,并发时一个 job 能把另一个 job 正在用的 pnpm 二进制掀掉。实测事故:两条 pipeline 同一秒创建、同落一台 runner,其中一条第四步炸pnpm: No such file or directory,而它前三步用同一个 pnpm 都正常、重跑即绿。排障判据:verify 红在「某步报 pnpm/node 二进制 not found」且前面几步用同一二进制都成功 = 基础设施 flake,先重跑别查代码 - 🚀
sw-standards sync自助同步 CLI(#32,0.10.0)— applier 一条命令自助同步规则(marker 段 / skills / 薄壳),替代「等维护者集中推送」;输出规则变更摘要,--check带退出码语义 - 🔄 规则三层化(#43)— 下游约定文件从「单文件巨石」拆为三层:
AGENTS.md常驻索引(P0 红线 + 选型表 + 细则通道)+.claude/skills/sw-*按需加载细则 + standardsrules/主源;sync 目标家族同步扩展(agents / skills / 薄壳三类),Codex / Copilot 经.agents/skills镜像同享 - 🚀 lint 执法批 — prettier 基座
semi: true+singleAttributePerLine(0.11.0,全生态存量重排);stylelint 新增hover-media-gate(:hover必须包@media (hover: hover),配合触摸端 hover 粘滞修复)与component-token-prefix;eslintroot-class-sw-prefix升 v3(根 class 名字必须与组件名对得上)
cli
- 🐛
sw config set拒绝合法的对象配置(#46,0.16.5)—framework.pwa与framework.errorHandler在 framework 侧的类型是boolean | XxxOptions,却被错列进 cli 的「纯布尔键」白名单 ⇒sw config set framework.pwa '{"enabled":true}'被当成非法形状拒绝写入。改为按 union 逐层校形状(叶子键 / 子字段 / 父对象整体 set 三种入口都覆盖) - 🐛 pwa 对象配置反被判成「关闭」、删掉
@vite-pwa/nuxt(#47,0.16.6)— 上一条的回归。#46 之前对象值在写入前就被拒、这条路径不可达;摘掉布尔守卫后对象值合法了,但 applier 派发端仍是getNestedValue(...) === true⇒ 对象恒判为 false ⇒ 走disablePwa()。配置写着 PWA 开启、package.json里的依赖却被删,且提示语淹没在成功回显里。修法是照抄 framework 自己的resolvePwa归一(boolean → 自身;对象 → 看.enabled,缺字段即关)
⚠️ 教训:从校验白名单里移除一个 key,等于给下游放行了它没见过的形状 —— 移除前要查这个 key 下游有没有按旧形状假设写的消费者。同型的 cli#39 当年选择在写入端拒绝来回避,#46 拆掉那道拒绝却没补派发端,于是原样复发 - 🔧
bin路径去掉./前缀(0.16.7)— 消除每次npm publish刷的"bin[sw]" script name ... was invalid and removed警告。措辞有误导性(听着像 bin 被删了,实际只是剥前缀),零行为变化,改的是「每次发版都刷一遍的噪音」 - ⚠️ AI 调用安全批(#48 / #49,0.20.0)—
sw upgrade加--check/--yes,非交互(MCP / 管道)写操作不再零确认、退出码分层 0/1/2(三条 BC);MCP 全部 15 工具补 annotations(只读 / 写 / 破坏性外观区分) - ⚠️ pwa 装卸职责移交 framework(0.17.0–0.19.0)— cli 的 pwa feature 不再装卸
@vite-pwa/nuxt(由 framework 统一携带);framework.pwa配置形态随 framework#359 收窄纯布尔,删validatePwaShape
docs
- 🐛
/composables/use-hover-preview自上线起线上一直访问不到 — docs 是 SSG 站、prerender 路由靠 crawler 从已有链接爬,而该页既不在侧边栏、正文也无人链接 ⇒ 零入边 ⇒ 从未被生成,线上返回首页 fallback。阴险处在于构建 / 测试 / lint 全绿,本地pnpm dev直接敲 URL 还完全正常(dev 按需渲染、不走 crawler),只能靠人肉发现。已补侧边栏条目,并加孤儿页守卫:每个 content 页必须至少有一条入边(侧边栏 /catalog.ts/ 其它页正文链接,三选一即可 —— 强求「都进侧边栏」会误伤后两类合法形态) - 🚀 guide 跟进流程演进(三语) — 新增「测试同步与门禁」章(e2e 适用判定 / verify 门禁 / 覆盖率 ratchet / 登录态注入);Git 协作规范整章重写为 feature-branch flow;生产部署页改运维 runbook 形态(首次上线 9 步 checklist + 第 N 次一个命令)
跨仓事件
- 🔧 feature-branch flow 迁移(standards#51 / #52)— 9 个 applier 默认分支统一
dev/main,dev/vN长期分支全部退役;只保留dev/main(集成 / 测试)与main(生产)两条长期分支,其余短期分支合并即删;生产发布 =dev/main → main发布 MR,mr-review 对发布 MR 出「🚀 发布摘要」(D5)、对触及server// CI / 依赖等风险路径的 MR 不自动合需人工(D6);starter CI 新增release-guard提示 job。分支命名与 upstream-first 定调为推荐并默认、不强制——机械层只保护两条长期分支本身 - 🔧 e2e 进 CI 门禁 + 覆盖率 ratchet(standards#48 / #49)— e2e 正式成为 applier 合并门禁(与 verify 并行、按路径触发、发布 MR 全量兜底);覆盖率逐仓 ratchet 只升不降;登录态 e2e 由 setup 走 UI 登录一次 +
storageState复用(TS-003);首批接入 yc118 / yc124
2026-07
framework v0.58.1 → v0.95.0 · cli v0.10.0 → v0.16.4 · standards v0.3.2 → v0.4.4 · starter v0.21.0 → v0.32.0
主题 / 语言切换器收口与 0.64 架构正交化打底,中旬 CSS 变量两层命名模型与 token 表面扩面固化设计语言,下旬管理台组件(SwTable)、SwSelect 搜索/创建、tracker 自建通道与自助注册连发;starter 电影三件套 + 通用页脚模板落地;设计体系(Claude Design / Open Design 双轨 + 20 卡管线)全量上线;月末 OpenAPI 双源与 ISR 私有护栏、表单控件族统一高度 + SwInput、SwVideoFeed 预载省流开关收尾。
月末最后一周是「ISR 缓存正确性」战役(#271 起):先发现自托管 node-server 上
isr完全不生效(nitro core 根本不消费它),继而连锁挖出通配污染、fs 驱动父子路径冲突、多动态段规则被丢弃、零段父路径漏配、被缓存页丢Host致 canonical 变 localhost 五个全绿却静默失效的坑——逐个补上构建期护栏。
framework
- 🚀 主题能力重构(epic #191)— theme 配置收敛为单旋钮
theme.mode(system / toggle / dark / light)+ color-scheme 解耦 +resolvedTheme;内置切换器SwThemeSwitch(仅 toggle 模式渲染,token / icon slot / 作用域插槽三档定制);toggle 模式注入防 FOUC inline bootstrap - 🚀 SwLangSwitch 内置语言切换器(#192)— 自 gate(i18n 启用且 locales ≥ 2 才渲染)+ 联动 cli 语言配置 + SEO 前缀切换,修 SSR 直出前缀语言页选中态
- 🚀 加密 useCookie 覆盖 + framework-api.json 结构化 props(#203)— framework 的 useCookie(自动 cachePrefix + AES)注册 auto-import 同名覆盖 Nuxt 内置;framework-api.json 组件层新增结构化 props 数组 + tsLayer 三级兜底回读源码
- ⚠️ 0.64.0 架构正交化 BC(#206)— ModuleOptions 删 theme 布尔糖 + sitemap 并入 seo 套件;YAGNI 收缩公开 API;safeExternalUrl / safeInternalPath 守卫上收 framework
- 🚀 dev mock 双端化(#208,0.65.0)— registerApiMock 放宽为 dev 期 SSR + CSR 双端拦截,universal plugin 成推荐范式,prod 双端删净不变
- 🚀 组件基线样式口径固化(#210,0.66.0)— 「基线样式非零样式」(丑但能用合格、看起来坏了不合格)入样式规范;SwRail gap 退化默认修正、SwFormField 补状态反馈基线
- 🐛 修复批(0.66.x) — nuxt-schema-org 钉 6.1.3(修 client 不 hydrate 崩溃);贴片期 autoplay 声画错乱(#211:贴片展示期压制 autoplay,skip() 统一起播出口)
- 🔄 CSS 变量两层命名模型 + token 表面扩面(#219 / #213,0.68.0)— 语义层 Shadcn 裸名豁免、组件级一律
--sw-<组件>-<prop>全名(--modal-*→--sw-modal-*等迁移,0.x 直改不留 shim);token 新增--foreground-soft/--gradient-brand,深色站--shadow-*覆盖与 currentColor 图标着色口径固化 - 🔧 WebSDK v1.1.6 vendored 升级(#225,0.70.0)+ seo-tdk-length lint(TDK 治理:title/description 字面量显示宽度静态预检,warn 级)
- 🚀 SwTable 数据表格(#227 → #234 管理台强化 → #235 类型导出,0.71–0.73)— 管理台首选组件:columns 配置 +
#cell-<key>插槽、受控列排序(v-model:sort 三态)、行选批量(v-model:selected 含 indeterminate)、loading 保结构遮罩、斑马纹 / 紧凑密度 / 粘性表头;SwTableColumn等公开类型 barrel 导出;自防全局 table 样式入侵 - 🚀 SwSelect searchable / creatable(#226,0.71.0)— Combobox 分支:输入过滤 + chips 多选 + 「创建 "xxx"」输入即建(multiple + searchable + creatable 即 tag-input 形态);连带 SwVideoFeed 播放速率 / 线路切换 API(#229)
- 🚀 tracker 自建通道 + 首屏 pageView(#228 / #236,0.71–0.73.3)— 无 WebSDK 站点用自建 endpoint 批量上报(batch + sendBeacon 兜底);SSR 场景首屏 pageView 补报(0.73.3 修补报 watch 的 TDZ 崩溃 hotfix,⚠️ 0.73.2 勿停留)
- 🚀 sw-hit-area 触摸热区 opt-out(#230,0.72.0)— 紧凑控件免除 44px 拉伸 + 伪元素热区扩到 44×44(「视觉小 + 外包热区」惯例内置);🐛 SwVideoFeed 手势中断吸附回弹(#231)、SwModal 关闭钮 ✕ → 内联 SVG(#232)
- 🚀 userStore.register 自助注册(#233,0.74.0)— 与 loginByUsername 对称复用 setInfo 链,成功即进登录态(bayverse 用户系统驱动)
- 🐛 修复批(0.74.x) — sitemap XSL 标题 undefined(#237:site.name 从 app.head.title 兜底);SwCarousel 手动导航重置 autoplay 计时相位 + 键盘焦点暂停(#238:刚选的片不再被临近 tick 换走)
- 🚀 SwVideoFeed 下拉刷新(#241,0.75.0)—
pullToRefreshopt-in:首条顶部下拉超阈值触发@refresh,受控refreshing收尾 +#refresh-indicatorslot 自渲染品牌指示器(悬浮不位移内容,仅 touch);snapbay「起浪…」signature 的底座 - 🐛 useSeo lint 补齐 error.vue 覆盖(#240,0.74.2)—
require-useSeo-in-pages此前只匹配app/pages/**,与文档声明不符;补isErrorPageFile后全局错误页缺 useSeo 同样报 warn(错误页 noindex 是硬要求) - 🚀 generate-api 双源:OpenAPI 3 接入(#242,0.76.0)— source adapter 架构,自研 server 的「API 文档 → 请求代码」自动链与 YAPI 源并行
- 🚀 ISR 私有数据护栏 L2–L4(#243 / #245,0.77.0–0.78.0)— generate-api 按 visibility 分文件 + manifest + private 元数据注入;eslint
isr-no-private-api机检 ISR/prerender 页调 private API(判据收敛 SSR 执行路径消事件处理器误报);request dev 期 SSR 调 private 警戒;generate-api --check漂移检查 - 🚀 表单控件族统一高度/字号 + SwInput(#244,0.78.0)— 语义 token
--control-height(32px) /--control-font-size(14px),SwInput / SwSelect / SwSegmented 同行混排默认等高等字号(⚠️ SwSelect 36→32px·字号 16→14、SwSegmented 42→32px 有意视觉 BC);新组件SwInput(表单基线盒子 + 触摸设备防 iOS 聚焦缩放),starter LoginForm 迁移作参考实现 - 🚀 SwVideoFeed 预载可控(#246 / #248,0.79–0.80.0)—
preload?: boolean | number:默认预载后 2 条视频各前 5s(⚠️ 原窗口 ±1 条各 30s 全量预载,CDN 流量大降);广告条跳过不占名额、尾部截断、挂载窗前伸;false 完全关闭 - 🐛 滚轮惯性尾巴过冲修复(#247,0.80.0)— Windows 精密触控板一次滑动窜多条:锁定解锁改 240ms 静默窗 + 力度回升绝对下限;deltaY 补
deltaMode归一化(Firefox 鼠标滚轮一格即翻条) - 🚀 埋点扩容三连(#249 / #250 / #251,0.81.0)—
track事件名放宽为「预置枚举 + 任意自定义字符串」并按通道分流(自定义名仅自建 endpoint 入库,WebSDK 通道枚举外名 dev 警告后忽略);视频播放心跳 + 累计观看时长watch_time;广告关闭埋点useAdTrack.reportClose(含close_reason) - 🚀 useHoverPreview 机制层收编(#253,0.83.0)— 卡片 hover 放大预览的意图状态机(300ms 弹出 / 140ms 关闭 / 顺移保持 / 滚动即关)+
computePreviewBox定位纯函数;浮层视觉仍归业务自绘,starter 删本地副本改引 framework - 🔄 token 与几何三件套 — 媒体遮罩语义 token
--scrim/--scrim-top(#254,0.84.0,一行消费免 no-hardcode disable);SwRail 箭头垂直锚点--sw-rail-arrow-top(#252,0.82.0);SwModal 视口安全 width / max-height + class 透传落 content(0.85.0,per-dialog 定制的官方通道) - ⚠️ SwSegmented 默认视觉对齐业界灰槽形态(0.86.0,视觉 BC)— 连带修「选中项 hover 被通用 hover 规则压成低对比黑字」
- 🚀 内置文案多语言化(#261,0.88.0)— 新增
sw-i18n内置文案字典 +useSwText,19 个组件的内置文案 /aria-label全量接入(此前硬编码中文,非中文站露馅) - 🚀
@swift-web/framework/store子路径导出(0.90.0)— 让「同名覆盖」的扩展模板真正成立:业务 store 与 framework store 同名时,唯有显式 import 才拿得到 base,否则指向自己形成无限递归 - 🐛 ISR 在自托管 node-server 上完全不缓存(#267,0.92.0,本月最重要的修复)— nitro core 只规范化
swr、不消费isr(仅 vercel / netlify / zeabur 三个平台 preset 认它),自托管上写了isr等于零缓存、每请求全量 SSR。改为构建期把isr翻译成等价cache键并存(平台走 CDN、自托管走服务端缓存,两边都对);同时把缓存挂上有界 LRU(1000 条 / 50MB / 单条 2MB),把「随机 query 撑爆进程内存」从 OOM 降级为命中率下降。业务侧写法不变,仍只写isr - 🚀 渲染策略构建期护栏四连(0.89–0.95)— 这类失效的共同点是 lint / typecheck / build 全绿、页面看着也正常,只有 curl 产物才看得出,故一律做成构建期硬校验并给可粘贴的修法片段:#262(通配规则把渲染语义补进父路径,0.89.0;0.89.1 修三处判据缺陷、0.89.2 排除 Nuxt 内部路由)/ #274(
fs缓存驱动 × 父子路径同时可缓存 ⇒ ENOTDIR,0.93.0)/ #276(路径含 ≥2 动态段时页面级defineRouteRules被 Nuxt 整条丢弃,0.94.0)/ #279(可选段页面的零段父路径拿不到缓存包裹,0.95.0) - 🚀 可缓存页禁读 query(#271 配套)— 新增 eslint
no-query-in-cacheable-ssr(error)+no-ineffective-route-rules;护栏 L5 拦「可缓存页 SSR 携带用户态」;dev 期大响应告警在根因处报出「哪个接口多大 / 多少条」。配合反代层 path-only cache key,缓存爆炸由「止血」转为根治 - 🐛 被缓存的页面 canonical 退化成 localhost(#278,0.95.0)—
cachedEventHandler进 handler 前只保留cache.varies白名单里的请求头,Host被丢掉 ⇒useRequestURL().origin落到http://localhost,canonical / og:url 全错,且只有「被缓存过的」页面才错 - ⚠️ 移除全局触摸最小高度,改
sw-hit-areaopt-in(#265,0.93.0,视觉 BC)— 原先给所有a/button加min-height: 44px,落地一年积累 38 处绕行。调研 13 个主流库的发布态 CSS:这种 blanket 规则零例;规范约束的是热区而非视觉盒、合规线是 AA 的 24px 而非 AAA 的 44px、inline 文本链接明文豁免——三层全反了。改为伪元素扩热区,视觉不变 - 🔧 其它 — WebSDK vendored 升 v1.1.7(#280,新增四类硬件信息事件自动采集;facade 12 个方法 + 28 个事件契约不变);播放器
autoplay默认关闭 + 尊重 prop + 静音降级,连带补「在播但封面还盖着」的兜底自愈(#281);useLocal/useSession泛型不再塌成unknown
starter
- 🐛 中转页 DOM XSS 加固 —
?url=跳转补 http / https scheme 白名单(连带沉淀 standards 通用规则) - 🚀 theme.mode 适配 + SwLangSwitch 接入 + Cursor 开箱配置 — swift.config 单旋钮 + 顶栏改 framework 内置切换器;
.cursor/mcp.json入库 - 🚀 电影三件套 demo 全量落地(#48–#51,0.26–0.28)— /movie 楼层 / 列表 / 详情参考实现:版式三旋钮 + 全版式插位广告 + 卡片信息层 v2 + 选集面板 + 弹幕全链路 + 前贴片广告示范(play_ads → SwAdPreroll 归一)
- 🚀 通用站点页脚模板(#52,0.29.x)— 数据驱动 AppFooter(品牌区 / 链接组 / 圆形图标链接 / 友链可选模块,5 常量改数据不动布局)+
(footer)分组路由 6 个静态页(about / contact / ads / terms / privacy / faq,prerender)+ 顶部导航字体层级与激活态优化 + 闪电新 logo 统一 - 🔄 审计修复批(0.26.1)— 登录方式切换迁 SwSegmented + 站内回跳守卫收敛 framework safeInternalPath
- 🚀 合规占位页补齐(0.30.0)—
(footer)新增 18 U.S.C. § 2257 合规声明与滥用报告(DMCA)两个结构占位页(noindex + prerender),页脚「政策」组注释链接解开即用,面向成人内容站合规标配 - 🚀 卡片 hover 放大预览(Refs fw#253,0.30.3)— 热播推荐楼层切 16/9 横版 +
MovieHoverPreview浮层 +MovieCard/MovieFloor的previewprop(默认开);机制层随后上收 framework,starter 删本地副本改引useHoverPreview/computePreviewBox - 🔄 审计修复批(0.31.0)— deploy 不再冲掉服务器上手填的
.env;占位符域名归位;noindex 页排除出 sitemap;TabBar 死链默认值;error-report 端点挪出/api/(避开 applier 的代理遮蔽);评论发布框头像改onMounted回填以消 ISR 页 hydration mismatch - 🐛 扩展 store 模板修法(0.32.0,配套 fw 0.90.0)— 改用显式
import从@swift-web/framework/store拿 base,修「同名覆盖时 base 指向自己」 - 🔄 排序参数 query → path 段(#271 范式落地)—
movie/list/[id]/[[order]].vue+ 边界校验;连带补nuxt.configrouteRules 兜底(该页defineRouteRules被 Nuxt 静默丢弃,即 fw#276 的形状)
cli
- 🐛 Windows 必现失败修复(#31)— spawnSync 补 shell,修 sw create / run 在 Windows 必现失败
- 🐛 升级与超时误报修复 — sw upgrade 补 --latest 修 0.x 跨 minor 假成功;npm pack 超时误报修正 + 上限 300s(#36)
- 🚀 sw_project_apis MCP 工具(#40)— 解析 applier app/api 生成物,AI 直接查后端接口清单
- 🔄 配置联动 BC 批(0.15.2 – 0.16.1)— framework.sitemap 迁 framework.seo.sitemap;
sw add page模板 TDK 引导升级(中文口径注释 + TODO 占位,0.16.0);schema 移除 tracker.autoPageClick(随 fw#228,0.16.1) - 🐛 修复批(0.15.x)— sw info 缺字段崩溃 / config set 校验残口 / 损坏 swift.config.json 走 CONFIG_PARSE_FAILED 错误码
- 🐛 输入白名单加固(#45,0.16.2)—
sw add/sw config拦原型链键 / 非法标识符 / 路径穿越 / 原型污染。⚠️ 首版正则误伤了 Nuxt 动态路由段[id]/[...slug](自造回归,0.16.3 放行) - 🔄
--text模式兑现「纯文本」承诺(0.16.2)— 统一剥 ANSI 转义;连带修KNOWN_DESCRIPTIONS跨仓漂移 +sw info的 framework 版本读取口径对齐version-check
standards
- 🚀 v0.4.x 规则增补 — 「用户可控跳转必过 scheme 白名单」/ SOP「issue 已存在→认领」/ no-hardcode 引入期姿势 /
--brand-*业务 token 命名空间 / mocking 双端化 - 🚀 v0.4.3 TDK 治理 — 新增 eslint 规则
seo-tdk-length(warn 级字面量预检)+ 「TDK 长度写时就写足」规则节(显示宽度口径) - 🔄 组件规则同步批 — SwTable / SwSelect searchable·creatable(SEL-003)/ sw-hit-area 紧凑控件 opt-out(含 chips/tab 正当场景界定)/ userStore 写状态清单补 register / 深色站 shadow 覆盖与 currentColor 图标着色 / SwInput 与
--control-*表单控件族入组件优先表 / SVF-006 下拉刷新受控收尾 - 🔄 渲染策略规则大改(v0.4.4 及以后)— 新增「可缓存页 SSR 禁读 query」硬规则 + path 化的四个结构性前置条件 + 「触摸目标约束热区不约束视觉尺寸」整节改写(含 13 库调研结论);订正零段父路径的根因表述——nitro 里 routeRules 匹配器与 h3 handler 路由器对
/P是否命中/P/**行为相反,原文只写了一半
docs
- 🚀 demo props 覆盖率闭环(#84)— 覆盖率规则落地 + 四批缺口回填收官,终值 278/278 = 100%
- 🚀 「设计体系」栏目上线(#85 – #88)— 三语 7 篇(设计语言 / Figma 工作流 / Claude Design 上手 / 协作 / 治理),Figma 与 Claude Design 双轨等重;「认识 Open Design」接入本地 agent 设计系统 bundle;设计卡片总览页 20 张实卡 iframe 预览 + 双资源包下载
- 🚀 部署文档补视频转码契约 — HEVC 必配 H.264 双 codec 变体(mermaid 选档流程图 + 单 URL 前端契约 + 双独立 URL 反模式 + AV1 演进预告)
- 🐛 修复 39 条失效的同页锚点(#90,占全站 113 条的 34%)— 根因是 heading id 由
@nuxtjs/mdc生成,规则反直觉(吞.、连续-折叠成一个、数字开头补_);连带新增docs-anchors.spec.ts全量校验并对复刻算法本身锁了 8 条实测值 - 🐛 修 6 组文档事实错 + 新增表格结构护栏(审计 07-28)
- 🚀 新增「自托管下 isr 如何真正生效」(三语)— 配套 fw#267,并修正原文对缓存位置的描述
跨仓事件
- 🔧 连续审计周期(07-02/03/04 三连 + 07-07/08 两连 + 07-13 深审)— swift-web-audit 多轮批量修复,07-13 批叠加 TDK 治理四路联动(framework lint + cli 模板 + standards 规则 + docs),发版链贯穿 framework 0.62–0.69 / cli 0.13–0.16 / starter 0.24–0.26 / standards 0.4.1–0.4.3
- 🔧 设计体系双轨管线(07-09 – 07-17)— framework
scripts/design流水线(ds-build 源码派生 20 卡 + brand-inject 品牌注入 + od-build Open Design bundle)→ Claude Design 底版 / yc001 品牌双项目 + docs 站资源包与实卡预览,全链单一事实源 = framework 源码 - 🔧 ISR 缓存正确性战役(07-29 – 07-31,framework 0.89 → 0.95 + starter + standards + docs + 8 个下游站)— 由「反代层要不要做 HTML 缓存」一路挖出五个全绿却静默失效的渲染策略坑,逐个补构建期护栏、改规则主源与三语文档、并把 8 个消费方全部升上来。教训沉淀成一条判据:「站不慢」不能作为「缓存规则生效了」的证据——反代层的固定 TTL 会掩盖应用层的漏配,判据只能是产物
curl出来的响应头 - 🔧 设计体系派生改源码直读(fw#257)—
ds-build的组件卡 CSS 从各.vue的<style>块直读,消除手抄快照漂移
2026-06
framework v0.16.1 → v0.58.1(42 个 minor + 20 个 patch)· cli v0.5.6 → v0.10.0 · standards v0.2.0 → v0.3.2 · starter v0.14.4 → v0.21.0
组件大爆发月:广告组件家族(12 个 SwAd*)+ WebSDK 埋点底座、轮播 / 横排 / 视频流 / 网格组件族(彻底去 swiper)、播放器广告与付费墙、SwEditor 富文本,叠加 module setup 分层重构、配置体系整改、pnpm 11+ 全生态闸门、obfuscate CSR 裸样式根治等跨仓事件。
framework
- 🚀 广告组件家族 + 统一埋点底座(epic #94)
- 全月落地 12 个自渲染广告组件:图片类
SwAdBanner/SwAdMrec/SwAdIcon、文字卡片类SwAdText/SwAdMarquee/SwAdNative、弹窗 / 悬浮类SwAdSplash/SwAdPopup/SwAdFloating、播放器位SwAdPreroll(前贴片,play_ads 协议归一)/SwAdPause(暂停广告)、合规角标SwAdLabel,内置曝光 + 点击埋点;图片广告可选文案 + CTA overlay - 集团 WebSDK 上报底座:
useTracker(28 个 WebSdkEvent)/useAdTrack(广告字段自动组装)/useAdFrequency(频控走加密缓存)+ tracker.client 插件(懒加载 / 自动 pageView / 配置缺失静默降级) :track组件内置埋点(SwLink / SwButton / SwCarousel / 播放器,#123)+ 通用曝光useExposure
- 全月落地 12 个自渲染广告组件:图片类
- 🚀 轮播 / 横排 / 视频流 / 网格组件族(#106)—
SwRail(原生横滚 + scroll-snap)/SwCarousel(transform 翻页 + 无缝 loop + autoplay + dots / 缩略图指示器)/SwVideoFeed(抖音式竖划短视频流,裸 hls 视频池 + 虚拟化)/SwGallery(响应式网格 + 加载更多)/SwPagination(页码翻页,starter 向上归并) - 🚀 播放器广告 + 付费墙 + 弹幕 — SwVideoFeed 信息流广告条 + 入口贴片(强制观看 prerollAdForceWatch,#179);SwVideoPlayer / SwVideoFeed 试看墙 paywall(#174)+ 重看试看片段 replayPreview(#186);SwVideoPlayer 内置弹幕 danmaku(条件懒加载 + 主色 token)
- 🚀 SwEditor 富文本(#187)— 保留 Tiptap 内核重写封装:v-model / @提及 #话题 / 内置 emoji 面板 / 图视频上传(emit-to-business)/ 配菜式工具栏 / token 化默认皮肤
- 🚀 新组件与皮肤上移 —
SwSegmented/SwSelect(平铺单选 / 下拉选择)、SwBreadcrumb(headless 面包屑 + BreadcrumbList JSON-LD);modal / toast 默认皮肤 token 化上移进 framework(#173),applier 删副本即得 - 🚀 registerApiMock dev 期请求 mock 层(#188)— 明文层声明式拦截(dev-only + client-only + prod DCE 删净)+ 内置 login / system-info 预设;build 产出 framework-api.json(四层 API JSDoc 数据源,cli MCP 消费)
- 🔄 module.ts setup 分层重构(#99)— 抽 setup/ 七层(types / defaults / resolve-options / diagnostics / register-config / register-runtime / configure-build),module.ts 收敛为薄编排 + 装配快照护栏测试
- ⚠️ BC 集 — userStore
login()→autoLogin()+ 新增公开loginByDevice();useLoginDialog的 show → open;SwAdSide→SwAdFloating改名;广告弹窗按场景拆分SwAdSplash/SwAdPopup;player API 命名对齐 HTML / 业界惯例 - 🐛 obfuscate 破坏 CSR CSS preload 根治(#169)— 生产混淆吞 Vite css preload url 致 SPA 导航整页裸样式,0.39.4 关 stringArray + 默认关 inlineStyles(框架级修复,升级即得)
- 🐛 SSR / 安全修复批 — deviceId 改 secure-context 安全的
randomUuid()(修非 HTTPS / LAN HTTP 500);useSeo prerender 页 origin 回退NUXT_PUBLIC_SITE_URL(#117,修 OG / canonical 烤成 localhost);cacheAesKey 长度 / auth cookie 名构建期 fail-fast
starter
- 🔄 广告体系换血 — 彻底去 swiper,自建广告组件全删改用 framework
SwAd*组件族;开屏广告迁SwAdSplash(system/info.layers 驱动) - 🚀 登录与能力上移收编 — yc001 登录组件 UI / 结构回灌(LoginForm + login.vue);modal / toast 皮肤副本删除走 framework 内置;PaginationBar 退役归并
SwPagination - 🐛 sitemap 收敛 framework 内置 — 删自建 sitemap 管线(根除自写文件服务路由的路径穿越隐患),统一走 framework 的 @nuxtjs/sitemap
- 🔧 CI / 部署 / mock 工程化 — verify 门禁 job(type-check + lint)+ CI 改 pnpm;deploy/ 运维三件套 +
pnpm deploy:prod(独立目录 build、rsync 不带 --delete,根治首屏裸样式窗口);内置业务 dev mock 预设(movie / search 整套)
standards
- 🔄 rules 单一事实源重构 — 拆单文件为 rules/ 多主源 + 双装配清单(
_claude/_mr),下游 CLAUDE.md 瘦身职责分离 - 🚀 stylelint no-hardcode 强制(#17)— color 类属性禁 hex 字面量(error 级)+ Tailwind at-rule / 函数白名单
- 🚀 统一开发流程 SOP + applier CI/CD + 部署规范 — issue-dev-sop 主源落地(issue 即方案 / 按 task 原子提交 / 自测留证),治理类 wiki 全弃;applier MR 门禁工作流 + 长期分支同步纪律 + 测试 / 生产部署规则
- 🚀 usage-review-rules 大扩充 + 交互体验规范 — 收编 utils / store / composable 层 20+ 条编号规则(CACHE / REQ / AES / DB / STORE 等);新增前端缓存加密 util / 广告位与打点 / dev mock 护栏 / 文档中等信息密度等规则;交互与体验规范 UX-001~010(#25)
cli
- 🚀 theme applier + MCP 富文档 — theme feature applier(#20,theme.enabled 自动 toggle 暗色 marker 块);sw_framework_docs 读 framework-api.json(四层 API + gotcha 关联 + 框架配置层)
- 🚀 create / config 能力补全 — sw create 询问启用 dev mock(选否删预设);sw config + MCP 全量覆盖 swiftConfig + auth 危险项二次确认;applier 创建补 pnpm 11 守卫 + 生成 .npmrc
docs
- 🚀 组件族三语文档批量新增 — 轮播族(SwRail / SwCarousel / SwVideoFeed)三语 + DemoBox;「广告底座与打点」指南三语
- 🚀 llms.txt / llms-full.txt 构建期生成(AI 友好文档入口)
跨仓事件
- 🔧 pnpm 11+ 全生态统一闸门 — 各仓 engines.pnpm ">=11" 下限、去 corepack / packageManager 钉死、pnpm 字段迁 pnpm-workspace.yaml、CI 改装 pnpm@11
- 🔧 release 链路安全化 — 4 发版仓统一 npm version(pnpm version 忽略 tag prefix 的坑)+ release 闸门加 typecheck 硬门 + release script 安全加载 .env(杜绝 secrets 打到 stdout)+ 删各仓 .env 收敛 ~/.zshrc 单一凭证源
- 🔧 配置体系整改(framework#164)— 项目常量进 nuxt.config、.env 只留环境相关、运行时零必填 env(根除 cluster 非主实例配置为空的雷),framework / starter / standards 联动落地
- 🔧 测试大补齐 — framework e2e 夹具场景数门槛入规 + 全组件夹具扩充(#143–156 群,e2e 240 全绿);starter 页面 smoke 消覆盖率 0/0 盲区;cli 参数组合 + 边界测试
2026-05
framework v0.7.0 → v0.16.0(9 个 minor + 数十 patch) · cli v0.2.7 → v0.5.1 · standards 首发 v0.0.1 → v0.1.3 · starter 首发 v0.14.0
5 仓体系(framework + starter + standards + cli + docs)成型并加速迭代的关键月,覆盖 ISR 安全增强、Cookie 加密、SEO 链路收归、SwButton 回归 vue idiom、verdaccio 私服上线、starter / standards 首次发 npm 包等多个跨仓事件。
framework
- ⚠️ useSeo 单一入口 + 修
<title>重复(v0.16.0 BC,refs framework#89)- 删
system.client链:旧版 hydration 后用后端 header 调useSeoMeta覆盖页面 title/description,导致<title>重复成站点名 | 站点名+ description 被后端值盖掉 - SEO 全显式单一入口:useSeo 不再从后端
systemStore.header兜底 title/description/keywords/og_image(缺失改 devconsole.warn,不静默兜底) - titleTemplate 交还 Nuxt 原生:移除
ModuleOptions.head.titleTemplate+useSeo的disableTitleTemplate入参;applier 改在nuxt.config.ts的app.head.titleTemplate配站点名后缀(源自swift.config.json的project.title) - JSON-LD
WebSite.name取runtimeConfig.public.siteName,不再读后端site_title;og:image 兜底仅本地/og-image.png - 升级 applier 须:每页显式传 title/description +
nuxt.config.ts配app.head.titleTemplate+runtimeConfig.public.siteName
- 删
- 🚀 sitemap.xml 精细化 + i18n strategy 检测(refs framework#85,配套 #87)
- GAP1:sitemap
siteUrl由NUXT_PUBLIC_SITE_URL锁定,跟 useSeo runtime origin 解耦(sitemap 是搜索引擎目录,必须稳定主域名;canonical 跟用户访问域名一致) - NUXT_PUBLIC_SITE_URL host 格式校验:合法 URL + http/https 协议 + 纯 origin(不带 path/query/hash)。dev
console.warn/ buildconsole.error,不阻断 build。能拦下漏协议(example.com)/ 占位符(<your-domain>)/ 错协议(ftp://)/ 带 path(https://x.com/api)等脏数据 - GAP2 简化版:检测
@nuxtjs/i18nstrategy ==='no_prefix'→ devconsole.warn引导改prefix*strategy(hreflang 互链自动配置由 framework#88 跟踪) - GAP3 默认 exclude 私有路径:sitemap 默认排除
/login、/register、/mine/**、/profile/**、/admin/**、/dashboard/**等通用私有路径,避免跟useSeo({ robots: 'private' })自相矛盾 - 新增
ModuleOptions.sitemap.exclude?: string[]让 applier 追加业务自定义私有路径(与 framework 默认合并,不是替换) - 新增 docs:sitemap 配置 / NUXT_PUBLIC_SITE_URL 配置 / ModuleOptions.sitemap
- GAP1:sitemap
- ♻️ useSeo origin 兜底链简化为单一事实源 + CSR 一致性诊断(refs framework#87)
- 4 层兜底(L1 explicit → L2
systemStore.info.site_url→ L3runtimeConfig.public.siteUrl→ L4useRequestURL().origin)→ 1 个事实源 + 1 个显式逃生口 - 主路径:
useRequestURL().origin(SSR Node 端从Host/X-Forwarded-*解析 / CSRwindow.location.origin) - L1 explicit
input.siteUrl保留为「显式逃生口」(多副域名想强制 canonical 收敛到主域名时用) - CSR hydration 阶段一次性比对
<link rel="canonical">与window.location.origin,不一致 = nginx 透传配错 → devconsole.warn/ prodconsole.error+ 修复指引 + docs URL(nginx origin 透传配置) SystemInfo.site_url字段保留供业务读取(如「最新地址」跳转链接),不再参与 SEO origin 决策NUXT_PUBLIC_SITE_URL仅 build-time 用(prerender / sitemap)- 行为变化但 API 签名不变 —— 旧依赖 L2/L3 兜底的项目需确认 nginx 透传
Host/X-Forwarded-Host/X-Forwarded-Proto,否则 canonical 会拿到内网地址(诊断 console 会立刻报警)
- 4 层兜底(L1 explicit → L2
- 🔧 publishConfig 切 verdaccio(v0.14.0 / v0.14.1,refs framework#77 / #78 / #79)
- framework 切自托管 verdaccio 私服(
npm.djatm.cloud),下游 applier 装包不再经 GitLab npm registry - prepublishOnly 钩子在发版时从 publish manifest 剥离
scripts.preinstall,避免消费方 install 时误触发 pnpm 检查脚本 - workspace 配置
@swift-web/standards: false防 consumer 跑 standards 的 preinstall
- framework 切自托管 verdaccio 私服(
- ⚠️ defineRouteRules 硬校验 + 删默认 error.vue(v0.13.0 双 BC,refs framework#71)
- applier 须显式开启
experimental.inlineRouteRules,未开启时 framework 模块 setup 阶段直接报错 - 此前是 silent no-op:applier 写了
defineRouteRules但实际无效,ISR / SSR 行为切换会暴露既有问题 - 删 framework 默认
error.vue,errorComponent 完全交 applier 自定义 - framework 内部
createError直接抛错,不再 fallback 渲染兜底页
- applier 须显式开启
- 🐛 SSR / 错误处理强化(v0.12.7 ~ v0.13.0 系列)
- SystemInfo onError 默认改为 fail-fast throw,删 SSR 阶段 deviceId guard 让
onError='throw'真实生效 createError改用error.data: { source, title, cause }结构化携带诊断信息,不再靠 message 字符串拼接- SSR 期空 apiBase fail-fast 明确报错,不再 silent 跳过
- SSR 期 deviceId 用固定值
'node'(后端约定),跟客户端逻辑解耦 - SSR error.vue 渲染时 client 不再后台拉 systemInfo + title 含完整 API 路径
- 整体让 SSR 失败立刻可见,不再积累隐性损坏
- SystemInfo onError 默认改为 fail-fast throw,删 SSR 阶段 deviceId guard 让
- ⚠️ SwButton API 重设计(v0.12.0 BC,refs framework#56 / #57)
- 自 v0.6.0 起 SwButton 使用
onTapcallback prop + 100ms 内置节流 + 主动 filteronClick,反 vue idiom + 反业界惯例(el-button / antd / mui / reka-ui 都不做内置节流,全部 emit@click) - 删
onTapcallback prop,改用标准@clickevent:<SwButton :on-tap="fn">→<SwButton @click="fn"> - 删
waitprop + 100ms 内置节流,async 期间防 double-submit 改由父组件管:loading状态机 - 删
inheritAttrs:false,vue 标准透传,class/style/aria-*自动透传到原生<button> - 新增
nativeType: 'button'|'submit'|'reset'(form submit 必备)/autofocus/icon(左侧图标 Vue 组件,loading 时被 spinner 替换) - 新增默认 loading spinner:
:loading="true"没传#loadingslot 时自动渲染(约 10 行 CSS,1em+currentColor自适配按钮文字大小颜色) - 配合 standards mr-review SB-001(
@click绑 async handler 必须传:loading)+ SB-002(form submit 必须传native-type="submit")兜底
- 自 v0.6.0 起 SwButton 使用
- 🚀 测试基础设施(v0.12.7 ~ v0.12.12 系列)
- 接入 vitest coverage(v8 provider + json-summary reporter)
- 重写 SwButton e2e 覆盖 disabled / loading / type / icon 主要 props
- utils/debug-log.ts 单测覆盖率 0 → 89.47%
- framework e2e gotoPage helper 绕开 @nuxt/test-utils createPage hydration 时序问题
- 🔧 release 流程 + 工程基础设施(v0.12.0+)
releasescript 拆三:release:patch/release:minor/release:major,裸release报错强制选版本(防 v0.12.0 BC 误发 patch 教训)- release script 显式传
--tag-version-prefix=fw/v,绕开 pnpm 不读.npmrc的 bug - 锁
packageManager pnpm@11.0.8 - playground devServer 端口 3500 → 3000(monorepo 端口统一)+ host env-aware
- 🐛 业务组件小修复(v0.12.x patches)
- SwQrcodeScanner 加 decode timeout 兜底,修非二维码图永挂 loading 真用户 bug
- upload-chunk 空文件(size <= 0)silent skip + 无任何回调,致消费方 pending 永锁(refs framework#60)
- SwImage
URL.createObjectURL内存泄漏(refs framework#61,已含在 SwImage 重构) - SwTiptapEditor template 内联 type cast
as在下游 applier rollup 解析失败 → 移到 script setupcomputed
- ⚠️ framework 接管 head 元素(v0.10.0 / v0.11.0 BC,refs framework#51)
<html>htmlAttrs 收归 framework(v0.11.0):lang单一事实源framework.i18n.defaultLocale;data-build-id/data-build-time按CI_COMMIT_SHORT_SHA→VERCEL_GIT_COMMIT_SHA→GITHUB_SHA→'local'优先级读环境变量- i18n plugin 自动注入
<html lang>(refs framework#51),替代 starter 在nuxt.config.app.head.htmlAttrs.lang写死 <title>titleTemplate 收归 framework(v0.10.0):默认'%s | %site_title',%site_titleruntime 替换为后端system.info.header.site_titleuseSeo取消site_title当 title 兜底,避免与 titleTemplate 叠加产出siteTitle | siteTitle的首页重复 buguseSeo({ disableTitleTemplate: true })单页关闭 titleTemplate 注入(适营销落地页 / 错误页 / 全屏专题页)- 新增 eslint 规则
swift-web/require-useSeo-in-pages:app/pages/**/*.vue必须显式调 useSeo,阻断 AI / 开发者漏写 - applier 的
app.head.htmlAttrs整块 + 顶部buildId/buildTime常量都可删
- ⚠️ Cookie / 登录态 / 设备认证安全加固(v0.9.0 BC,refs framework#48 / #45)
- AccountInfo 从 cookie 搬到 localStorage(加密),密码不再随每个 HTTP 请求飞到 header,DevTools Cookies 面板不再可见明文 JSON
- 🔴 修复「记住我」被绕过的隐私 bug:0.8.x 起 framework 在
loginByUsername/loginByQrcode内部总是无条件调用setAccount写 cookie 30 天,无视消费方"记住我"意图;0.9.0 通过options.remember让用户意图真正生效 AccountInfo接口新增必填remember: boolean字段;loginByUsername/loginByQrcode签名extra?: Record→options?: { remember?, extra? },remember默认true保持兼容- 核心 cookie(token / deviceId / channel_code / share_code)全部 AES-CBC 加密 + 默认
secure: true(localhost / 127.0.0.1 浏览器自动豁免) - 新增
userStore.clearAccount()action(单独清 AccountInfo 不动 tokenInfo)+useTheme.setTheme(theme)action useCookiewrapper 扩展支持maxAge/sameSite/secure/path/domain/default/watch;解密失败自动 fallback 兼容旧明文 cookie- 新增 eslint
no-direct-cookie-in-app规则编译期拦截app/下直读写敏感 cookie
- 🚀 ISR 安全增强 + path-aware lint plugin(v0.8.0 BC,refs framework#44)
- 针对 ISR 路径上的"设备 token 通过 Pinia payload 烤进缓存"等用户态泄漏隐患做系统性重构
- device + auth 身份从 SSR 期完全挪到 client hydrate 后建立,新增
auth.client.tsplugin 作为唯一建立点 system.server.ts简化:删 SSR 期userStore.login()+ 内置IGNORE_PATHS,保留 systemInfo 拉取 + initCodeuseAuthReadycomposable 让业务request()透明等到 auth.client 完成- framework
module.ts自动注入experimental.inlineRouteRules: true让 page 级defineRouteRules真正生效 - 新增
@swift-web/framework/eslintsubpath export,3 条规则:require-define-route-rules/no-isr-on-paid-paths/no-isr-on-user-state-paths - 0.8.1 path-pattern 改 segment 级匹配,覆盖嵌套路由;0.8.2 规则 options 支持自定义 segments;0.8.3
ModuleOptions.auth扩展boolean | AuthOptions支持auth: false关掉整套 client auth init - BC:
systemInfoIgnorePaths: string[]删除,改systemInfo: boolean | { enabled?, endpoint?, ignorePaths? };迁移示例['/']→false,['/p']→{ ignorePaths: ['/p'] }
- 🔄 SwImage / SwAsyncText 重构(v0.7.x ~ v0.8.x BC,refs framework#34 / #35 / #61)
- 移除
@nuxt/image依赖,新引入外链图 provider 抽象 - SwDecodeImage 删除,其加密能力收纳进 SwImage 统一图片入口(清理
.cursor-scale/.cursor-scale-av业务专属样式) - SwDecodeText 改名 SwAsyncText,并切到 useDecryptedAsset composable(依赖 #34)
- fix URL.createObjectURL 没对应 revokeObjectURL,加密图片列表场景内存泄漏(#61)
- SwImage 能力补齐:外层
click事件(覆盖 overlay)、titleprop(hover tooltip / SEO)、placeholder扩展string | { dark, light } | false、#placeholderslot、@load/@error透传、hover-zoomclass
- 移除
- 🚀 PWA SW 配置改业界主流(v0.7.7,refs framework#43)
- skipWaiting: true(新 SW 立即激活,不等所有 tab 关闭)
- clientsClaim: true(新 SW 接管所有 client)
- 图片 runtime caching 改为 StaleWhileRevalidate 策略(先返缓存 + 后台更新)
- 对齐 Workbox 推荐 + el-ui / antd-pro 等业界 PWA 默认行为
- 🚀 useSeo 长度阈值改用显示宽度算法(v0.7.5,refs framework#39)
- 原
validateSeoLengths用 JS.length(UTF-16 code units)对 ASCII / CJK 一视同仁 - 但 50-160 字符阈值按 Google SERP 英文字符宽度标准设计,CJK 在 SERP 视觉宽度约英文 2 倍
- 引入
displayWidth函数(CJK Unified Ideographs / Extension A-H / 全角符号 / CJK 标点算 2,ASCII 算 1) title/description走 displayWidth;keywords检查数量和总长度保持.length- 阈值数字(10/60/70 / 50/160/200)不变,单位含义升级为"显示宽度"
- 原
- 🔄 codegen 抽离到 framework(v0.7.0)
- 把 starter 的
optimize-images/generate-icons/check-og-image等构建脚本抽到@swift-web/framework/codegen子模块 - 下游
scripts/*.ts退化为一行薄封装(import + 调用) - 核心逻辑跟随
pnpm update @swift-web/framework升级,applier 不再需要"复制 starter 脚本到自己项目"的旧维护模式 - framework 提供纯函数 + 回调接口(如
generateIcons的onFaviconConflictcallback),终端交互留在调用方 - starter 五个脚本完成迁移
- 把 starter 的
starter
- ⚠️ 适配 framework#89 SEO 单一入口(v0.14.2)
nuxt.config.ts改用 Nuxt 原生app.head.titleTemplate: \%s | ${swiftConfig.project.title}`+runtimeConfig.public.siteName(站点名源自swift.config.json的project.title`,单一事实源)- 同步带 starter#24 修复:
.npmignore排除发包专用template-integrity.spec.ts,防泄漏到sw create派生的 applier
- 🚀 首发 npm 包(v0.14.0)
- starter 此前是 git-only template(cli 用 SSH git clone 拉模板),不发 npm
- v0.14.0 起作 npm 包发版,给 cli 用
npm pack取(配合 cli 0.5.0) prepack/postpack钩子处理 publish manifest:reset version 0.0.0、设 private:true、去 publishConfig / release scripts- 保证发出来的包是"新项目"模板状态而非业务实例
- 🔧 publishConfig 切 verdaccio + 升下游依赖
- 升 framework
^0.14.0+ standards^0.1.1 .npmrc切 verdaccio- 锁定 Vue 全家桶单版本修复生产构建 SSR 500
- patch vue-router 5.0.7 修复
@nuxt/test-utils下的 TypeError
- 升 framework
- 🔧 加 pnpm 11+ preinstall 阻塞
check-pnpm.mjs在 preinstall 阶段校验process.env.npm_config_user_agent- 未达 pnpm 11 / 用 npm / 用 yarn 立即 exit 1 + 中文引导
- 🔧 systemInfo onError 改 throw + nuxt-config 适配 fw 0.13
- 跟 framework fail-fast 策略对齐
- 开启
experimental.inlineRouteRules配合 fw v0.13.0 硬校验 - 升 framework 0.13.0
- 🚀 error.vue dev 详情结构化(配合 fw v0.12.9-0.12.11)
- dev 模式 error.vue 展示 error.message 详情
- 改用 error.data 结构化展示替代 message 字符串拆分
- 详情标题改红色(不再用前置圆点)
- 🚀 LoginForm 复用 framework 账号存储(配合 fw v0.9.0)
- 删 self-maintained
useLocal('login-username' / 'login-password' / 'login-remember')三项 - 改用 framework
userStore.setAccount/getAccountInfo/clearAccount - 通过
loginByUsername(u, p, { remember: isRemember.value })把"记住我"勾选意图正确透传给 framework
- 删 self-maintained
- 🚀 home 首页重写 + 视觉组件(v0.7-0.8 期)
- 重写首页 + icons 演示页
- 新增 LogoMark / LangSwitch / ThemeSwitch 业务组件
- 闪电 LOGO 重生成图标
standards
- 🚀 首次上线发版 v0.0.1 → v0.1.3(最新一波)
- v0.1.1:切 verdaccio publishConfig
- v0.1.2:preinstall 加 cwd-in-node_modules guard(防 consumer install 误触发)
- v0.1.3:prepublishOnly strip preinstall
- 🔄 目录重构 common-standards/ → rules/(marker 协议 v1 → v2 BC)
- 文件命名去前缀编号:
10-rendering-strategies.md→rendering-strategies.md _order.jsonsections 结构控制拼接顺序(替代靠文件名编号)- marker v2 加版本号防回退(v1 BEGIN/END 包夹 → v2 加
<!-- swift-web/standards@version -->) - 同步下游 4 仓的字面量引用
common-standards/→rules/
- 文件命名去前缀编号:
- 🚀 component-review-rules 体系(陆续完善)
- 按组件名纵向组织 mr-review 规则的新章节
- 首版 SwButton 两条:SB-001(
@click绑 async handler 必须传:loading状态机,防 double-submit)+ SB-002(form 内提交按钮必须传native-type="submit") - 后续陆续扩展到 18 条,覆盖 SwImage / SwModal / SwUploadImage / SwTiptapEditor 等组件的常见 review 失误
- 后续逐条机械化为 eslint 规则进
@swift-web/standards/eslint
- 🚀 eslint 规则集演进(v1 → v4 跨期)
- v4(fw v0.12.x):SwButton SB-001/002 机械化兜底
- v3(fw v0.10.0):require-useSeo-in-pages
- v2(fw v0.9.0):no-direct-cookie-in-app
- v1(fw v0.8.0):require-define-route-rules / no-isr-on-paid-paths / no-isr-on-user-state-paths
- 三档分级:必改(block PR) / 重要(讨论) / 次要(review 总结)
- 🚀 客户端安全主源章节(配合 fw v0.9.0)
- 5 条 review 规则:cookie secure、敏感字段禁 cookie、remember 透传、不绕开 wrapper、加密非安全屏障
- 客户端加密安全模型文档化:明确"加密 ≠ 安全屏障"(
cacheAesKey/apiKey在 client bundle 暴露),真正安全依赖 HTTPS + 后端鉴权 - 三语
/guide/client-encryption-boundary同步上线
- 🚀 ISR 安全 mr-review checklist + discuss-rendering v3(配合 fw v0.8.0)
- 渲染策略 §三 用户态泄漏(最严重风险)专章
- SWR 降级为 ISR 别名(简化判断复杂度)
- 决策树补 prerender (SSG) 行
- rendering-quick-guide 实践型指南
- 🚀 standards 仓上线 + npm 包发版(refs standards#1 / #3 / #4)
- 抽出 swift-web 通用规范作单一事实源 —— 渲染策略 / SSR 安全 / 公私 API 边界 / AI 提交标记 / 客户端安全等规则不再分散在 framework / starter / docs 的 CLAUDE.md
- 统一在
standards/rules/*.md维护,_order.json显式控制拼接顺序 pnpm sync脚本通过 marker 协议把规则段注入下游 4 仓的 CLAUDE.md- 作为 npm 包
@swift-web/standards发版,对外暴露/eslint子路径 - 含
navigate-to-must-return(Nuxt navigateTo 不能裸调)/root-class-sw-prefix(无 class 自动放过 + 多根独立判定)等机械化规则 /prettier+/stylelint子路径让各仓配置走import base + spread override模式
cli
- 🔧 适配 framework#89(v0.5.5)
applyProjectVars移除 titleTemplate 占位符替换(starter 改用读swift.config.json的模板字面量,sw create派生项目天然拿到自己的站点名,无需字符串替换)add.test.tsstore 演示输入改shopping-cart,避开旧 user store 命名触发 pre-release-doc-check 跨仓字符串误报
- 🚀 sw create 改 npm pack 模式(v0.5.0,refs framework#79)
- 此前
sw create通过 SSH git clone@swift-web/starter仓拉模板,要求新机器配 GitLab SSH key + 有对应 repo 权限 - v0.5.0 起改用
npm pack @swift-web/starter从 verdaccio 拉 tgz 解压(配合 starter 首次发 npm 包,见 starter 节) - 新机器零 GitLab 依赖:模板每次拉 latest,不再担心版本滞后
applyProjectVars替换package.json/nuxt.config.ts/README.md三处占位符的逻辑不变
- 此前
- 🔧 publishConfig 切 verdaccio + install 脚本删 AUTH 段(v0.4.0 / v0.5.0)
- cli 自身发版切到 verdaccio
- install.sh / install.ps1 删除 NPM_TOKEN AUTH 段(verdaccio
access:$all后匿名安装 OK)
- 🐛 sw info 补 errorHandler 行 + sw run 失败补 exit(1)(v0.3.x)
- sw info 输出补全 errorHandler 配置项展示
- sw run 子进程失败时正确传递 exit code
- 🐛 sw add page 默认渲染策略改 ISR(v0.3.x)
- 默认
ssr: true→isr: 3600,对齐 swift-web "ISR 是主力"的设计初衷 - 性能优先,必要时再走完整 SSR
- 默认
- 🔧 release script 拆三 + 裸 release 报错(v0.3.1+)
- 对齐 framework 拆
release:patch/release:minor/release:major,裸pnpm release报错 + 提示三选一 - 防 BC 改动"按 enter 默认 patch"误发(framework v0.12.0 已踩坑,cli / standards 同步对齐)
- release script 显式传
--tag-version-prefix=cli/v
- 对齐 framework 拆
- 🔄 命令层输出统一走 core/output(v0.3.1)
- 之前各命令文件零散调
console.log/console.error - 统一改
output.success/output.error/output.warn/output.info/output.hint - 配合
--text/--json模式实现 interactive / text / json 三态输出 - setNestedValue 泛型化
- 之前各命令文件零散调
- 🚀 接入 ESLint flat config(v0.3.x)
- 跟 framework / starter / docs 统一 lint 体系
- 接入
@swift-web/standards/eslint
- ⚠️ configKey 改名(v0.3.0 BC)
swiftWebFramework→swiftConfig,配置项 key 缩短- 注释 + 测试 fixture 同步更新
- 项目模板
nuxt.config.ts/swift.config.json同步迁移
- ⚠️ 删
sw init-mcp命令(v0.3.0 BC)- MCP 配置改为通过文档指导 applier 手工写
.mcp.json,不再由 cli 命令生成 - 配合
sw_framework_docsMCP tool 在 cli 内部一站提供
- MCP 配置改为通过文档指导 applier 手工写
docs
- 🔧 publishConfig + .npmrc 切 verdaccio
- 升下游依赖 framework
^0.14.0/ standards^0.1.1
- 升下游依赖 framework
- 🔧 加 pnpm 11+ preinstall 阻塞
- 跟 starter 同款
check-pnpm.mjs
- 跟 starter 同款
- 🔧 跟 framework 0.10 / 0.11 / 0.12 / 0.13 BC 同步文档
- SwButton API 重设计 → seo / 组件文档全面更新
- titleTemplate / htmlAttrs 接管 → framework/seo 文档章节新增
- defineRouteRules 硬校验 / removed default error.vue → routing / error-handling 重写
- SystemInfo fail-fast / createError 结构化诊断 → 文档同步更新
- 7 个组件文档同步 v0.12 API 重设计
- 🚀 三语 client-encryption-boundary 新增(配合 fw v0.9.0 cookie 安全)
- 明确"加密 ≠ 安全屏障"
cacheAesKey/apiKey在 client bundle 中暴露,真正安全依赖 HTTPS + 后端鉴权- 与 standards 客户端安全主源章节同步
- 🚀 docs framework/module-options systemInfo 文档迁移(配合 fw v0.8.0)
- 旧
systemInfoIgnorePaths章节替换为新systemInfoschema 文档 + 迁移说明 - systemInfo Store 自动初始化章节更新到新 API
- 简介示例配置移除
systemInfoIgnorePaths,改systemInfo
- 旧
- 🚀 三语 rendering-quick-guide 新增(配合 fw v0.8.0 ISR 安全)
- 5 分钟决策矩阵 + 详情页决策树 + 反模式速查 + 示例代码 + review checklist
- 与原
/guide/rendering-strategies(理论篇)并列 - 让实践派开发者快速决策选 ISR / SSR / CSR / SSG
2026-04
framework v0.4.x → v0.6.x · cli v0.2.1 → v0.2.7
SEO 标志性发布 + 组件大规模重命名 BC + 业务组件三态 prop 模式统一。
framework
- 🚀 auth 安全加固(v0.6.5)
initCode渠道码 URL 注入防护:?switch=1路径下从 URL 注入的渠道码会被中间件拒绝,防恶意链接劫持渠道归因- logout 清理同步:登出时同步清渠道码 cookie / IDB 解密缓存 / 约定登录凭证 localStorage 三处状态
- 🚀 useSeo dev 体验完善(v0.6.1 ~ v0.6.4 系列)
- v0.6.4:SEO 指南页从 framework 内部 wiki 迁出到公开 docs 站
- v0.6.3:告警 console 输出紧凑化 + 链接到 SEO 知识库 wiki
- v0.6.2:dev 长度警告加页面 URL + 新增
silenceLengthWarnings: true静音开关(私有页 / 工具页用) - v0.6.1:JSON-LD 切换到
@unhead/schema-org/vue导入路径(解决与 nuxt-schema-org 的签名差异)
- 🚀 SEO 标志性发布(v0.6.0)
useSeo()composable 一站式 SEO 元信息:每个 page 一次调用自动输出全套og:*/twitter:*/ canonical / JSON-LD- origin 4 层兜底:显式 → systemStore.info.site_url → runtimeConfig.public.siteUrl → useRequestURL(解决多副域名 + 反代未配齐 X-Forwarded 头时 canonical 漏内网地址)
- image 4 层兜底链:显式 → header.og_image → header.img → /og-image.png
- robots prop:
'private'(noindex,nofollow) /'noindex'(noindex,follow) / 任意原始字符串 - JSON-LD 默认输出 WebSite + WebPage schema;
type:'article'时加 Article schema - 强制启用
@nuxtjs/sitemap+nuxt-schema-org+@nuxtjs/robots三子模块(不可关闭,仅aiBotPolicy选项控制 GPTBot/ClaudeBot/CCBot/PerplexityBot 等 AI 训练 bot) - SwImage 新增
preloadprop 自动注入<link rel="preload" as="image">,配合loading="eager"+fetchpriority="high"用于详情页 hero 大图 LCP 优化 - 后端
system.info.header.og_image字段(运营 CMS 上传 1200×630 PNG/JPG);旧img字段保 0.6.x 兼容期 0.7.0 移除
- 🐛 业务组件多项修复(v0.5 / v0.6)
- useLoginBy iOS Safari 误判 WebView:原
/Version\/[\d.]+(?: Chrome\/)?/正则 Chrome/ 可选分组导致 iOS SafariVersion/X.X Mobile/...命中后被误判走 redirect 登录;修复为强制要求字面<空格>Chrome/ - SwModal:
description在同时传入默认 slot 时不渲染(aria-describedby警告),现在传入description即始终渲染 - useToast / useModal:
crypto.randomUUID在非 HTTPS 环境(如http://0.0.0.0)不可用,添加Date.now + Math.random降级兜底 - SwTiptapEditor:移除模板绑定中的
as Editor类型断言,修复vite-plugin-vue-tracer解析报错
- useLoginBy iOS Safari 误判 WebView:原
- 🚀 SwImage 能力补齐(c-image 迁移缺口,v0.5)
- 外层
click事件(覆盖 overlay 区点击) titleprop(hover tooltip / SEO)placeholder类型扩展为string | { dark, light } | false,对象形式走 CSS-only 主题切换placeholderClassprop + 内置最小化占位兜底样式#placeholderslot(slot 优先于 prop);@load/@error事件透传hover-zoomclass(opt-in)+ CSS 变量--sw-image-hover-zoom-scale
- 外层
- 🚀 新增组件(v0.5)
- SwAddToHomescreenGuide:H5 PWA 添加到主屏幕引导,从屏幕底部滑入非阻断式 bottom-sheet,iOS Safari / Android Chromium 各给对应步骤,桌面 / WebView / 国产浏览器静默不弹;
rememberForprop 支'session'/ 正数 N(N 天内不再弹);CSS 变量--sw-add-to-homescreen-guide-bg/--sw-add-to-homescreen-guide-radius/--sw-add-to-homescreen-guide-z定制 - SwQrcodeScanner:图片二维码识别,含
trigger/preview插槽 + 完整事件流 - SwQrcodeGenerator:二维码生成,自定义尺寸 / 容错级别 / 前景背景色 + PNG 下载
- SwFormField 简单模式:
name可选,新增required/hint/errorprop,作为表单字段布局容器使用,不依赖 vee-validate
- SwAddToHomescreenGuide:H5 PWA 添加到主屏幕引导,从屏幕底部滑入非阻断式 bottom-sheet,iOS Safari / Android Chromium 各给对应步骤,桌面 / WebView / 国产浏览器静默不弹;
- 🚀 业务组件「三态 prop」模式统一(v0.5)
onRecord/fetchPlayUrl等 prop 支持三种语义- undefined → 走默认 API(SwVideoPlayer 默认 POST
/movie/doHistory、SwAudioPlayer 默认 POST/audio/doHistory、SwVideoPreview 默认 POST/movie/play) - function → 覆盖默认行为
- null → 显式禁用
- 业务方零配置即可工作,需要走自己 API 时传 function,明确禁用传 null
- ⚠️ 组件大规模重命名 + API 重设计(v0.5 BC)
- SwBtn → SwButton:CSS class
sw-btn→sw-button;新增type语义类型 prop +loadingprop +#loading/#icon/#icon-right三插槽 - SwAlink → SwLink:
sw-alink→sw-link;安全修复target="_blank"自动加rel="noopener noreferrer",外链额外nofollow - SwPlayer → SwVideoPlayer:仅 rename,API 不变
- SwPlayerAudio → SwAudioPlayer:rename + 完全重写对齐 SwVideoPlayer。新增
url/type/linkCodev-model /initialSeekTime(替代seekTime)/ 14 emit / 6 expose(含switchLink保留进度),删playMode,修「切换线路 N 次 → N 个 timeupdate 监听堆叠」 - SwPlayerPreview → SwVideoPreview:rename + 能力补齐。
fetchPlayUrl三态默认走/movie/play,新增url直传跳过 fetch + mp4/webm 支持 +reload()应对 URL 过期 - AudioRecordParams 类型变化:新增
event/view_time/code字段(向VideoRecordParams对齐),自定义onRecord需更新类型签名
- SwBtn → SwButton:CSS class
- 🔧 reset.css / theme.css 增强(v0.5)
- 新增
scrollbar-width: thin全局细滚动条,消费项目开箱生效 - 暗色模式两个选择器加入
color-scheme: dark,浏览器滚动条轨道等系统 UI 自动切换为暗色 dexie/qrcode自动注入 ViteoptimizeDeps.include,pnpm 严格模式下消费项目不再需要手动配置
- 新增
starter
- 🚀 useSeo() 全量替代 useSeoMeta(配合 fw v0.6.0)
- starter 6 页全部迁移到 framework 接管的
useSeo() local-seo/require-seo-metaESLint 规则强制每页必填 SEO- 私有页(profile / login / register / mine 等 4 页)设
robots: 'private' / 'noindex'
- starter 6 页全部迁移到 framework 接管的
- 🚀 public/og-image.png 占位图 + prebuild check-og-image 检查(配合 fw v0.6.0)
- 1200×630 PNG 占位图放进 public/
scripts/check-og-image.ts在 prebuild 阶段验证,缺失则 build 失败- 防 applier 删 og-image.png 后社交分享卡片 broken
- 🚀 @phosphor-icons/vue(v0.5 期)
- 1300+ 图标、6 种风格作为标准图标库加入直接依赖
- 替代之前依赖 framework 自带图标方案
- 🚀 modal.css 默认视觉样式(v0.5 期)
- SwModal 默认视觉样式(遮罩、居中卡片、按钮、入场动画),亮 / 暗主题自动适配
- 可在
custom.css中覆盖--sw-modal-*CSS 变量定制
- 🔧 CSS rem 单位强制(配合 fw v0.4)
- stylelint
declaration-property-unit-allowed-list强制布局尺寸(width/height/padding/margin)用 rem - 跟随浏览器字号缩放提升无障碍
border-*和定位属性保留 px- 整工程从硬编码 px 切到 rem 单位制
- stylelint
- 🔧 auth 中间件增强(配合 fw v0.4)
guest.global中间件支持?switch=1参数,允许已登录用户进入登录页切换账号- logout 后凭证自动清除
- Guest 中间件匹配改用
startsWith,修复子路径未被正确拦截
cli
- 🐛 sw upgrade 私仓认证修复(v0.2.7)
- 原本
sw upgrade用npm view @swift-web/framework version拉版本,没透传~/.npmrc的_authToken,私仓访问 401 - 修复后正确传递 token,能从私有 registry 取得最新版本号
- 原本
- 🚀 MCP 工具
sw_framework_docs(v0.2.6)- 动态查询 framework 中可用的组件 / composable 清单
- 让 Claude Code 等 AI 工具不再凭印象引用旧组件名(避免如 SwBtn 已改名后 AI 还在生成 SwBtn 的失误)
- 配合
sw init-mcp生成.mcp.json(后续 v0.3.0 删init-mcp改文档指导)
- 🚀 i18n-applier 对称化 + scanBusinessI18nUsage(v0.2.4 / v0.2.5)
- enable / disable 流程对称,对齐 PWA / Tailwind 幂等原则
- 新增
scanBusinessI18nUsage模块扫描业务代码 i18n API 残留 - 精简 enable 汇报;列出 disable 残留
- 🚀
sw config sync命令(v0.2.3)- 重跑所有功能开关 applier(i18n / pwa / tailwind 等),把
swift.config.json与nuxt.config.ts强制对齐 - 用于:手工改了
swift.config.json后同步项目文件 / 升级 cli 后回灌新的开关默认值
- 重跑所有功能开关 applier(i18n / pwa / tailwind 等),把
- 🚀 Tailwind v4 applier(v0.2.1)
sw init交互扩展支持 Tailwind v4 一键启用- 自动注入
@import "tailwindcss"+ 必要 vite 插件 + tailwind.css + stylelint 白名单 - 六步注入幂等可重跑,关闭时自动回滚
- 🚀 swift.config.json 精简(v0.2.1)
- 移除冗余字段,与最新 ModuleOptions 形状对齐
- sw add page 模板加
useSeo占位与 framework SEO 强制启用对齐
- 🚀 @swift-web scope 迁移到 group registry(跨 v0.2.x)
- 从 project-level(432 / 435 分别 framework / cli)迁到 group-level(group 754)
- 单 token 访问全部包;安装脚本(install.sh / install.ps1)同步更新
- 简化 token 管理(之前每个包一个 deploy token)
docs
- 🔧 Sidebar 调整
- 各组件文档页同步 v0.5 组件重命名(SwBtn → SwButton 等)
- 新增"渲染模式快速指南"入口(指向待新增的 rendering-quick-guide)
- 🚀 6 个中文 markdown frontmatter 扩长达标
- 按新 useSeo 长度阈值(中文 25-80 字 = 英文 50-160 字符)
- use-add-to-homescreen / use-login-by / quick-start 简繁各 3 个
- SEO 长度建议表加"显示宽度"说明 + 中英对照
- 🚀 24 页 useSeo() 迁移(配合 fw v0.6.0)
- docs 自己也跟着 starter 走
- 英文页
silenceLengthWarnings: true(英文从中文翻译过来,长度不可控,length 警告对它们无意义)
- 🚀 三语 framework/seo.md 同步(配合 fw v0.6.0)
- 完整 useSeo() API 文档、origin / image / robots / JSON-LD 详细说明、SEO 强制启用机制
/guide/seo附录 A 提供 MR review 自检清单 + eslint 规则名映射
2026-03
5 仓首发月。
framework
- 🚀 首发 v0.1.0
- 20 个无样式核心组件:SwButton / SwImage / SwModal / SwToast / SwUploadImage / SwPlayer / SwQrcodeGenerator 等
- 8 个 composable:useModal / useToast / useTheme / useUploader / useLoginCheck / useLoginDialog / useLoginBy / useUserActive
- 2 个全局 store:userInfo(用户信息 + Token 管理)/ systemInfo(系统配置)
- 主题系统:light / dark / auto,localStorage 持久化
- 路由守卫鉴权体系:
guardedPaths/guestPaths配置 - 全局错误监控:Vue runtime 错误捕获上报
- 生态集成:@nuxt/image / @vite-pwa/nuxt / @nuxtjs/i18n
starter
- 🚀 首发
- Nuxt 4 项目工程结构 + ESLint + TypeScript 严格模式
- 内置 CI/CD(Dockerfile + GitLab CI 流水线)
- SEO 基础设施(
useSeoMeta()/ sitemap / OG 图片生成) - 作为 swift-web 唯一的下游业务模板源
cli
- 🚀 首发 v0.1.0
sw create <project-name>— 从 starter 模板生成完整 Nuxt 项目sw config— 交互式管理swiftWebFramework配置项(启用 / 禁用各子模块)sw add <type>— 代码生成器,快速生成页面 / 组件 / store 文件模板--text模式 — 在不支持彩色输出的 CI 环境降级为纯文本输出
docs
- 🚀 首发
- 基于 Nuxt Content 搭建官方文档站
- 自定义 docs 布局 + 导航(DocsNavSidebar / DocsToc / DocsPageHeader / DemoBox / ApiTable 等专用组件)
- 完成 20 个 Sw* 组件的 Props / Events / Slots 文档页与交互 Demo
- 完成 useModal / useToast / useTheme 等 composable 文档页
- 完成框架配置参考页(Module Options)
- 支持亮 / 暗 / 跟随系统三种主题,PWA 离线访问
- 三语言切换(简体中文 / 繁体中文 / English)