搜索高亮别急着包 span:CSS Custom Highlight API 的边界和取舍 搜索高亮不一定要反复往 DOM 里塞 span。从实时搜索、长文档和编辑器高亮的问题背景出发,拆开 CSS Custom Highlight API 适合解决的绘制层问题、语义和兼容边界,并对比 mark.js、react-highlight-words、CodeMirror、Tiptap 等开源方案。 2026-08-14
TypeScript 7 升级要并行安装:让 tsc 变快,让 ESLint 留在 TS 6 API TypeScript 7 最诱人的变化,是把编译器和语言服务迁到了 Go。对每天反复跑 tsc、开编辑器等诊断、让 Agent 一轮轮改代码的人来说,这类性能提升很实在:少一点等待,机器也少一点白白发热。 我这次在这个 Hexo 博客仓库里做了一轮真实升级验证。结论先放前面:这个项目可以让 tsc 使用 TypeScript 7,但不能把根依赖里的 typescript 直接替换成 7。当前更稳的 2026-08-14
Vue KeepAlive 内部滚动恢复怎么封:库、生命周期和跨版本适配 内部滚动恢复看起来只是两行代码:离开时记 scrollTop,回来时再写回去。 真正做进业务以后,它会很快变成一个生命周期问题。el-table 的滚动容器不在宿主元素上,<keep-alive> 会把组件树移出再插回,激活后接口刷新又可能把滚动位置打回 0;如果用户已经开始滚动,恢复逻辑还不能继续把位置顶回旧值。 这类问题最好不要直接沉淀成一段 directive 模板。更稳的拆法是 2026-08-14
Codex 只认一个账号时,浏览器登录态怎么组织 Codex Tab 只能同时使用一个 ChatGPT 账号,但浏览器可以保存多份登录态。文章整理 ChatGPT Web、Codex App 和浏览器 Profile 的边界,给出 Edge/Chromium 专用数据目录的低频切换方案,并说明第三方多会话扩展为什么不适合作为首选。 2026-08-12
给静态博客音乐播放器补一个单一播放页所有权 静态博客里的全局音乐播放器真正卡在页面生命周期:普通跳转会销毁音频实例,新标签页又可能重复发声。这篇记录不引入 PJAX 和后端,只用 localStorage 短租约、BroadcastChannel 和首页新标签页打开,把“只让一个页面发声”做成可维护的前端协议。 2026-08-08
Windows 上 Node spawn 命令为什么会 ENOENT:从 cmd shim 到 execa Windows 上很多 CLI 入口会通过 .cmd / .bat 或 node_modules/.bin shim 暴露。Node 原生 spawn 裸跑命令时容易踩到 PATH、PATHEXT 和参数转义边界;长期维护的工具脚本更适合把命令执行统一交给 execa。 2026-08-04
Windows 上别直接相信 python 命令:给本地校验补一个跨平台入口 Windows 上的 python / python3 可能只是 Microsoft Store App Execution Alias,脚本看似有 Python 入口,实际校验会直接失败。更稳的做法是把 Python 探测、Codex bundled Python、py launcher 和临时 PyYAML 依赖放进一个 Node 包装器,让 Skill 校验只暴露同一个跨平台命令。 2026-08-03
GitHub SSH 克隆在 22 端口断开时,改走 443 端口 给 GitHub 添加 SSH 公钥后,git clone 仍然可能失败。错误信息看起来像权限问题: git clone git@github.com:<owner>/<repo>.git Cloning into '<repo>'... Connection closed by 140.82.116.3 port 22 fatal: Could not read from r 2026-07-28
把 Codex Home 迁移做成跨平台 Node 脚本 Codex Home 迁移一开始容易写成 macOS 一套 shell、Windows 一套 PowerShell。更稳的做法是用一个零依赖 Node 脚本作为入口,把 symlink、junction、hard link、dry-run、备份和 WSL 边界都收进实现里,让读者只面对同一个迁移命令。 2026-07-27
把嵌套 clone 变成主仓库源码:一次 Git 归属边界清理 从别的仓库抄一份工具源码回来时,最容易留下嵌套的 .git 和原作者 remote。文章用一次清理过程说明怎么识别它是不是 submodule、怎么保留源码但切断上游 Git 关系、怎样调整 .gitignore,最后让主仓库只推自己的 Gitee 远端。 2026-07-26
把旧工具库迁到 es-toolkit:一次 sheng-tool 现代化改造 一次旧 TypeScript 工具库现代化改造:把 lodash-es、dayjs、Jest、Rollup 2 和 npm 托管文档迁到 es-toolkit、Vitest、tsdown、TypeDoc、GitHub Pages;用 exports、.mjs/.cjs、TSDoc 示例即测试、package smoke、publint 和 npm pack dry-run 卡住发布边界。 2026-07-25
Skill 管不住代码风格时:把项目约定写成 ESLint 护栏 Skill 能提醒 Agent 代码应该怎么写,却很难阻止它继续写出不符合项目风格的代码。更稳的做法是把高频项目约定沉淀成 ESLint 和脚本护栏:i18n key 必须静态、用户文案先进入清单、资源路径要真实存在、Figma 节点不能拿错,watch 里的无意义比较也能提前打标。 2026-07-24
Composable 的公开面别靠默契:用 ESLint 守住私有模块边界 Composable 抽多了以后,公开面、owner 和 Vue/Nuxt 上下文调用时机最容易漂移。文章把一次项目里的 composable 边界治理拆成五条可复制的 ESLint 规则:全局 source/action 层不反向依赖 UI,局部 composable 不接收全局能力透传,use*.ts 只导出主入口,私有子模块表达父子归属,上下文 API 保持顶层同步调用。 2026-07-24
把源码工作区嵌进 Hexo:Sandpack、Monaco 和本地预览的取舍 把文章里的完整示例从普通代码块升级成可浏览、可预览、可诊断的源码工作区:多文件源码交给 Sandpack,Lint 诊断交给 Monaco,代码包放进 /files/,打包产物放到 .code-lab-dist 再挂回 /js/code-lab/,本地 server 负责自动重启。 2026-07-24
把无限滚动触底触发器抽成 composable:虚拟列表、哨兵和滚动兜底 无限滚动最容易被写成一个 useIntersectionObserver demo:底部 sentinel 进入视口就请求下一页。但虚拟列表、短列表和接口状态变化会让这个模型失效。更稳的做法是把触底触发抽成 composable:哨兵观察负责常规场景,滚动距离负责兜底,数据变化后再等 DOM patch 和下一帧布局完成重新检查。 2026-07-24
构建过了不代表 Nitro 能启动:给 server bundle 补运行时 import 检查 Nuxt / Nitro 项目里,build 和 typecheck 通过不一定代表 server bundle 能在 Node 里启动。依赖升级后,旧包可能继续留下 package exports 不再公开的子路径 import。这个检查脚本在构建后扫描 .output/server,提取运行时裸包 specifier,并用 Node resolver 提前暴露 ERR_PACKAGE_PATH 2026-07-24
Skill 约束不了响应式尺寸时:用构建插件给 UnoCSS 自动补 lg 副本 Agent 可以记住样式约定,但不能保证每次都写对响应式尺寸。文章复盘一个 Astro / UnoCSS 项目如何在 mobile-forever、@unocss/postcss、UnoCSS transformer 和 PostCSS plugin 之间反复试错,最后用构建插件自动补 lg 副本,并用测试守住配置顺序。 2026-07-24
无限滚动为什么会跳到新底部:一次滚动快照恢复的复盘 复盘一次普通 feed 无限滚动在分页追加时跳到新底部的问题:先看错误 watcher 如何把当前会话快照误当历史快照,再拆出滚动恢复闸门、触底加载 composable、回归测试和可复制源码包。 2026-07-22
Tailwind @apply 不是把 class 搬进 CSS:哪些写法不能内联 很多人会把 Tailwind class 理解成 CSS 预设,但 @apply 只会内联 Tailwind 能识别并生成声明的 utility。文章从 CSS 值、group/peer 标记、自定义 class、v3/v4 的 @utility 和 @reference 差异讲清边界,并给出 lint 与编译检查的护栏。 2026-07-21
别等 review 才想起 SSR:给 Nuxt 模块级 composable 补上静态护栏 一次移动端个人页吸顶 Header 重构里,跨组件 DOM 状态确实需要浏览器会话级 source,但模块级状态又会碰到 Nuxt SSR 风险。文章复盘这条弯路:为什么不能只靠 Pinia、useState 或 .client.ts,最后如何用 client-only source facade、ESLint 规则、测试和可复制源码包把边界落下来。 2026-07-16
状态归属比组件封装更重要:一次 Profile 外层错误边界重构 一次 Profile 页外层状态重构里,加载、错误、空态和内容不可用被同一个 blocker 混在一起,导致状态切换和组件命名越来越难解释。文章记录如何先按 owner 拆开四态,再把 EmptyState、RenderErrorBoundary、StateHost 和主资源边界 composable 沉淀成可复制方案。 2026-07-15
用 const enum 和字符串值类型保留公开 API 的自然写法 组件和工具 API 里经常同时需要两种语义:内部代码希望用有名字的 enum 分支,外部调用方又希望直接传普通字符串。文章用 const enum 和 `${Enum}` 派生字符串值类型,把命名常量、公开字符串 API、lint 护栏和适用边界拆清楚。 2026-07-14
当组件只有一个调用方:可选 props 为什么应该被 lint 管住 一次 Vue 组件重构里,单调用组件仍然保留可选 props,导致父子契约变松、子组件继续写防御判断。文章记录为什么 optional props 是 API 契约,不只是默认值问题,以及如何用可复制的全仓组件调用图、defineProps AST 和架构 lint 把这类退化提前挡住。 2026-07-14
Composable API 为什么要默认用对象边界 业务 composable 和页面 helper 的入参、返回值默认用对象,核心价值是降低 API 演进成本。文章从位置参数、单值返回、对象解构和无参 resolver 四种写法出发,整理什么时候该用对象边界,什么时候可以保留底层工具式 API。 2026-07-13
Nuxt plugin 抢跑 Pinia 为什么会把应用启动打挂 一次 Nuxt 客户端插件为了抢在 WebSocket 建连前注册监听使用 pre 时序,结果早于 @pinia/nuxt 执行,启动阶段调用 useAppStore 触发 getActivePinia。文章复盘 plugin 顺序、Pinia 激活点、dependsOn 修复和脚本化 lint 护栏。 2026-07-13
Nuxt 自动导入不该靠自觉:一次组件和 Vue API import 的 ESLint 护栏 Nuxt 会自动导入组件和常用 Vue API,但手写 import 很容易在重构后留下冗余、deep import 和路径耦合。文章记录一次只用 warn、不做 autofix 的 ESLint 护栏:怎么限定扫描范围、对齐 Nuxt 真实组件名生成机制、放过非 owner 模块,并用扫描统计和测试支撑渐进治理。 2026-07-09
别让一个 composable 承担两种身份:一次 Profile 全局状态重构 一次 Nuxt Profile 页重构里,Header 和 Profile 共用的 useMeProfile 同时承担当前登录账号和当前路由用户两种语义,导致刷新链路、SSR 首帧和账号切换都变得含糊。文章记录如何把 source owner 拆成当前账号身份、当前账号基础资料、当前账号原始数据和路由 Profile source,并补上 stale response、写后刷新和单测护栏。 2026-07-09
Tailwind @apply 里的 ease 为什么会拖到构建才报错 一次 @apply ease 把 Tailwind utility 和 CSS 值混在一起,编辑器、stylelint 和 git hook 都没拦住,直到 Nuxt build 才失败。文章复盘为什么会这样,为什么标准写法是 ease-[ease],以及如何用 Stylelint 黑名单规则和文件级 Tailwind 编译脚本把问题提前到提交前。 2026-07-09
跑马灯文字为什么会重叠:一次 flex clone 布局问题的复盘 跑马灯文字重叠的核心常常是 flex 轨道、真实内容和 clone 的布局盒不一致。文章复盘一次长徽章文字盖住 clone 的问题,说明为什么要抽共享轨道组件、哪些 CSS 契约必须由共享层统一承担,以及 Lint、单测和 Skill 各自能防住什么。 2026-07-08
不要用屏幕宽度判断触摸交互:一次照片网格拖拽排序修复 照片网格在桌面端需要 hover 菜单和短按拖拽,在手机和平板上却需要长按菜单和长按排序。文章把问题拆成布局断点和输入能力两层,解释为什么不能用屏幕宽度判断交互方式,以及如何用 hover/pointer media query、SortableJS 触摸延迟和测试断言守住这个边界。 2026-07-08
浏览器为什么播不了 App 语音:一次 AMR 互通和策略模式改造 App 语音介绍在移动端能互通,到了 Web 却只转圈不出声。排查后发现,历史语音文件是 AMR,浏览器原生 Audio 不支持,资源 404 和 CORS 都不是根因。文章拆解 AMR 文件、媒体栈、播放与录音策略,以及 benz-amr-recorder 和 audio-decode 这两条库路线的取舍。 2026-07-08
Vue 的 script setup 泛型组件到底解决了什么 Vue 3.3 给 script setup 加了 generic 属性,让 SFC 组件也能像 TypeScript 函数一样把 props、emits、slots 和子组件透传绑定到同一个类型参数。文章结合官方文档、Vue Language Tools 源码和完整 ActionMenu 示例,解释多泛型怎么写、怎么被解析、怎么在调用方保留精确类型。 2026-07-07
Vue watch 的 cleanup 到底清理了什么 有一类前端 bug 很难从截图里看出来:页面已经切到新用户了,旧用户的异步结果才慢悠悠回来,然后把新页面上的一小块状态覆盖掉。 这次遇到的是个人主页里的距离展示。组件会监听用户身份、在线状态和经纬度,条件满足时读取浏览器已有定位权限,再计算「离我多远」。真正麻烦的是定位 API 本身:它不像 fetch 一样天然能用 AbortController 取消。用户快速切换个人主页时,旧页面发起的定位读 2026-07-07
一个昵称为什么这么难:emoji、PAG 特效和跑马灯 彩色昵称看起来只是一个文本组件,实际同时承载 emoji 原色、DOM 文本、PAG/WebP 前景特效和跑马灯。文章复盘为什么会出现重影、闪烁、金色文本和 clone 重叠,并整理真实文本层与视觉特效层的分工、测量和测试护栏。 2026-07-06
SVG 图标为什么在真机上被挤扁 PC 模拟移动端正常,真机上返回、关闭、充值图标却被挤扁。文章从 Figma 导出的 SVG frame、viewBox、preserveAspectRatio、真实可见边界和 CSS 尺寸入手,说明为什么不能只看外层尺寸,也不要把 SVG 变形误判成 rem 或响应式问题。 2026-07-06
少一点 formatter:前端展示层和后端原始字段的边界 很多前端复杂度来自太早把原始响应包成新的 view-model。文章复盘 Account Overview、菜单行、ProfileEditor 等场景,整理 raw source owner、derived display consumer、叶子组件格式化边界和测试方式,避免 formatter 变成黑盒。 2026-07-06
OpenWrt 路由器上跑 OpenClash:手动补内核、双路由和 fake-ip 排查 OpenWrt 路由器里 OpenClash 内核下载失败,补上后手机和其他电脑能走代理,只有 Mac 不行。文章把问题拆成内核架构、插件状态、家庭网络拓扑和 Mac 本机 Clash Verge TUN / fake-ip 冲突,按层确认流量到底被谁接管,形成一套路由器代理排查路径。 2026-07-04
别再用 length 统计用户文本:一次 Unicode 字符数和 ESLint 护栏复盘 昵称计数用 value.length,遇到 emoji 和国旗就会提前超限或截断错误。文章从 Unicode grapheme 出发,补统一的计数、截断、取首字符工具,再把昵称、签名、备注、搜索和举报描述迁过去,并用 ESLint 规则阻止后续误用,覆盖更多用户可见输入。 2026-07-03
Header 不要被页面反向控制:一次 Nuxt SSR hydration 错位复盘 一次 Nuxt Header hydration mismatch 复盘。先讲 layout 先渲染 Header、page slot 后写 Header 状态导致的时间线错位,再补充登录态首帧不可确定时为什么 key 不够、v-show 只能缩小结构破坏,以及如何用 @vue/server-renderer 写出稳定复现单测。 2026-06-29
NextAuth 安全升级撞上 sidebase 旧入口 一次 next-auth 安全升级消掉了 CVE 告警,却触发 @sidebase/nuxt-auth 对旧子路径 next-auth/core 的解析警告。文章从 package exports 变化解释原因,并讨论升级、兼容、回滚和本地 built Nitro 验证时该看哪些边界。 2026-06-26
WebStorm 主题插件被升级覆盖后,自己打一个固定版 WebStorm 升级后旧 One Dark 风格被覆盖,插件市场里的同名主题也不对味。文章记录如何从本地配置找回旧版主题,比较新旧 UI 色表,再把旧主题重新打成固定版插件,让每天盯着看的编辑器颜色保持稳定,也顺手解释 JetBrains 主题插件结构。 2026-06-26
Teleport 弹窗尺寸为什么会丢 一次账号编辑弹窗变窄的排查。根因集中在 Teleport + Transition + 初始 v-if=false 后插入节点这组触发条件:CSS v-bind 变量可能没有正确回填到目标节点。文章用最小复现排除 Teleport 普遍丢样式和 rem 换算这两条误判路径。 2026-06-22
自定义滚动条别挤布局:一次 hover 抖动的处理 弹窗网格在 hover 时因为滚动条出现而横向抖动。文章把问题归到 scrollport 宽度变化,最终用 v-scrollbar 封装 OverlayScrollbars:隐藏原生滚动条、保留原滚动元素契约、让滚动条视觉层不参与布局,适合菜单、弹窗和图片网格这类紧凑区域。 2026-06-17
Nuxt Image 不是 img 的平替:一次本地 assets 图片 404 的排查 把 img 换成 Nuxt Image 后,本地 assets 图片经 IPX 改写成 404。文章说明 Nuxt Image 是图片优化组件,不是 img 的无脑平替;public 图源、Vite import 资源、/_nuxt 路径和 provider 处理边界要分清,也说明什么时候该继续用原生 img。 2026-06-17
修复 Vue Devtools Open In Editor 找不到 Toolbox WebStorm Vue / Nuxt Devtools 的 Open in editor 找不到 JetBrains Toolbox 管理的 WebStorm。文章把问题定位到 launch-editor 的 macOS WebStorm 发现逻辑和实际应用包路径不一致,并给出修复和验证方式。 2026-06-11
Clash Verge TUN 下让公司内网依赖走内网 TUN 模式下,公司内网域名可能被 Clash DNS 接管并落到 fake-ip,导致客户端已连接公司网络但请求没有真正进内网。文章按代理规则、fake-ip 过滤、公司 DNS、fixed hosts 和 TUN 路由排除逐层处理,避免只靠一条 DIRECT 规则误判。 2026-06-09
把 Hexo 文章文件名、URL 和排序分开管理 从 source/_posts 的扫读体验开始,重新拆分 Hexo 的本地文件名、公开 URL 和列表排序。文章说明为什么文件名改成日期 + 中文标题,公开路径交给 url_title,同日排序用 url_title 稳定,文章资源继续映射到对应的 /files/ 公开目录。 2026-06-07
读《置身钉内》:AI 办公里的权力、责任和人的边界 围绕《置身钉内》这篇长文,顺着钉钉 ONE 项目的立项、发布、共创、迭代和收缩,讨论 AI 办公产品里的组织目标、产品权力、责任分配和人的位置。重点不是复述钉钉故事,而是看一个 AI 系统到底在替谁承担成本,又把哪些责任推回给人、团队和组织。 2026-06-07
iOS WebKit 中 transform 和 z-index 的一次层级闪烁排查 移动 H5 奖励卡在 Android 正常,iOS 切换时却短暂层级错乱。文章把问题缩到 WebKit 在 transform 动画里的合成处理,解释 z-index、旋转卡片和合成层之间的关系,以及为什么一行看似不改位置的样式能稳定表现,并提醒移动端要单独验证动画层级。 2026-06-05
一个 H5 装饰按钮在 Android WebView 和 iOS Safari 上的两次渲染排查 一个固定在右下角的 H5 装饰按钮,先后在 Android WebView 和 iOS Safari 暴露纹理、mix-blend-mode、半像素描边、overflow、圆角和动画裁剪问题。文章记录两次排查以及最后用更明确的裁剪和纹理层级稳住渲染,也提醒桌面 Chrome 正常不代表 WebView 稳定。 2026-06-05
Codex Skill 里不应该明文保存密钥 以 Figma token 为例,说明 Codex Skill 不应该保存明文密钥。Skill 是长期可复用指令,密钥会过期、泄露和轮换;更稳的做法是把私有 env、读取规则、过期提醒、备份范围和上下文暴露边界分开管理,避免进入仓库、日志和 Agent 上下文。 2026-06-04
组件状态和就近差异样式 从上传组件这类状态影响多个子元素的场景出发,讨论组件状态应该放在根元素上,子元素根据根状态改变表现。文章继续拆 SCSS、Less、Stylus、CSS Modules 和 Vue scoped 下 &、@at-root、空格和 BEM 选择器的输出边界,让状态样式更靠近组件结构。 2026-06-04
给 Vite Chrome Extension 补一个开发态自动 reload Chrome Extension content script 开发时很容易跑着旧运行时。文章把自动 reload 拆成三段:Vite watch 持续写真实 dist,扩展运行时负责重新加载,目标页面刷新后重新注入 content script,并说明为什么不能直接套普通 Web App HMR。 2026-06-03
Chrome Extension 里缓存已观察数据该放哪里 围绕 Jenkins enhancer 的已观察构建记录,比较页面 localStorage、chrome.storage.local、IndexedDB、storage.session 和内存变量。文章重点不是哪个 API 更高级,而是数据归属、可见性、生命周期和查询能力。 2026-06-02
Android 和 iOS App WebView 远程调试排查记录 按平台整理 App WebView 远程调试入口。Android 侧区分无线 adb pair/connect 和 USB 兜底,iOS 侧回到 Safari Web Inspector、WebKit 与 Xcode CoreDevice 链路,并说明无线调试的实际边界。 2026-06-02
静态站点缓存怎么配:从 Hexo 全站协商到 Astro 的 hash 资源 从 Hexo 博客错误使用长缓存头讲起,区分稳定 URL 和带 hash 资源的缓存策略。文章说明无 hash 的 HTML、CSS、XML 更适合协商缓存,浏览器每次复用前要验证;Astro 这类 hash 产物则可以走长期强缓存和 immutable,也解释 no-cache 名字为什么容易误导。 2026-06-02
把 Cursor 当工程工具,而不是聊天窗口 从成本、上下文、模型选择和团队沉淀出发,整理 Cursor 的日常使用判断。文章区分哪些任务适合 Agent,哪些先用 Ask 探索,哪些该交给官方文档或低成本模型,并把 Rules、Skills、验证命令、上下文控制和 review 成本放进同一套工程习惯里。 2026-06-01
Vite library mode 里漏到 Chrome Extension 的 process.env Chrome Extension content script 一加载就报 process is not defined,popup 却正常。文章把差异缩到 Vite 构建形态:library mode + iife 不适合当 content script 常规入口,最终改成普通 JS input 并固定输出 classic script。 2026-06-01
一次 Git 历史压平惊魂:orphan 分支和 git add -A 的坑 复盘一次发布前清理 Git 历史的险情。目标是把仓库压成新的初始化提交,但 orphan 分支、git add -A、未跟踪文件、删除记录和历史敏感信息会叠在一起;文章重点讲安全检查、备份分支、验证、提交作者和 force push 边界。 2026-05-30
后台管理系统常见 UX 问题总结 把一份后台管理系统 UX 问题清单重新整理成开发前就该考虑的判断。文章围绕筛选、表格、批量操作、弹窗抽屉、风险动作、空态、错误态和长期扫读成本,讨论后台作为工作台应该如何组织,目标是降低重复操作和判断成本,而不是按展示页思路堆卡片和装饰性布局。 2026-05-29
一次 Astro 静态构建里被误导的 MissingSharp 排查记录 CI 报 MissingSharp,硬盘上却不缺 sharp。文章复盘这次 Astro 静态构建排查:真正的问题来自一个 server import 在 prerender 阶段启动服务端副作用链,最后把错误带到图片优化和 native / CJS 包加载上,排障时要先确认副作用入口。 2026-05-28
Chrome Extension debugger 与 CDP 的能力边界 Chrome Extension 的 debugger 权限可以让扩展通过 CDP 操作目标标签页,但它有明显权限提示和安全代价。文章梳理普通内容脚本做不到的场景、debugger 能接触到的 DevTools Protocol 能力,以及 attach、detach、最小权限和用户触发边界。 2026-05-26
Vue script setup 中组件静默消失的原因:一次命名冲突排查 一次 Vue script setup 组件静默消失排查。页面没有明显报错,根因却是普通变量名和组件名只差大小写,模板编译时解析到了错误对象。文章从编译产物和组件解析规则还原问题,并提醒不要让组件和局部变量只靠大小写区分,适合排查“没报错但没渲染”的场景。 2026-05-26
Vue script setup 中 defineProps 的编译边界与错误排查 defineProps 看起来像函数,实际是 Vue script setup 的编译器宏。文章从一次把 defineProps 包进 toRefs 的错误开始,回到 @vue/compiler-sfc 对宏调用的识别边界,并用对应 tag 源码说明为什么运行时不该再出现它。 2026-05-23
把微信收藏表情导出来,再分批导入飞书 微信没有正式的收藏表情批量导出入口,飞书单次导入又限制 50 张图。文章记录一条可复用路径:让微信网页版展示表情,用浏览器拿图片资源,过滤无关图片,再按飞书限制分组打包成 zip,减少手工保存、重命名和重复整理,适合迁移大量收藏表情和图片素材。 2026-04-24
自己写小工具时,技术选型应该先想清楚什么 内部小工具常常从几行脚本开始,却很快接上上传、改库、调接口和批量处理这些真实副作用。文章提醒先判断一次性还是长期使用,再决定脚本语言、运行环境、依赖规模、dry-run、验证方式、失败退出和回滚边界,把“能跑”提升到“可控”,避免临时脚本变成长期隐患。 2026-04-10
一次 Hexo 文章目录结构探索:为什么最后放弃了 index.md 复盘一次 Hexo 文章目录和资源组织探索。文章比较 index.md 文章包、post_asset_folder、source/files、skip_render 和公开 URL 的实际表现,解释为什么最后放弃看起来更“文档站”的目录结构,改用中文本地文件名配稳定资源映射。 2026-03-26
没有个人 Git 仓库时,怎么维护自己的内部小项目 有些脚本、知识库和 AI 工作流资产暂时进不了正式业务仓库,但仍然需要长期维护。文章讨论没有个人远端 Git 仓库时,怎样用本地 Git、bundle、云盘备份和清晰提交习惯保住历史,同时避免把内部链接、旧项目痕迹和私有信息扩散到不合适的位置。 2026-03-12
WebStorm EAP 插件不兼容时,手动放开 until-build WebStorm EAP 升级后,插件经常只是因为 plugin.xml 里的 until-build 上限太保守而被拦下。文章说明 JetBrains 插件兼容范围里的 since-build 和 until-build 分别控制什么,以及解包、调整、重新打包安装时要如何判断风险。 2026-02-26
把 Codex Home 从隐藏目录搬出来,用 Git 管理 AI 工作流资产 把 Codex Home 从隐藏目录迁到可管理的私有 Git 工作区,用提交历史管理 AGENTS、Skill、规则、工具和私有环境配置。文章把跨平台 Node 迁移脚本作为主入口,再解释 macOS、Windows、WSL 的链接差异、skills/.system 的忽略边界和迁移后的旧路径清理。 2026-02-12
Node 文件遍历工具的迭代:从 walk 到 readdir,再到 tinyglobby 从一个 Hexo 发布脚本出发,比较 walk、Node 原生 readdir 和 tinyglobby 的取舍。问题表面是遍历 public 目录,本质是如何稳定枚举文件、生成 OSS object key、处理 Windows 路径分隔符、过滤文件集合,并把脚本维护成本压低。 2026-01-29
让 Codex 指挥 Cursor Agent 干活:一个省额度的多 Agent 工作流 把 Cursor Agent 当成可独立执行的 worker 接入 Codex 主工作台。核心不是把两个聊天窗口串起来,而是让 Codex 写清任务边界、工作区、输出格式和验收方式,Cursor 负责分担读仓库、查资料和初稿整理,最后再由 Codex 接回结果复核。 2026-01-15
HTTPS 到底解决了什么:证书、密钥交换和 TLS 握手 从 HTTP 明文传输的窃听、篡改和冒充问题讲起,拆开 TLS 证书链、RSA 密钥传输、ECDHE 密钥协商、前向安全和 TLS 1.3 握手。文章用小数字例子解释 RSA 的模幂陷门、Diffie-Hellman 到椭圆曲线 ECDHE 的计算方式,再落回浏览器如何验证服务器身份并协商会话密钥。 2023-11-22
需要什么样的 Git 多人协作方式? 围绕开源项目里常见的线性历史,讨论日常多人协作为什么容易变成分叉、临时提交和合并噪声。文章把提交、分支、rebase、squash、Fork + Pull Request 和同仓分支 + MR 放在一起,讲清差异、目的和该保留怎样的历史记录,方便后续 review、回滚和追溯。 2022-08-26
从 Windows 迁到 Mac 的开发环境与键位配置 记录从 Windows 切到 Mac 后如何重新调顺开发环境。重点不是软件清单,而是外接键盘、快捷键、锁屏、终端中断、滚动方向、触摸板手势这些每天重复很多次的动作,怎样在保留肌肉记忆的同时接受 Mac 自己顺手的地方,并适配系统入口变化和外设差异。 2022-08-11
你永远无法理解时间 转载一篇关于时间复杂性的长文。它用历法、时区、夏令时、闰秒、Unix 时间、系统时钟和单调时间拆掉很多常识判断,提醒开发者别把时间当成简单递增的数字,尤其别把本地时间、时间戳、系统时钟和跨端一致性混为一谈。适合在处理日期、定时任务和日志排序前先读一遍。 2022-06-02
用 cron 在 Node.js 里实现周期性定时任务 从 setInterval 写不下去的定时需求讲起,梳理 cron 表达式如何描述每天、每周、每月这类时间规则。重点放在 Node.js 里的 cron 包适合处理哪些小型周期任务,以及它只解决“什么时候跑”,不自动解决任务重入、进程重启和可靠性问题。 2022-05-09
npm、yarn 和 pnpm 的 lockfile 机制 从依赖漂移的真实问题切入,解释 package.json 只声明版本范围、lockfile 才记录完整依赖树。再顺着 npm、yarn、pnpm 的锁文件看,为什么团队、CI 和发布环境要提交同一份锁定结果,以及重装依赖、处理锁文件冲突、避免混用包管理器时到底在复现什么。 2022-05-09