Skip to content

工程化实践

Git · iframe 通信 · AST 解析 · 前端监控 SDK · 条件编译 · VitePress vs VuePress


一、Git 常用命令

基本操作

  • git init / git add . / git commit -m "msg" / git status / git diff
  • git pull <remote> <branch> / git push <remote> <branch>

分支操作

  • git branch / git checkout -b <new> / git merge <branch> / git branch -d <branch>

撤销操作

  • git checkout -- <file>:恢复工作区
  • git reset <commit>:回退到指定 commit(保留工作区修改)
  • git reset --hard:完全回退(丢弃所有修改)
  • git revert <commit>:生成新 commit 抵消指定 commit(保留历史)
  • reset vs revert:reset 丢弃后续提交记录,revert 保留记录

提交规范

  • feat(新功能)、fix(修复)、refactor(重构)、docs(文档)、style(格式)、test(测试)、chore(构建/依赖)

二、iframe 父子页面通信(postMessage)

场景:组件库官网中通过 iframe 嵌入移动端预览站点,需实现父子页面路由同步。

核心实现

js
// 父页面发送消息
iframe.contentWindow.postMessage({ type: 'devui', value: newPath }, '*')

// 子页面接收消息
window.addEventListener('message', (event) => {
  if (event.data.type === 'devui') {
    router.replace(event.data.value)
  }
})

防止路由死循环

  • 问题:子通知父 → 父变更后又通知子 → 死循环
  • 解决:通过 sessionStorage 标记变更来源,来自父页面的变更不再回传

注意事项

  • postMessage 第二个参数建议指定目标 origin 而非 '*'(安全)
  • 需过滤 message 事件来源(Chrome 插件可能触发 message 事件)
  • 通过 event.data.type 标识消息类型进行过滤

三、AST 解析 Markdown 提取代码

场景:组件库文档中 demo 代码写在 Markdown 里,移动端预览需要复用这些代码。

方案:将 Markdown 转为 AST,遍历节点提取所需代码块。比正则更准确严谨。

js
const mdParser = require('@textlint/markdown-to-ast').parse
const mdAST = mdParser(mdFileContent)

mdAST.children.forEach(({ type, depth, lang, raw }) => {
  if (type === 'CodeBlock' && lang === 'html') { /* 提取 HTML 代码 */ }
  if (type === 'Header' && depth === 3) { /* 提取标题作为 demo 分类 */ }
})

四、前端监控系统搭建(SDK 开发)

目标:1 分钟感知、5 分钟定位、10 分钟恢复

异常捕获

  1. 运行时错误window.addEventListener('error', handler, true) — 捕获阶段,可拦截资源加载错误
    • 过滤 Script error.(跨域脚本错误)、JSBridge 告警等无效错误
    • 资源超时判断:performance.getEntriesByType('resource')duration > 20s 视为超时
  2. Promise 错误window.addEventListener('unhandledrejection', handler) — 捕获未处理的 reject
  3. 框架错误
    • Vue:重写 Vue.config.errorHandler
    • React:创建 ErrorBoundary 组件,在 componentDidCatch 中上报
  4. SourceMap 还原:使用 devtool: 'hidden-source-map',发布后上传 .map 文件到服务端

行为采集

  1. 用户行为:监听 click 事件,白名单过滤(a/button/li + 特定 className)
  2. XHR 劫持:重写 XMLHttpRequest,记录请求耗时、响应大小、状态码
  3. 路由跳转:劫持 history.pushState/replaceState + 监听 popstate

数据上报

  • GIF 信标new Image().src = url + '?data=...' — 兼容性好、不阻塞页面、不携带 cookie
  • POST 上报:数据量大时用 fetch(url, { method: 'POST', body }) 避免 URL 长度限制

错误回放(rrweb)

  • 利用 MutationObserver 异步记录 DOM 变化,序列化为 JSON
  • 每 10 秒制作快照,保留最近 2-3 段行为记录(控制在 500KB 内)

身份标识与指纹

  • 页面级 identitysessionStorage 存储随机标识
  • Canvas 指纹:绘制固定内容 → base64 编码 → 配合 UA + IP 做 MD5 计算 UV

全链路日志关联

  • Nginx 网关自动生成 X-Request-Id → 响应头携带 req-id
  • SDK 读取响应头 req-id 存入日志,实现前端通信日志与后端服务日志关联

五、Vue 项目条件编译

场景:同一套代码构建出不同版本(如公有云/私有云),需要按环境剔除部分代码

实现方案js-conditional-compile-loader + cross-env

html
<!-- IFTRUE_public -->
<div>仅公有云版本显示</div>
<!-- FITRUE_public -->

<div>所有版本都显示</div>

编译时不满足条件的代码块被完全剔除,不会出现在最终产物中


六、VitePress vs VuePress

对比项VitePressVuePress
构建工具ViteWebpack(可配置 Vite)
启动速度极快(毫秒级冷启动)较慢
体积更轻量较大
主题/插件生态较新,正在完善成熟丰富
适用场景Vue3 项目文档、组件库文档需要丰富插件的项目
  • VitePress 支持直接在 .md 中写 Vue 组件
  • 组件库文档常用插件:vitepress-theme-demoblock(demo 代码块展开/收起)

相关