工程化
发表于更新于
常见们工程化
OHNII7. 监控体系
7.1 性能监控
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| class PerformanceMonitor { constructor() { this.init(); } init() { window.addEventListener('load', () => { this.reportPerformance(); }); } reportPerformance() { const timing = performance.timing; const metrics = { dns: timing.domainLookupEnd - timing.domainLookupStart, tcp: timing.connectEnd - timing.connectStart, blank: timing.domLoading - timing.fetchStart, dom: timing.domComplete - timing.domLoading, load: timing.loadEventEnd - timing.fetchStart }; this.report('/api/performance', metrics); } report(url, data) { navigator.sendBeacon(url, JSON.stringify(data)); } }
new PerformanceMonitor();
|
7.2 错误监控
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| class ErrorMonitor { constructor() { this.init(); } init() { window.addEventListener('error', (event) => { this.reportError({ type: 'js_error', message: event.message, filename: event.filename, lineno: event.lineno, colno: event.colno, stack: event.error?.stack }); }); window.addEventListener('unhandledrejection', (event) => { this.reportError({ type: 'promise_error', message: event.reason }); }); window.addEventListener('error', (event) => { if (event.target !== window) { this.reportError({ type: 'resource_error', url: event.target.src || event.target.href }); } }, true); } reportError(error) { const data = { ...error, url: window.location.href, userAgent: navigator.userAgent, timestamp: Date.now() }; navigator.sendBeacon('/api/error', JSON.stringify(data)); } }
new ErrorMonitor();
|
7.3 用户行为监控
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| class Analytics { constructor(appId) { this.appId = appId; this.queue = []; } pageView(pageName) { this.track('page_view', { page: pageName }); } track(eventName, properties = {}) { const data = { appId: this.appId, event: eventName, properties, timestamp: Date.now(), url: window.location.href, userId: this.getUserId() }; this.queue.push(data); this.flush(); } flush() { if (this.queue.length === 0) return; const data = [...this.queue]; this.queue = []; navigator.sendBeacon('/api/analytics', JSON.stringify(data)); } getUserId() { return localStorage.getItem('userId') || 'anonymous'; } }
const analytics = new Analytics('my-app-id'); analytics.pageView('home'); analytics.track('button_click', { button: 'login' });
|
8. 面试口述版本
面试官:请说说你对前端工程化的理解
回答框架:
“前端工程化是通过工具和流程规范,提升开发效率和代码质量的体系。主要包括5个方面:
1. 代码规范
- ESLint检查代码质量
- Prettier统一代码格式
- Git Hooks提交前自动检查
- Commitlint规范提交信息
2. 构建工具
- Webpack/Vite打包构建
- Babel转译ES6+代码
- 代码分割、Tree Shaking优化
- 开发服务器、热更新
3. 模块化
- ES Module标准化模块
- 支持按需加载、Tree Shaking
- CommonJS用于Node.js
4. 自动化测试
- 单元测试(Jest)
- 集成测试
- E2E测试(Cypress)
- 测试覆盖率
5. CI/CD
- GitHub Actions/GitLab CI自动化部署
- 代码提交 → 自动测试 → 自动构建 → 自动部署
- Docker容器化部署
6. 监控体系
- 性能监控(Performance API)
- 错误监控(全局捕获)
- 用户行为分析(埋点)
工程化的目标是提升开发效率、保证代码质量、降低维护成本。”
9. 高频追问
Q1: Webpack和Vite的区别?
Webpack:
- 基于Bundle,打包所有模块
- 冷启动慢(需要打包)
- 热更新慢(需要重新打包)
- 生态成熟,插件丰富
Vite:
- 基于ESM,按需加载
- 冷启动快(无需打包)
- 热更新快(只更新变化模块)
- 生产环境使用Rollup打包
选择建议:
- 新项目:Vite(开发体验好)
- 老项目:Webpack(生态成熟)
Q2: 如何实现代码规范自动化?
1 2 3 4 5 6 7
| 1. ESLint + Prettier:代码检查和格式化 2. husky:Git Hooks管理 3. lint-staged:只检查暂存区文件 4. commitlint:提交信息规范
流程: git commit → pre-commit hook → lint-staged → ESLint/Prettier → 通过才能提交
|
Q3: CommonJS和ES Module的区别?
| 特性 |
CommonJS |
ES Module |
| 加载时机 |
运行时 |
编译时 |
| 加载方式 |
同步 |
异步 |
| 输出 |
值拷贝 |
值引用 |
| 动态加载 |
支持 |
不支持(需import()) |
| Tree Shaking |
不支持 |
支持 |
| 使用场景 |
Node.js |
浏览器、现代工具 |
Q4: CI/CD的完整流程是什么?
1 2 3 4 5 6 7 8 9 10 11
| 1. 代码提交到Git仓库 2. 触发CI流程: - 安装依赖 - 代码检查(ESLint) - 运行测试 - 构建打包 3. 测试通过后触发CD流程: - 部署到测试环境 - 自动化测试 - 部署到生产环境 4. 监控告警
|
Q5: 如何做前端监控?
性能监控:
- Performance API获取性能数据
- 上报LCP、FID、CLS等指标
错误监控:
- window.onerror捕获JS错误
- unhandledrejection捕获Promise错误
- 资源加载错误监听
用户行为:
- 页面浏览(PV/UV)
- 事件追踪(点击、提交)
- 用户路径分析
上报方式:
- navigator.sendBeacon(不阻塞)
- Image对象(兼容性好)
- fetch/xhr(灵活)
Q6: Monorepo的优缺点?
优点:
- 代码复用方便
- 统一依赖管理
- 原子化提交(多包同时修改)
- 统一构建、测试、发布
缺点:
工具:
- pnpm workspace
- Lerna
- Nx
- Turborepo
10. 实战经验
经验1:从0搭建工程化体系
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| 1. 初始化项目 - 选择构建工具(Vite/Webpack) - 配置TypeScript
2. 代码规范 - 配置ESLint + Prettier - 配置husky + lint-staged - 配置commitlint
3. 自动化测试 - 配置Jest单元测试 - 配置Cypress E2E测试 - 设置测试覆盖率要求
4. CI/CD - 配置GitHub Actions - 自动化测试、构建、部署
5. 监控体系 - 接入性能监控 - 接入错误监控 - 配置告警规则
|
经验2:优化构建速度
1 2 3 4 5 6 7 8 9 10
| 问题:Webpack构建时间从5分钟优化到1分钟
方案: 1. 使用cache缓存 2. 多进程打包(thread-loader) 3. 缩小构建范围(exclude) 4. DllPlugin预编译第三方库 5. 升级到Webpack 5
结果:构建时间从5分钟降到1分钟
|
经验3:统一团队代码风格
1 2 3 4 5 6 7 8 9 10
| 问题:团队成员代码风格不统一
方案: 1. 制定ESLint规则 2. 配置Prettier自动格式化 3. Git Hooks强制检查 4. 编辑器配置同步(.editorconfig) 5. Code Review流程
结果:代码风格统一,减少Review时间
|