如何清理源码里面没有被应用的代码
项目迭代久了,最常见的“技术债”之一就是:代码里堆了一堆没人敢删、也没人再用的东西——旧接口、废弃组件、改过几轮后遗留的工具函数、还有 CSS 里躺平的选择器。构建阶段的 Tree Shaking 的确能帮你把一部分“没被引用的导出”从产物里剔掉,但它解决不了“源码越来越难读、越来越不敢改”的问题。想把尸体代码从仓库里清干净,通常要靠静态分析 + IDE 辅助 + 人工确认这套组合拳。 下面按两类说:JS/TS 和 CSS。 清理 JavaScript/TypeScript 代码1. 使用静态分析工具ts-unused-exports / ts-prune 这类工具会扫一遍 TypeScript 工程,列出“导出了但没人用”的东西。它的优势是快,缺点是一定会有误报/漏报(比如动态引用、约定式导出、代码生成),所以输出更像“待处理清单”,别指望一键删干净。 ts-unused-exports该工具会分析你的 TS 源码,并报告所有未被使用的导出。你可以根据报告结果,手动或借助脚本自动删除这些代码。使用示例: 1npx ts-unused...
如何避免使用 Context 时引起整棵挂载树重渲染?
Context 真的是 React 里“又香又容易翻车”的东西:不想层层传 props?用它。结果某个值一变,凡是 useContext 过的组件全都跟着 re-render,一不小心就把页面拖慢。 我这篇想解决的不是“能不能用 Context”,而是“用了以后怎么别把整棵树一起带飞”。下面按一个比较工程化的思路:先搞清楚它为什么会触发渲染,再给出几种最常用、最容易落地的缩小影响范围的方法。 理解 Context 更新导致的重新渲染你可以把 Context 理解成“全局订阅”:组件一旦 useContext(SomeContext),就相当于订阅了这个 Context 的 value。只要 Provider 的 value 变了,这些订阅者都会重新渲染。 关键点在于:React 比较的是 value 的引用是否变化。也就是说,哪怕里面的字段没变,只要你每次 render 都 new 一个对象/数组/函数,引用就变了,订阅者照样会刷新。 优化策略1. 使用 useMemo 缓存 Provider value这是最常见也最“性价比高”的一招:让 Provide...
组件封装应遵循哪些基本准则?
我见过不少组件一开始封得挺开心,后面就开始长出各种 enableXxx、disableYyy、showZzz 开关,最后变成“谁用谁害怕”。组件封装最难的不是写功能,而是把边界画清楚:哪些能力属于组件、哪些应该交给组合;哪些应该做成显式 API、哪些可以隐藏在内部。 下面这些是我自己在写组件(不管 React/Vue 还是别的)时经常会过一遍的 checklist,偏经验总结,尽量可落地。 一、设计目标与基本原则我通常会先问自己三个问题:这个组件解决什么问题?它的“最小好用”长什么样?未来别人会怎么扩展它? 单一职责(Single Responsibility):一个组件只解决一类问题;超出边界的能力通过组合扩展。 显式 API:输入输出清晰,避免“魔法”与隐式副作用;缺省值合理且可覆盖。 可组合性优先:通过组合(children、slots、render props)扩展能力,而非内置过多开关。 受控/非受控双模:同时支持受控(value/onChange)与非受控(defaultValue)用法。 可访问性(A11y)内建:ARIA 语义、...
如何做好代码重构
我对“重构”的定义很朴素:业务行为不变,但你下次改需求不会骂街。 很多人把重构做成了重写:开个大分支,改一堆东西,然后合并时痛苦到怀疑人生。更稳的做法是小步快跑:先把安全网(测试/回归点)搭起来,再一点点把“难维护的结构”拆开。 下面按我在项目里比较常用的套路,聊聊重构的流程、常见手法,以及几个真挺容易踩的坑。 代码重构的整体流程1. 分析和识别代码问题重构前别急着动手,先回答两个问题: 现在这段代码到底哪里痛(改一次要摸很多文件?经常引 bug?性能/可读性问题?) 这次重构的边界在哪(只动某个模块?只抽公共逻辑?还是补齐测试后再拆层?) 常见的“代码异味”(Code Smells)我一般会重点盯这几类: 重复代码:相同或相似的代码片段出现在多个地方。 过长方法:方法体太长,逻辑复杂,难以维护。 过度耦合:模块之间依赖过于紧密,不易独立修改。 命名不规范:变量或方法名称模糊,不易理解其含义。 另外还有个很实用的信号:“改一个小需求,要在脑子里模拟半天才敢下手”。这种地方通常就是重构价值最高的区域。 2. 编写和完善测试用例如果这段代码完全没有测试...
什么是 requestIdleCallback?
你有没有写过这种代码:页面一打开,你顺手就想做点“顺便的事”——埋点、预加载、计算一堆东西、顺手还想把用户最近浏览记录也整理一下。 然后你发现:用户的顺便 = 主线程的噩梦。 requestIdleCallback 的思路很朴素:正事(输入、滚动、动画、渲染)优先,剩下的等浏览器“喘口气”再做。像你在工位被人叫住:“哥你先把线上故障处理了,我这 PPT 不急,等你空了再说。” 先一句话:requestIdleCallback 是啥?requestIdleCallback(cb) 用来注册一个回调:当浏览器主线程出现空闲(idle)时,尽量调用它,让你在“不会影响用户交互”的时间片里做一些不紧急的工作。 几个关键词你得先记住: 它是“尽量”,不是“保证” 它面向的是主线程的空闲时间(不是 Web Worker 那种真并行) 它更适合“可切片、可中断”的任务 为什么会有“空闲”这种东西?浏览器主线程平时主要忙这些: 跑 JS 样式计算 / 布局 / 绘制 处理输入事件(点击、滚动、键盘) 合成与动画调度 如果你在关键路径里塞了一个大计算,用户...
浅析如何做一套前端监控
我见过最“有用”的监控不是把大盘做得多漂亮,而是:线上一报错,你能在 5 分钟内回答三件事——是谁遇到了、在什么页面/什么操作遇到了、怎么复现/怎么修。 这篇不讲大而全的平台选型,按“从 0 落地一套能用的前端监控”来写:错误怎么抓、性能怎么量、用户行为怎么采、数据怎么上报,以及最容易被忽略的隐私合规怎么守住底线。 前端监控的目标与意义做监控前先把目标说清楚,不然很容易变成“什么都采一点,最后没人看”。我通常会把目标分成四类: 稳定性(错误):JS 运行时错误、Promise 未捕获异常、资源加载失败……你需要能“分组 + 定位 + 追踪版本”。 性能体验:首屏与交互是否顺(FCP/LCP/CLS/INP、长任务、请求耗时),以及“哪个页面/哪个接口在拖后腿”。 用户路径:用户做了什么操作后触发问题(点击/跳转/停留),让排障不再靠猜。 安全与合规:采集范围可控、敏感信息不落盘;必要时做脱敏、采样和权限控制。 一句话:监控的价值不在“数据多”,而在“能不能让排障更快、让质量可衡量”。 监控指...
何为单点登录(SSO)?
单点登录(SSO)这玩意儿,很多人第一次接触是在公司内网:你开了 OA,再点文档系统,不用再输密码;再点工单系统,还是不用。 这时候你会产生一种错觉:好像“全公司共用一个账号密码”就完事了。 其实不是。SSO 的精髓不是“共用密码”,而是“共用一次登录的结果”,也就是:我在一个可信的地方证明过“我是谁”,其他系统就别再折腾我了。 先一句话:什么是单点登录?单点登录(Single Sign-On, SSO):用户在一个统一的认证中心登录一次之后,就能访问多个相互信任的系统/应用,而不需要在每个系统里重复登录。 它解决的主要是两件事: 用户少输几次账号密码(体验) 公司少养几套“用户体系 + 权限体系 + 登录逻辑”(治理) 先认清角色:谁负责“认人”,谁负责“用人”?SSO 场景里最常见有两个角色: IdP(Identity Provider,身份提供方):负责认证,也就是“我来确认你是谁”。常见是统一登录中心。 SP(Service Provider,服务提供方):具体业务系统,比如 OA、工单、文档、财务系统等。 你可以把它理解成: IdP =...
git pull 和 git fetch 有啥区别?
我见过很多 Git 事故,开头都差不多:“我就随手 pull 了一下……” 然后分支就开始长出一堆莫名其妙的 merge commit,或者你本地改到一半突然冲突,心态当场下线。 其实 git pull 和 git fetch 的区别很简单:一个只更新“情报”,一个更新“情报 + 现场”。 先一句话结论(TL;DR) git fetch:把远端的新提交拉到本地,但不动你当前分支(不合并、不改工作区)。 git pull:等价于 git fetch + 把远端分支的更新合到你当前分支(默认 merge,也可以 rebase)。 所以我通常这样记: fetch = “我先看看远端发生了啥” pull = “我直接把远端的变化拿过来并处理掉” 先讲清楚一个重要概念:远端跟踪分支你执行 git fetch origin 以后,Git 会更新这些东西: origin/main origin/master origin/feature-xxx 注意:origin/main 这种叫 远端跟踪分支(remote-tracking branch),它只是 G...
macOS 用虚拟机装 Windows(VirtualBox)
一、虚拟机安装虚拟机选择我装 Windows 的目的很纯粹:在 macOS 上偶尔打开 IE/Edge 或者跑一跑 Windows 环境下的页面/脚本,验证兼容性。既然不是拿来当主力系统用,性能、功耗、资源占用这些就不用纠结太多,能稳定跑起来就行。 如果你也只是做测试,VirtualBox 的优势很明显:免费、足够用、还能随手打个快照。至于 Parallels / VMware 这类商业方案体验更好,但多数时候你可能用不到那份“丝滑”。附一个对比文章:macOS 下虚拟机选哪个? 市面上常用虚拟机里,VirtualBox 是长期免费的,所以我这里直接选它。 相关链接官网:https://www.virtualbox.org/ App 下载:https://download.virtualbox.org/virtualbox/6.1.32/VirtualBox-6.1.32-149290-OSX.dmg 二、Windows 系统镜像下载镜像下载网站: https://msdn.itellyou.cn/ 建议选择 Win10 系统的镜像 镜像文件一般比...
前端如何实现页面截屏?
截图这个需求看起来很简单:点个按钮,生成一张图。但真做起来你会发现它分成两类完全不同的问题: 把某个 DOM 区域“渲染成图片”(类似 html2canvas 的思路) 直接捕获屏幕/窗口/标签页的一帧(更像“录屏里截一帧”) 这篇文章按这两条路线各给一个原生实现的 demo,顺带把坑点说清楚;最后再补两个常用开源库的用法,方便你直接落地。 使用 Canvas 绘制 DOM 元素核心原理先把话说重一点:“纯原生把 DOM 画到 canvas”本质是在复刻 html2canvas。浏览器没有提供“一键把 DOM 截成图”的官方 API,所以你只能自己遍历节点、算布局、画背景、画文字、画图片……这条路能走,但边角非常多。 这里讲一个最简版本的思路:解析 DOM 树,用 Canvas 2D API 把你关心的信息画出来,最后导出图片。 遍历 DOM 树:从目标元素开始递归遍历所有子元素。 获取计算样式:利用 window.getComputedStyle 获取每个元素的最终样式(背景、字体、边框等)。 定位绘制:根据元素的 getBoundingC...
