一、前言
"我本地明明是好的"------上线事故的经典台词。及格线是"能跑",本篇把"能跑"升级成"放心跑":发布前六大类自查清单 + 一个 20 行的前端报错监控,全部可落地。
二、Checklist 总览
text
□ 1. 构建配置 □ 2. 环境变量 □ 3. 体验遗留
□ 4. 性能项 □ 5. 安全项 □ 6. 监控兜底
2.1 构建配置
text
□ sourcemap 已关闭(build.sourcemap: false,默认关------开了等于把源码送人)
□ console / debugger 构建时自动删除(见下)
□ 打包基于正确环境:build vs build:test(061 篇)
□ dist 体积骤增要排查(对比上次发版)
ts
// vite.config.ts:生产构建自动去 console
export default defineConfig({
esbuild: {
drop: ['console', 'debugger'] // ★ 构建时全局删除,源码不受影响
}
})
2.2 环境变量
text
□ VITE_API_BASEURL 指向生产地址(不是 localhost!------060/061 篇)
□ 所有 VITE_ 变量不含密钥(打包后明文可见------061 篇坑 3)
□ .env.production 与后端确认过域名/协议(https 混用 http 会被浏览器拦截)
2.3 体验遗留
text
□ 全局搜 TODO / FIXME / console.log(esbuild 兜底删,但业务调试逻辑要人工清)
□ 所有接口的 loading/空态/错误态三态齐全
□ 移动端适配机型抽查(iPhone SE 小屏 + 大屏)
□ 弱网(Network 面板 Slow 3G)下不白屏、有骨架屏
2.4 性能项(077/078 篇清单回收)
text
□ 分包 + gzip 生效(Network 看 transferred 体积)
□ 首屏 Lighthouse 跑分记录(优化前的基线数据)
□ 大图 webp/压缩,首屏图片懒加载
2.5 安全项
text
□ v-html 处的内容都经过 XSS 过滤(081 篇富文本回显)
□ token 不放 localStorage 的敏感接口已评估(至少不放密码类明文)
□ 接口权限后端兜底(070 篇:前端隐藏只是体验)
□ 依赖无高危漏洞:npm audit 跑一遍
2.6 监控兜底(重点,见第三节)
text
□ JS 报错监控已接入
□ 接口异常有埋点/日志(060 篇拦截器埋点位)
□ 知道回滚方案(保留上一版 dist 目录,出事切回去)
三、20 行前端报错监控(原理版)
企业一般接 Sentry/自研平台,原理就两层捕获 + 一个上报:
ts
// src/utils/monitor.ts
import { post } from '@/utils/request'
export function initMonitor() {
// ① 捕获 JS 运行时错误 / 资源加载错误
window.addEventListener('error', (e) => {
const msg = e.error
? `${e.error.message}\n${e.error.stack?.slice(0, 500)}` // js 错误 + 堆栈
: `资源加载失败:${(e.target as HTMLElement)?.getAttribute?.('src') ?? ''}`
report(msg)
})
// ② 捕获 Promise 里没人处理的 reject(060 篇拦截器漏网之鱼)
window.addEventListener('unhandledrejection', (e) => {
report(`未处理的 Promise 错误:${String(e.reason).slice(0, 300)}`)
})
}
// ③ 上报:sendBeacon 页面关闭时也能发出去(比 fetch 可靠)
function report(message: string) {
const data = JSON.stringify({
message,
url: location.href,
ua: navigator.userAgent,
time: Date.now()
})
navigator.sendBeacon('/api/log/fe', data)
}
ts
// main.ts 最后一行
initMonitor()
三个点:error 兜运行时、unhandledrejection 兜 Promise、sendBeacon 兜"报错瞬间页面就关了"。报错日志进后端后再接告警(邮件/钉钉),闭环完成。
四、发布流程建议
text
1. 打 tag / 记录本次版本号
2. 构建(正确环境变量)
3. 本地 dist 预览自测:npm run build && npx vite preview ← ★ 别跳过
4. 上传到带日期的新目录:/usr/share/nginx/html/20260908/
5. Nginx 软链切换:ln -sfn /usr/share/nginx/html/20260908 /usr/share/nginx/html/current
6. 线上冒烟测试(验证清单 084 篇)
7. 出问题:软链切回上一版目录,10 秒回滚
软链方案 = 发版即切换、回滚即切回,比"删了重传"安全一个量级。
五、踩坑记录
- sourcemap 悄悄开着:某次调试改了配置忘关------生产 map 文件暴露源码结构,npm audit 级别的事故
- 只测了 happy path:线上用户会乱点乱输------三态(加载/空/错)和弱网必须自查
- 监控只报错不聚合:同一错误刷 1000 条通知------后端按 message 聚合 + 频次阈值告警
- 回滚靠重新打包:线上急修时手忙脚乱------软链/多目录方案提前备好
- npm audit 看到高危就慌:先看依赖链是否能在不动主版本的情况下升级(npm audit fix),再评估影响面
- Checklist 存在心里:人会漏------沉淀成仓库里的 Markdown/Issue 模板,每次发版勾一遍
六、今日小结
- 六类清单:构建 / 环境变量 / 体验 / 性能 / 安全 / 监控,沉淀成文档逐项勾
- console 自动删:esbuild: { drop: 'console', 'debugger' };sourcemap 生产必关
- 监控最小实现:error + unhandledrejection + sendBeacon 三层
- 发布用多目录 + 软链:秒级回滚能力是底气
下篇预告
知识学完,市场检验:面试篇来了。下一篇 086 Vue3 高频面试题(上):响应式、diff 算法、Composition API 优势------每题给"简答 + 加分项",对标系列前文。