<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Honglei He&apos;s Blog</title><description>Welcome to Honglei He&apos;s personal site!</description><link>https://www.hehonglei.cn/</link><language>en</language><item><title>Cloudflare Pages Worker 体积优化实战：从 24 MB 到 3 MB 的瘦身之旅</title><link>https://www.hehonglei.cn/posts/cloudflare-pages-worker-size-optimization/</link><guid isPermaLink="true">https://www.hehonglei.cn/posts/cloudflare-pages-worker-size-optimization/</guid><description>将 Astro SSR 博客部署到 Cloudflare Pages 时遭遇 Worker 体积超限问题，通过图标按需导入、页面预渲染等一系列优化手段，最终将 Worker 体积从 24 MB 压缩到 3 MB 以内。</description><pubDate>Thu, 09 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;1. 背景&lt;/h2&gt;
&lt;p&gt;我的个人博客基于 Astro 5 构建，使用 &lt;code&gt;@astrojs/cloudflare&lt;/code&gt; 适配器以 SSR 模式部署在 Cloudflare Pages 上。某次常规更新后，突然发现部署失败，Wrangler 报错：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;✘ [ERROR] The Pages project &quot;my-blog&quot; does not exist.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个问题很容易解决——在 Cloudflare Dashboard 中创建对应名称的 Pages 项目即可。但紧接着第二个错误来了：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Error: Failed to publish your Function. Got error: Your Worker exceeded
the size limit of 3 MiB. Please upgrade to a paid plan to deploy Workers
up to 10 MiB.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;查看构建日志，Worker 总大小竟然高达 &lt;strong&gt;24 MiB&lt;/strong&gt;。本文记录了我一步步排查并解决这个问题的过程。&lt;/p&gt;
&lt;h2&gt;2. 问题定位：谁吃掉了 24 MB？&lt;/h2&gt;
&lt;p&gt;部署时 Wrangler 会打印模块清单。我按大小排序后，找到了几个「大块头」：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;模块&lt;/th&gt;
&lt;th&gt;大小&lt;/th&gt;
&lt;th&gt;占比&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;MainGridLayout&lt;/td&gt;
&lt;td&gt;14,898 KB&lt;/td&gt;
&lt;td&gt;61%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;data-layer-content&lt;/td&gt;
&lt;td&gt;3,748 KB&lt;/td&gt;
&lt;td&gt;15%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rss.xml&lt;/td&gt;
&lt;td&gt;776 KB&lt;/td&gt;
&lt;td&gt;3%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;config&lt;/td&gt;
&lt;td&gt;536 KB&lt;/td&gt;
&lt;td&gt;2%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;独立文章块（约 68 篇）&lt;/td&gt;
&lt;td&gt;~5,000 KB&lt;/td&gt;
&lt;td&gt;20%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;code&gt;MainGridLayout&lt;/code&gt; 一个组件占了全部体积的 &lt;strong&gt;61%&lt;/strong&gt;，这明显不正常。&lt;/p&gt;
&lt;h3&gt;2.1 根因 #1：图标全量打包（14.9 MB）&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;MainGridLayout&lt;/code&gt; 中使用了 &lt;code&gt;astro-icon&lt;/code&gt; 的 &lt;code&gt;&amp;lt;Icon&amp;gt;&lt;/code&gt; 组件，而 &lt;code&gt;astro.config.mjs&lt;/code&gt; 中是这样配置的：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;icon({
  include: {
    &quot;material-symbols&quot;: [&quot;*&quot;],  // 全量导入
    &quot;fa6-brands&quot;: [&quot;*&quot;],
    &quot;fa6-regular&quot;: [&quot;*&quot;],
    &quot;fa6-solid&quot;: [&quot;*&quot;],
    &quot;tabler&quot;: [&quot;*&quot;],
    &quot;flat-color-icons&quot;: [&quot;*&quot;],
  },
}),
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;[&quot;*&quot;]&lt;/code&gt; 意味着将 &lt;strong&gt;6 套图标集的所有图标数据&lt;/strong&gt; 全部打包进 SSR Worker。仅在 &lt;code&gt;@iconify-json/material-symbols&lt;/code&gt; 一个包中就有成千上万个图标，每个图标的 SVG path 数据都被序列化为 JS 对象。&lt;/p&gt;
&lt;p&gt;更关键的是，在 SSR 模式下，&lt;code&gt;astro-icon&lt;/code&gt; 不会将 &lt;code&gt;@iconify-json/*&lt;/code&gt; 标记为外部依赖（而在静态模式下会），导致所有图标数据被内联到 chunk 中。这就是 &lt;code&gt;MainGridLayout&lt;/code&gt; 14.9 MB 的来源。&lt;/p&gt;
&lt;h3&gt;2.2 根因 #2：内容数据层膨胀（3.7 MB + 5 MB）&lt;/h3&gt;
&lt;p&gt;项目有 68 篇 Markdown 文章，源文件合计约 460 KB。但在 SSR 模式下，Astro 5 将整个内容集合序列化为 JS 模块并打包进 Worker：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;data-layer-content（3.7 MB）&lt;/strong&gt;：所有文章的前言字段 + 正文 + 渲染后的 HTML + 集合元数据&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;独立文章块（~5 MB）&lt;/strong&gt;：每篇文章对应一个 60-110 KB 的 chunk，包含 expressive-code 语法高亮、Mermaid 图表等编译产物&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这两部分合计约 &lt;strong&gt;8.7 MB&lt;/strong&gt;，本质是将静态内容不必要地塞进了运行时。&lt;/p&gt;
&lt;h3&gt;2.3 根因 #3：RSS Feed 引入重型依赖（776 KB）&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;rss.xml.ts&lt;/code&gt; 导入了 &lt;code&gt;markdown-it&lt;/code&gt; 和 &lt;code&gt;sanitize-html&lt;/code&gt; 两个包，只是为了在 RSS 的 &lt;code&gt;&amp;lt;content:encoded&amp;gt;&lt;/code&gt; 中渲染文章全文。这对于一个已有 description 字段的 RSS feed 来说是完全多余的。&lt;/p&gt;
&lt;h2&gt;3. 优化方案&lt;/h2&gt;
&lt;h3&gt;3.1 图标按需导入（节省 14.6 MB）&lt;/h3&gt;
&lt;p&gt;首先统计项目中实际用到的所有图标。可以通过 grep 扫描全部 &lt;code&gt;.astro&lt;/code&gt;、&lt;code&gt;.svelte&lt;/code&gt; 文件中的 &lt;code&gt;&amp;lt;Icon name=&quot;...&quot;&amp;gt;&lt;/code&gt; 引用：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;grep -rn &apos;name=&apos; --include=&quot;*.astro&quot; --include=&quot;*.svelte&quot; src/ \
  | grep -iE &apos;material-symbols:|fa6-|tabler:|flat-color-icons:|ic:&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;整理出实际使用的图标清单（我的项目约 60 个），将配置改为：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;icon({
  include: {
    &quot;material-symbols&quot;: [
      &quot;arrow-forward-rounded&quot;,
      &quot;book-2-outline-rounded&quot;,
      &quot;chevron-right-rounded&quot;,
      // ... 约 30 个实际用到的图标
    ],
    &quot;fa6-brands&quot;: [&quot;github&quot;, &quot;react&quot;, &quot;vuejs&quot;, /* ... */],
    &quot;fa6-solid&quot;: [&quot;arrow-up-right-from-square&quot;],
    &quot;fa6-regular&quot;: [&quot;address-card&quot;],
    &quot;tabler&quot;: [&quot;rocket&quot;, &quot;brand-tailwind&quot;, /* ... */],
  },
}),
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;注意：&lt;/strong&gt; 如果你的组件中有动态图标名（如 &lt;code&gt;&amp;lt;Icon name={item.icon} /&amp;gt;&lt;/code&gt;），需要把所有可能的运行时值也加进去。我在首页的 TechStack、MovingTechStack、Projects 等组件中发现了大量此类用法。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;效果立竿见影：&lt;code&gt;MainGridLayout&lt;/code&gt; chunk 从 &lt;strong&gt;14,898 KB → 269 KB&lt;/strong&gt;。&lt;/p&gt;
&lt;h3&gt;3.2 预渲染内容页面（节省 6-8 MB）&lt;/h3&gt;
&lt;p&gt;对于博客这类内容驱动的站点，绝大多数页面在构建时就是确定的。Astro 5 支持对特定页面使用 &lt;code&gt;export const prerender = true&lt;/code&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
// src/pages/posts/[...slug].astro
export const prerender = true;

export async function getStaticPaths() {
  // ...返回所有文章路径
}
---
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;为以下 6 个内容页面添加了预渲染声明：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;页面&lt;/th&gt;
&lt;th&gt;预渲染内容&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;posts/[...slug]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;27 篇文章详情页&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;posts/[...page]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;文章列表分页&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;technology/[...slug]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;36 篇技术文章&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;technology/[...page]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;技术文章分页&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;read/[...slug]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;3 篇阅读笔记&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;read/[...page]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;阅读笔记分页&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;预渲染后，这些页面的内容不再打包进 Worker，而是输出为静态 HTML 文件，由 CDN 直接服务。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;踩坑记录：&lt;/strong&gt; 预渲染时 Astro 会尝试优化远程图片（调用 &lt;code&gt;inferRemoteSize&lt;/code&gt; 获取尺寸）。如果你的图片托管在 Cloudflare R2 等外部服务，需要确保构建环境能访问这些 URL。另一个选择是在 &lt;code&gt;ImageWrapper&lt;/code&gt; 组件中提供显式的 &lt;code&gt;width&lt;/code&gt;/&lt;code&gt;height&lt;/code&gt;，并设置 &lt;code&gt;inferSize: false&lt;/code&gt; 来跳过运行时图片尺寸推断。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;同时修复了一个潜伏的 bug：&lt;code&gt;BlogCard.astro&lt;/code&gt;、&lt;code&gt;PostCard.astro&lt;/code&gt; 等多个组件使用了 &lt;code&gt;currentLang&lt;/code&gt; 变量但从未定义（&lt;code&gt;const currentLang = Astro.locals?.lang&lt;/code&gt;），在 SSR 模式下因为 &lt;code&gt;Astro.locals&lt;/code&gt; 有全局默认值而没暴露，切换到预渲染后就报错了。&lt;/p&gt;
&lt;h3&gt;3.3 其他优化&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;banner 图片显式尺寸&lt;/strong&gt;：给 &lt;code&gt;&amp;lt;ImageWrapper&amp;gt;&lt;/code&gt; 添加 &lt;code&gt;width={1920} height={1080}&lt;/code&gt;，避免预渲染时的网络请求&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RSS feed 预渲染&lt;/strong&gt;：为 &lt;code&gt;rss.xml.ts&lt;/code&gt; 添加 &lt;code&gt;export const prerender = true&lt;/code&gt;，在构建时生成静态 XML&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;robots.txt 预渲染&lt;/strong&gt;：同上&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;4. 优化效果&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;阶段&lt;/th&gt;
&lt;th&gt;Worker 大小&lt;/th&gt;
&lt;th&gt;状态&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;优化前&lt;/td&gt;
&lt;td&gt;~24 MB&lt;/td&gt;
&lt;td&gt;❌ 部署失败&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;图标按需导入&lt;/td&gt;
&lt;td&gt;~11 MB&lt;/td&gt;
&lt;td&gt;❌ 仍超 3 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;图标 + 预渲染&lt;/td&gt;
&lt;td&gt;~3 MB 以内&lt;/td&gt;
&lt;td&gt;✅ 部署成功&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;最终，Worker 体积从 &lt;strong&gt;24 MB 压缩到 3 MB 以内&lt;/strong&gt;，成功部署到 Cloudflare Pages 免费计划。&lt;/p&gt;
&lt;h2&gt;5. 总结与建议&lt;/h2&gt;
&lt;p&gt;如果你的 Astro SSR 项目也遇到了类似的 Worker 体积问题，建议按以下顺序排查：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;检查依赖打包情况&lt;/strong&gt;：&lt;code&gt;astro-icon&lt;/code&gt; 的全量导入是最常见的体积炸弹，务必使用精确匹配的图标名而非 &lt;code&gt;[&quot;*&quot;]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;评估 SSR 的必要性&lt;/strong&gt;：纯内容展示页面应尽可能预渲染。Astro 5 中 &lt;code&gt;export const prerender = true&lt;/code&gt; 可以精确控制每个页面的渲染策略&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;审视重型依赖&lt;/strong&gt;：&lt;code&gt;markdown-it&lt;/code&gt;、&lt;code&gt;sanitize-html&lt;/code&gt; 等库体积不小，如果只在非关键路径使用，考虑按需加载或寻找替代方案&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;监控构建产物&lt;/strong&gt;：每次构建后检查 &lt;code&gt;dist/_worker.js/chunks/&lt;/code&gt; 目录，及时发现体积异常增长&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;项目虽小，部署到生产环境时这些细节往往会成为「最后一公里」的障碍。希望本文的排查思路能为你提供参考。&lt;/p&gt;
</content:encoded></item><item><title>AWS AI Agent 峰会见闻：国内企业 Agent 落地现状、挑战与实践</title><link>https://www.hehonglei.cn/posts/aws-ai-agent-summit-2026/</link><guid isPermaLink="true">https://www.hehonglei.cn/posts/aws-ai-agent-summit-2026/</guid><description>参加 AWS AI Agent 峰会的见闻与思考：从主题演讲到滴滴、SAP、安克创新等企业的实战分享，涵盖 Agent 安全、WorkFlow 设计、合规出海等话题，以及国内企业 AI 全链路覆盖的现状与挑战。</description><pubDate>Thu, 25 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;1. 引言&lt;/h2&gt;
&lt;p&gt;参加本次峰会的初衷，是想深入了解 AI Agent 在国内企业中的落地现状。两天的议程密集而充实，一个最直观的感受是：&lt;strong&gt;国内大量互联网企业及年轻公司已经基本实现 AI 全链路覆盖&lt;/strong&gt;——从销售、售前、售后，到开发、数据分析，每个部门都在利用 AI Agent 提升效率。&lt;/p&gt;
&lt;p&gt;然而一个普遍存在的问题也随之浮现：各个 BU 使用的 Agent 不同、底层 LLM 不同，导致信息孤岛和沟通成本的上升。如何打通这些环节、减少&quot;传话&quot;损耗，是当前全链路 AI 化企业面临的共同课题。&lt;/p&gt;
&lt;p&gt;本文按议程顺序，对两天所见所闻做一整理与扩写。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;2. 主题演讲：AWS Agent 服务体系全景&lt;/h2&gt;
&lt;p&gt;主题演讲围绕 AWS 构建 Agent 的工具链展开，核心产品包括：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;服务&lt;/th&gt;
&lt;th&gt;定位&lt;/th&gt;
&lt;th&gt;类比&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Amazon Quick&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;AI 助手&lt;/td&gt;
&lt;td&gt;类 Claude / Codex&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Amazon Continuum&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;编程助手&lt;/td&gt;
&lt;td&gt;类 Trae / Cursor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Kiro&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;更接地气的 AI 助手&lt;/td&gt;
&lt;td&gt;介于豆包和 Trae 之间&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Amazon Transform&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;大规模迁移/改造工具&lt;/td&gt;
&lt;td&gt;效果待验证&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Amazon Bedrock AgentCore&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Agent 开发平台&lt;/td&gt;
&lt;td&gt;类 Hermes Agent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AgentCore Harness&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;轻量 Agent 创建工具&lt;/td&gt;
&lt;td&gt;一句话生成 Agent&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;此外还分享了多家企业的 Agent 架构设计，为后续各专题分享做了铺垫。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;3. DevOps Agent 实践指南&lt;/h2&gt;
&lt;p&gt;该环节对各 AWS Agent 服务进行了逐一深入介绍。重点在如何将 Agent 嵌入 DevOps 工作流——从代码提交到部署监控，Agent 可以在每个节点承担自动化角色，减少人工介入。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;4. 企业 WorkFlow 设计：让 Agent 管理流程，而非人传递信息&lt;/h2&gt;
&lt;p&gt;这是一个很接地气的分享。讲者所在团队在实际使用 Agent 时发现，&lt;strong&gt;不同环节间的信息传递消耗了大量不必要的人力时间&lt;/strong&gt;——A 环节产出的结果，需要人为传达给 B 环节的 Agent，期间容易出现信息衰减、理解偏差。&lt;/p&gt;
&lt;p&gt;他们的解决方案是设计一个&lt;strong&gt;中央编排 Agent&lt;/strong&gt;，统一管理整个 WorkFlow 中各个子 Agent 的输入输出。信息流转由 Agent 直接对接 Agent，人类只需关注最终决策点。这种&quot;去人工传话&quot;的设计思路，对多 Agent 协作场景具有很好的参考价值。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;5. 安克创新：全业务线智能化转型&lt;/h2&gt;
&lt;p&gt;安克创新（Anker）分享了其自研 Agent &lt;strong&gt;Anka&lt;/strong&gt;，核心设计理念：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;多入口触达&lt;/strong&gt;：用户可从企业微信、飞书、内部 OA 等多个入口与 Anka 交互，体验一致&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;统一理解&lt;/strong&gt;：打通各业务系统的数据孤岛，Anka 充当统一的语义理解层&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;模型持续进化&lt;/strong&gt;：基于业务反馈持续微调，模型能力随业务共同成长&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;反哺业务增长&lt;/strong&gt;：从&quot;提效工具&quot;升级为&quot;业务增长引擎&quot;，Agent 产出的洞察直接指导业务决策&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;安克的案例说明，当 Agent 深入业务全链路后，它的价值就不仅是&quot;省人力&quot;，而是能够主动发现增长机会。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;6. SAP for Me：企业级 Agent 的边界哲学&lt;/h2&gt;
&lt;p&gt;SAP 分享了其平台内置的智能助手 &lt;strong&gt;SAP for Me&lt;/strong&gt;，背景是 SAP Support 场景分散在多个系统和门户中，用户需要在多个知识库中检索、对比，在多个系统中创建和分配工单——大量重复性机械劳动占用了支持人员的时间。&lt;/p&gt;
&lt;p&gt;SAP for Me 的能力包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;跨系统知识检索&lt;/li&gt;
&lt;li&gt;在多个系统中执行真实的读写操作&lt;/li&gt;
&lt;li&gt;完成端到端工作流&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;更值得关注的是 SAP 对&lt;strong&gt;个人 Agent&lt;/strong&gt; 与&lt;strong&gt;企业 Agent&lt;/strong&gt; 的区分：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;维度&lt;/th&gt;
&lt;th&gt;个人 Agent&lt;/th&gt;
&lt;th&gt;企业 Agent&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;设计哲学&lt;/td&gt;
&lt;td&gt;自由可扩展&lt;/td&gt;
&lt;td&gt;稳定可预期&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;安全模型&lt;/td&gt;
&lt;td&gt;自我把控&lt;/td&gt;
&lt;td&gt;开发者控制&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;预算&lt;/td&gt;
&lt;td&gt;低预算&lt;/td&gt;
&lt;td&gt;按需投入&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;操作流程&lt;/td&gt;
&lt;td&gt;灵活多变&lt;/td&gt;
&lt;td&gt;固定、不可出错、可溯源&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;边界&lt;/td&gt;
&lt;td&gt;开放&lt;/td&gt;
&lt;td&gt;明确、权限受控&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;这个对比切中了企业引入 Agent 时的核心矛盾：&lt;strong&gt;开发者喜欢个人 Agent 的自由度，企业却需要完全的审计追溯与权限控制&lt;/strong&gt;。找到二者的平衡点，是企业 Agent 架构设计的关键。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;7. 构建企业级 AI Agent 安全方案&lt;/h2&gt;
&lt;p&gt;安全是本次峰会的高频词。分享者指出，2026 年 Agent 安全领域的十大高危问题：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Agent 目标劫持&lt;/strong&gt;——攻击者通过注入恶意指令篡改 Agent 的执行目标&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;工具滥用&lt;/strong&gt;——Agent 调用工具的权限超出必要范围&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;身份和权限滥用&lt;/strong&gt;——Agent 持有的凭证被恶意利用&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;供应链漏洞&lt;/strong&gt;——Agent 依赖的第三方模型或插件被投毒&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;非预期的代码执行&lt;/strong&gt;——Agent 生成的代码绕过沙箱限制&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;记忆和上下文投毒&lt;/strong&gt;——恶意输入污染 Agent 的长期记忆&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;不安全的 Agent 间通信&lt;/strong&gt;——多 Agent 协作时通信信道被劫持&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;连锁失败&lt;/strong&gt;——一个 Agent 的错误决策在 Multi-Agent 系统中级联放大&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;利用人机信任&lt;/strong&gt;——Agent 以&quot;可信&quot;口吻诱导用户执行危险操作&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;异常 Agent&lt;/strong&gt;——Agent 出现非预期的自主行为&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;安全防护需要从三个层面着手：&lt;strong&gt;生成式 AI 安全&lt;/strong&gt;（提示词安全、内容过滤）、&lt;strong&gt;Agentic AI 安全&lt;/strong&gt;（工具调用审计、权限边界）、&lt;strong&gt;通用应用安全&lt;/strong&gt;（身份认证、传输加密）。分享还演示了如何使用 Amazon Bedrock Guardrails 实现上述安全策略。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;8. Kubernetes 上微调与部署小语言模型&lt;/h2&gt;
&lt;p&gt;本环节聚焦于如何利用 Agent 优化 K8s 运维，具体场景包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;安全告警处理&lt;/strong&gt;：Agent 自动分类告警严重等级，低优先级告警自动归档，高优先级告警生成初步分析报告&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;容器管理&lt;/strong&gt;：Agent 协助诊断容器异常、推荐资源配额调整方案&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;日志管理&lt;/strong&gt;：Agent 聚合跨 Pod 日志，自动识别异常模式并关联到最近的变更记录&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;小语言模型（SLM）在 K8s 运维场景中的优势在于低延迟和低资源消耗，适合作为 Agent 的&quot;本地大脑&quot;。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;9. 开发工具体验&lt;/h2&gt;
&lt;h3&gt;Agentic AI 代码秀&lt;/h3&gt;
&lt;p&gt;现场演示了使用 AWS 工具构建 Agent 的完整流程，从零开始创建一个可用的 Agent 仅需数分钟。演示侧重于展示 Bedrock AgentCore 的开发效率。&lt;/p&gt;
&lt;h3&gt;AgentCore 可视化编排&lt;/h3&gt;
&lt;p&gt;演示了在可视化画布上通过拖拽编排 Agent，类似于低代码平台的操作体验。这种可视化方式显著降低了构建 Agent 的门槛，让非开发人员也能参与到 Agent 的设计中。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;10. AI Agent 的认识升级与业务提效&lt;/h2&gt;
&lt;p&gt;本环节梳理了 Agent 的运行时工作流（注意这不是线性结构，而是&lt;strong&gt;树形结构&lt;/strong&gt;）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;用户输入 (Chatbox)
    │
    ▼
AgentCore Runtime（执行环境）
    │
    ▼
Customer Support Agent（主程序）
    │
    ├── AgentCore Memory —— 管理长期/短期记忆
    ├── AgentCore Observability —— 观察与记录决策过程
    ├── AgentCore Evaluation —— 对决策结果进行评估
    ├── AgentCore Gateway —— 调用 MCP 等外部工具
    ├── AgentCore Identity —— 身份鉴权
    └── AgentCore Policy —— 访问控制
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;树形结构意味着各个模块不是串行调用，而是根据场景并行或条件触发——更接近人类处理问题的实际方式。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;11. 滴滴出海 14 国：客服 Agent 实战&lt;/h2&gt;
&lt;p&gt;滴滴分享的客服 AI Agent 覆盖 14 个国家，按两个维度展开：&lt;/p&gt;
&lt;h3&gt;使用体验维度&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;响应速度&lt;/strong&gt;：客服场景下延迟不可接受，Agent 必须在毫秒级完成意图识别和回复生成&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;内容准确性&lt;/strong&gt;：回复必须基于真实的知识库内容，不可出现幻觉&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;服务质量维度&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;多维度打分&lt;/strong&gt;：从态度、用语、是否提供了合适的服务等多个角度对 Agent 回复进行自动评分&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;推理链&lt;/strong&gt;：Agent 需要展示完整的推理过程——为什么会给出这个建议，中间经过了哪些判断步骤&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可溯源&lt;/strong&gt;：每一个评分结果、每一条提示内容都要求能够追溯到源头依据&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;滴滴的方案还支持按业务线和国家分配不同的 Agent 实例，满足不同地区法规和业务习惯的差异。这种&quot;一国一策&quot;的架构对出海企业具有借鉴意义。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;12. Amazon DevOps Agent &amp;amp; Security Agent：出海安全合规加速器&lt;/h2&gt;
&lt;p&gt;安全合规是出海企业的必修课，而传统方式面临多重挑战：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;配置漂移&lt;/strong&gt;：合规状态随时间推移持续衰减，需要持续监控与修复&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;告警风暴&lt;/strong&gt;：海量安全告警掩盖了真正的威胁信号&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;手动流程&lt;/strong&gt;：截图、填表等人工环节耗费大量时间&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;测试难以规模化&lt;/strong&gt;：安全测试难以做到持续化、全覆盖&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;法规差异&lt;/strong&gt;：各国法律法规不同且持续更新，需要持续学习最新法规&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;审计周期长&lt;/strong&gt;：从准备到出报告的审计流程耗时久&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;该分享展示了如何利用 DevOps Agent 自动检测配置漂移并修复，利用 Security Agent 自动分类告警、生成合规报告，将安全合规从&quot;项目制&quot;转变为&quot;持续运营&quot;。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;13. Agentic GEO：让品牌被 AI 看见&lt;/h2&gt;
&lt;p&gt;这是一个新颖的话题——&lt;strong&gt;当用户越来越多地通过 AI Agent 获取信息时，品牌如何确保自己被 Agent 推荐&lt;/strong&gt;？&lt;/p&gt;
&lt;p&gt;关键策略包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;权威认证&lt;/strong&gt;：让品牌的官方信息获得可被 Agent 验证的权威背书&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;内容结构化&lt;/strong&gt;：品牌信息需要以 Agent 易于理解和提取的结构呈现&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;多渠道覆盖&lt;/strong&gt;：在多个平台和触点保持一致的品牌信息&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;多结果占位&lt;/strong&gt;：确保品牌信息覆盖不同维度的查询需求&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;本质上是 SEO 的 Agent 时代版本——从&quot;让搜索引擎找到你&quot;演进为&quot;让 AI Agent 推荐你&quot;。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;14. 结语与感受&lt;/h2&gt;
&lt;p&gt;两天峰会信息量极大，几点核心感受：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;人多。&lt;/strong&gt; 会场座无虚席，侧面印证了 AI Agent 在当前技术圈的热度——这已经不是一个&quot;要不要做&quot;的话题，而是&quot;怎么做好&quot;的话题。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;累。&lt;/strong&gt; 议程从早到晚几乎没有空隙，分享内容技术密度高，需要大量消化。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;收获。&lt;/strong&gt; 国内企业 AI Agent 落地已从概念验证进入大规模工程化阶段。共同挑战不再是&quot;Agent 能不能用&quot;，而是多 Agent 协作中的信息打通、安全合规的系统性保障、以及从&quot;提效工具&quot;到&quot;业务增长引擎&quot;的价值升级。这些问题本身，也正是下一阶段 Agent 工程化的核心命题。&lt;/p&gt;
</content:encoded></item><item><title>Loop Engineering：当 AI Agent 能自己干活，人类开发者该做什么</title><link>https://www.hehonglei.cn/posts/loop-engineering/</link><guid isPermaLink="true">https://www.hehonglei.cn/posts/loop-engineering/</guid><description>Loop Engineering 是 2026 年 AI 开发领域最火的新范式。本文深入解析其六大组件、四级演进脉络、典型工作流设计，以及三个你必须警惕的深坑——包括 Claude Code 负责人 Boris Cherny 和 Google Cloud AI 总监 Addy Osmani 的核心观点。</description><pubDate>Tue, 16 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;1. 引言&lt;/h2&gt;
&lt;p&gt;2026 年 6 月，AI 开发圈被一个词刷屏了：&lt;strong&gt;Loop Engineering&lt;/strong&gt;（循环工程）。&lt;/p&gt;
&lt;p&gt;引爆点是一连串来自行业核心人物的声音。&lt;strong&gt;Peter Steinberger&lt;/strong&gt;（OpenClaw 创始人）在 X 上发了一句话，获得超过 &lt;strong&gt;800 万次浏览&lt;/strong&gt;：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;你不该再亲自给编程 Agent 写提示词了。你应该设计 Loop，让 Loop 替你去写。&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Boris Cherny&lt;/strong&gt;（Anthropic Claude Code 负责人）紧接着表示：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;我已经不给 Claude 写提示词了。我有 Loop 在跑，它们自己决定该干什么。我的工作是写 Loop。&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;他透露到 2026 年，自己已经&lt;strong&gt;不再手写一行代码&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;随后，&lt;strong&gt;Addy Osmani&lt;/strong&gt;（Google Cloud AI 总监、前 Chrome 工程负责人）发表长文，系统性地阐述了 Loop Engineering 的完整框架。硅谷 AI 圈从此又多了一个带 &quot;Engineering&quot; 后缀的关键词。&lt;/p&gt;
&lt;p&gt;本文从概念起源、核心组件、实践模式、风险警示四个维度，把 Loop Engineering 讲清楚。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;2. 四个 Engineering 的演进脉络&lt;/h2&gt;
&lt;p&gt;要理解 Loop Engineering 为什么是&quot;下一站&quot;，需要先看清 AI 开发范式的演进路径：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;阶段&lt;/th&gt;
&lt;th&gt;时间&lt;/th&gt;
&lt;th&gt;核心问题&lt;/th&gt;
&lt;th&gt;核心能力&lt;/th&gt;
&lt;th&gt;类比&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Prompt Engineering&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2023&lt;/td&gt;
&lt;td&gt;怎么问 AI&lt;/td&gt;
&lt;td&gt;语言表达、任务拆解&lt;/td&gt;
&lt;td&gt;学会提问&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Context Engineering&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2024&lt;/td&gt;
&lt;td&gt;给 AI 看什么&lt;/td&gt;
&lt;td&gt;信息筛选、上下文组织&lt;/td&gt;
&lt;td&gt;学会备课&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Harness Engineering&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2025&lt;/td&gt;
&lt;td&gt;在哪里安全运行&lt;/td&gt;
&lt;td&gt;系统设计、规则制定&lt;/td&gt;
&lt;td&gt;学会搭台&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Loop Engineering&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2026&lt;/td&gt;
&lt;td&gt;怎么让它持续转&lt;/td&gt;
&lt;td&gt;目标定义、流程设计&lt;/td&gt;
&lt;td&gt;学会管理&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;这个演进有一个清晰的主线：&lt;strong&gt;人的角色在持续向上移动&lt;/strong&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Prompt Engineering 时代，人在&lt;strong&gt;手动操控&lt;/strong&gt;每一个步骤&lt;/li&gt;
&lt;li&gt;Context Engineering 时代，人开始思考&lt;strong&gt;信息架构&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Harness Engineering 时代，人开始设计&lt;strong&gt;约束系统&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Loop Engineering 时代，人只定义&lt;strong&gt;目标和规则&lt;/strong&gt;，系统自己跑&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Boris Cherny 的原话点出了本质：&lt;strong&gt;&quot;我的工作是写 Loop&quot;不是说工作变少了，而是说创造价值的杠杆点移动了。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;用一个类比：早期工厂老板亲自操作机器，后来设计流水线，再后来设计自动化管理系统。Loop Engineering 就是 AI 时代的&quot;设计流水线&quot;——你不是在拧螺丝，你在设计整条流水线。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;3. Loop Engineering 的六大组件&lt;/h2&gt;
&lt;p&gt;Addy Osmani 将 Loop Engineering 拆解为六个核心模块。这六个模块缺一不可，各自解决一类问题。&lt;/p&gt;
&lt;h3&gt;3.1 自动化调度（Automations）—— Loop 的&quot;心跳&quot;&lt;/h3&gt;
&lt;p&gt;Automations 负责让 Loop &lt;strong&gt;自己启动&lt;/strong&gt;，而不是等人来喊。它包括两类触发方式：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;触发类型&lt;/th&gt;
&lt;th&gt;示例&lt;/th&gt;
&lt;th&gt;Claude Code 对应&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;定时触发&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;每天早上 9 点扫描 Open Issues&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/loop&lt;/code&gt;、&lt;code&gt;cron&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;事件触发&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;CI 失败自动启动诊断 Loop&lt;/td&gt;
&lt;td&gt;Git hooks、GitHub Actions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;目标驱动&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;设定大目标，Loop 自动拆分子任务&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/goal&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;关键设计原则：**不要让&quot;人记得启动&quot;成为系统的前提。**一个好的 Loop 应该是自驱动的。&lt;/p&gt;
&lt;h3&gt;3.2 工作树（Worktrees）—— 隔离运行环境&lt;/h3&gt;
&lt;p&gt;当多个 Agent 并行工作时，它们不能共享同一个文件系统——会互相覆盖对方的修改。&lt;/p&gt;
&lt;p&gt;基于 Git 的 Worktree 机制解决了这个问题：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 每个子任务在独立的 Worktree 中运行
git worktree add ../fix-auth-bug main
cd ../fix-auth-bug
# Agent 在此环境中工作，互不干扰
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Worktree 的三大价值：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;并行安全&lt;/strong&gt;：10 个 Agent 同时修 Bug 不会冲突&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可回滚&lt;/strong&gt;：Agent 改坏了直接删 Worktree，不影响主干&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可审查&lt;/strong&gt;：每个 Worktree 一个分支，改动隔离、可独立 Review&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3.3 技能（Skills）—— 持久化项目知识&lt;/h3&gt;
&lt;p&gt;如果说 Context Engineering 解决的是&quot;单次会话给 Agent 看什么&quot;，Skills 解决的是**&quot;跨会话如何积累知识&quot;**。&lt;/p&gt;
&lt;p&gt;Skills 是存放在项目中的 Markdown 文件，Agent 每轮自动加载。它们包含：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.claude/
├── SKILL.md          # 总体项目规范
├── agents/
│   ├── reviewer.md   # 代码审查 Agent 的行为定义
│   └── fixer.md      # Bug 修复 Agent 的行为定义
└── skills/
    ├── coding-style.md   # 代码风格约定
    ├── architecture.md   # 系统架构约定
    └── pitfalls.md       # 踩过的坑
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;你踩过的每一个坑、总结的每一条规范，都会沉淀为 Skill，成为后续所有 Agent 的&quot;肌肉记忆&quot;。&lt;strong&gt;Skill 的质量决定了 Loop 产出的质量。&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;3.4 连接器（Connectors）—— 让 Agent 接入真实世界&lt;/h3&gt;
&lt;p&gt;基于 &lt;strong&gt;MCP（Model Context Protocol）&lt;/strong&gt;，Agent 可以连接外部工具：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Agent ←→ MCP Server ←→ 外部系统
                           ├── GitHub API（读 Issue、开 PR）
                           ├── Slack（发通知、接收指令）
                           ├── 数据库（查询数据、验证结果）
                           ├── CI/CD（触发构建、读取日志）
                           └── Linear / Jira（更新工单状态）
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;没有 Connectors，Agent 只是在&quot;沙箱里自言自语&quot;。有了 Connectors，它才能真正影响外部世界——开 PR、更新工单、通知团队。&lt;/p&gt;
&lt;h3&gt;3.5 子 Agent（Sub-agents）—— Maker/Checker 分离&lt;/h3&gt;
&lt;p&gt;这是 Loop Engineering 中最容易被低估但最重要的设计模式：&lt;strong&gt;不要让同一个 Agent 既写代码又审查代码。&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// 错误设计：一个 Agent 自产自审
const result = await agent(&quot;修复这个 Bug，然后审查自己的修复&quot;);

// 正确设计：Maker 和 Checker 分离
const fix = await agent(&quot;修复这个 Bug&quot;, { role: &quot;maker&quot; });
const review = await agent(`审查这个修复：${fix.diff}`, { role: &quot;checker&quot; });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;为什么要分离？&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;同一 Agent 自审&lt;/th&gt;
&lt;th&gt;Maker/Checker 分离&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;倾向于&quot;放自己一马&quot;&lt;/td&gt;
&lt;td&gt;独立视角，找出盲区&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;容易忽略安全问题&lt;/td&gt;
&lt;td&gt;Checker 被明确告知&quot;你的任务是找问题&quot;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;缺乏对抗性验证&lt;/td&gt;
&lt;td&gt;可以设计为&quot;默认驳回，除非证明正确&quot;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Checker 应该被提示为&quot;默认不信任，除非证明正确&quot;，而不是&quot;默认通过，除非明显有问题&quot;。&lt;/strong&gt; 这个提示词的微小差别，决定了验证的有效性。&lt;/p&gt;
&lt;h3&gt;3.6 记忆 / 状态（Memory）—— 超越上下文窗口&lt;/h3&gt;
&lt;p&gt;Agent 的上下文窗口（Context Window）是有限的，但一个持续运行的 Loop 需要&lt;strong&gt;记住已经做了什么、还剩什么没做&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;Memory 层的实现可以很简单：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# state.md
## 当前状态
- 最后运行: 2026-06-16 09:00 UTC
- 进行中: fix-login-timeout（PR #42 等待 Review）

## 已完成
- [x] 修复 API 超时重试逻辑 — #41 已合并
- [x] 更新依赖版本 — #40 已合并

## 待处理
- [ ] 排查 CI 偶发失败 — 已分配 Worktree ci-flaky-test
- [ ] 升级 Node.js 到 v26 — 等待 LTS
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Osmani 强调：&lt;strong&gt;&quot;每个成功的 Loop 背后，都有一套默默工作的状态文件。&quot;&lt;/strong&gt; 状态文件是 Loop 的&quot;短期记忆&quot;，Skills 是 Loop 的&quot;长期记忆&quot;。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;4. 完整 Loop 示例：一条真实的工作流&lt;/h2&gt;
&lt;p&gt;把六个组件串起来，一条典型的 CI 自动修复 Loop 长这样：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;08:00  定时任务自动触发
08:01  分诊 Agent 扫描：
         - 昨夜 CI 有 3 个失败
         - GitHub 上有 2 个新 Open Issue
         - 昨日合并的 PR 有 1 个回归
08:05  写入状态文件 state.md
08:06  对每个值得处理的问题开独立 Worktree
08:07  Worktree A — Maker Agent 起草修复方案
       Worktree B — Maker Agent 起草修复方案
       Worktree C — Maker Agent 起草修复方案
08:15  三个修复方案均提交到各自分支
08:16  Checker Agent 对照 SKILL.md 规范审查三个方案
08:25  方案 A 通过 → 自动开 PR
       方案 B 被驳回 → 退回 Maker Agent 重写
       方案 C 通过 → 自动开 PR，更新对应 Issue
08:30  处理不了的标记为 need-human-triage
08:31  更新状态文件，记录进度
08:32  发送 Slack 摘要通知团队

第二天从状态文件继续。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;全程开发者一个字都没有敲。&lt;/strong&gt; 你的工作是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;确保这条 Loop 的规则是合理的&lt;/li&gt;
&lt;li&gt;审查 Checker Agent 通过但你觉得可疑的 PR&lt;/li&gt;
&lt;li&gt;不断优化 Skills 中的项目规范&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h2&gt;5. Loop 成熟度模型&lt;/h2&gt;
&lt;p&gt;Osmani 在文章中提出了一个六级成熟度模型，帮助团队评估自己处于什么阶段：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;等级&lt;/th&gt;
&lt;th&gt;名称&lt;/th&gt;
&lt;th&gt;特征&lt;/th&gt;
&lt;th&gt;人的参与度&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;L0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;人工逐轮提示&lt;/td&gt;
&lt;td&gt;每次手动粘贴 Prompt&lt;/td&gt;
&lt;td&gt;100%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;L1&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;脚本化重试&lt;/td&gt;
&lt;td&gt;用脚本批量调用 Agent&lt;/td&gt;
&lt;td&gt;90%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;L2&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;定时 Loop&lt;/td&gt;
&lt;td&gt;定时运行，只报告不自动修改&lt;/td&gt;
&lt;td&gt;70%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;L3&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;有状态 Loop&lt;/td&gt;
&lt;td&gt;进度跨会话持久化&lt;/td&gt;
&lt;td&gt;40%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;L4&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;自验证 Loop&lt;/td&gt;
&lt;td&gt;有确定性检查，Agent 能判断自己是否做对了&lt;/td&gt;
&lt;td&gt;25%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;L5&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;多 Agent 协作&lt;/td&gt;
&lt;td&gt;Maker/Checker 分离，专门化 Agent 分工&lt;/td&gt;
&lt;td&gt;15%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;L6&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;生产级监督&lt;/td&gt;
&lt;td&gt;有安全护栏、自动回滚、异常升级机制&lt;/td&gt;
&lt;td&gt;10%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;大多数团队目前处于 &lt;strong&gt;L1-L2&lt;/strong&gt; 阶段。L4 以上的 Loop 已经具备了替代初-中级开发者的能力——这也是为什么 JetBrains 2026 Q2 调研显示&lt;strong&gt;全球初级开发岗位需求同比暴跌 40%&lt;/strong&gt;。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;6. 三个你必须警惕的深坑&lt;/h2&gt;
&lt;p&gt;Loop Engineering 不是银弹。Osmani 和 Cherny 都明确警示了三个核心风险。&lt;/p&gt;
&lt;h3&gt;6.1 验证仍是人的责任&lt;/h3&gt;
&lt;p&gt;Loop 可以自动完成&quot;声明完成&quot;，但&lt;strong&gt;不能自动完成&quot;证明正确&quot;&lt;/strong&gt;。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;完成了&quot;是一份声明。&quot;做对了&quot;是一个事实。声明不等于事实。——Addy Osmani&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Checker Agent 可以减少遗漏，但不能替代人的判断。安全变更、架构决策、用户体验问题——这些需要人的确认。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;原则&lt;/strong&gt;：Loop 可以自动处理你&lt;strong&gt;充分理解&lt;/strong&gt;的问题；面对你不理解的问题，Loop 只是帮你把问题变得更清晰，决策仍然在你。&lt;/p&gt;
&lt;h3&gt;6.2 理解债务（Comprehension Debt）&lt;/h3&gt;
&lt;p&gt;这是 Osmani 提出的一个关键概念，比技术债务更隐蔽也更危险。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Loop 生成代码的速度
         &amp;gt;
你理解代码的速度
         =
理解债务在累积
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;当 Loop 每天产出数万行代码，而你的理解速度是恒定的，&lt;strong&gt;理解债务会以指数级增长&lt;/strong&gt;。总有一天，你会面对一个自己完全不知道如何运作的系统。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;缓解策略&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;设置 Loop 的&quot;产出速率上限&quot;——不是让它跑得越快越好&lt;/li&gt;
&lt;li&gt;定期停下来，人工 Review 近期所有自动变更&lt;/li&gt;
&lt;li&gt;对核心模块禁止 Loop 自动修改，只允许人工操作&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;6.3 认知投降（Cognitive Surrender）&lt;/h3&gt;
&lt;p&gt;这是最深刻的风险——&lt;strong&gt;当系统能自己运转，人会本能地停止思考&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;Cherny 的原话：&lt;em&gt;&quot;最舒服的姿势恰恰是最危险的。当你不再理解 Loop 在做什么但 Pipeline 还能跑的时候，你已经把工程师的核心能力交出去了。&quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;对抗策略&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;定期&quot;离线日&quot;&lt;/strong&gt;：每周有一天不用 Agent，纯手写，保持手感&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;自问测试&lt;/strong&gt;：如果这个 Loop 明天消失了，你还能不能自己做完它做的事？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;保持&quot;以工程师的身份&quot;搭建 Loop&lt;/strong&gt;：你是在设计系统，不是在按&quot;开始键&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;7. 一句话总结不同角色如何面对 Loop Engineering&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;角色&lt;/th&gt;
&lt;th&gt;你应该做什么&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;初级开发者&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;学会读懂 Loop 的产出，专注于理解而非堆砌代码&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;中级开发者&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;把你的经验沉淀为 Skills，成为 Loop 的&quot;教练&quot;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;高级 / 架构师&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;设计 Loop 的约束边界和验证规则，定义&quot;完成&quot;的标准&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;技术管理者&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;重新思考团队结构和绩效衡量方式，代码量不再是好指标&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Addy Osmani 的最后一段话是最好的收尾：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&quot;搭好你的 Loop，但要以一个打算继续当工程师的人去搭建它——不要做只会点&apos;开始键&apos;的人。&quot;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h2&gt;8. 参考资料&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://addyosmani.com/blog/loop-engineering/&quot;&gt;Loop Engineering — Addy Osmani Blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://techorange.com/2026/06/10/loop-engineering-ai-agent/&quot;&gt;Loop Engineering 崛起：当 AI Agent 能自己工作，Google 工程师点人类三大职责&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.163.com/dy/article/KVG2KFMB051180F7.html&quot;&gt;一文读懂 Loop Engineering：6 大板块和三个大坑&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/cobusgreyling/loop-engineering&quot;&gt;cobusgreyling/loop-engineering — GitHub 实用参考和模式&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/ChaoYue0307/awesome-loop-engineering&quot;&gt;ChaoYue0307/awesome-loop-engineering — 精选资源合集&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.aliyun.com/article/1740864&quot;&gt;AI Agent 的 4 个工程关键词：Prompt、Context、Loop、Harness&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://hub.baai.ac.cn/view/55505&quot;&gt;Harness 之后，硅谷 AI 圈又来新词了：Loop Engineering&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>WWDC26 上的 Web 技术革命：Safari 27 带来了什么</title><link>https://www.hehonglei.cn/posts/wwdc26-safari27-web-technology/</link><guid isPermaLink="true">https://www.hehonglei.cn/posts/wwdc26-safari27-web-technology/</guid><description>WWDC26 WebKit 专场发布了 Safari 27 的五大重磅特性：CSS Grid Lanes 原生瀑布流、完全自定义的 &lt;select&gt; 元素、&lt;model&gt; 3D 模型嵌入、visionOS 沉浸式网站环境，以及跨浏览器 Web Extensions 打包。本文逐一解析每个特性的用法与设计意图。</description><pubDate>Tue, 16 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;1. 引言&lt;/h2&gt;
&lt;p&gt;2026 年 6 月，Apple 在 WWDC26 上由 WebKit 团队带来了 Safari 27 的一系列 Web 平台新特性。相比往年 Safari 更新的&quot;挤牙膏&quot;节奏，今年的 Web 技术专场堪称一场&lt;strong&gt;小爆发&lt;/strong&gt;——从 CSS 布局到表单控件、从 3D 内容嵌入到空间计算 Web 体验，每一项都直击前端开发者多年来的痛点。&lt;/p&gt;
&lt;p&gt;本文逐项解析五大核心特性，并附上代码示例，帮助你快速理解这些新能力将如何改变我们的开发方式。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;2. 五大核心特性&lt;/h2&gt;
&lt;h3&gt;2.1 CSS Grid Lanes — 原生瀑布流布局&lt;/h3&gt;
&lt;p&gt;这是本次 WWDC 最受前端开发者关注的 CSS 新特性。&lt;strong&gt;Grid Lanes&lt;/strong&gt; 让 Web 平台原生支持了 Pinterest 式的瀑布流/砖石（Masonry）布局——不需要任何 JavaScript，几行 CSS 即可实现。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;传统方案的痛点&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;在此之前，实现瀑布流布局只有两条路：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方案&lt;/th&gt;
&lt;th&gt;问题&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;JavaScript 计算&lt;/td&gt;
&lt;td&gt;性能差、窗口 resize 卡顿、需要 ResizeObserver + 绝对定位&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CSS Grid + &lt;code&gt;grid-auto-rows: masonry&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;自 2020 年起一直是实验性提案，从未进入任何浏览器&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Grid Lanes 的解决方案&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Grid Lanes 引入了 &lt;code&gt;grid-template-columns&lt;/code&gt; 的新语法 &lt;code&gt;lanes()&lt;/code&gt;，让元素在列间自然流动：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.masonry {
  display: grid;
  grid-template-columns: lanes(300px, 300px, 300px);
  gap: 16px;
}

/* 配合 auto-fill 实现响应式 */
.masonry-responsive {
  display: grid;
  grid-template-columns: lanes(auto-fill, minmax(280px, 1fr));
  gap: 16px;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;与之前被废弃的 &lt;code&gt;masonry&lt;/code&gt; 关键词不同，Grid Lanes 的设计更通用——它不仅支持瀑布流，还支持&lt;strong&gt;任何自定义的格子排列算法&lt;/strong&gt;，是一个远比&quot;砖石布局&quot;更大的概念。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;核心特点&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;纯 CSS 实现&lt;/strong&gt;，零 JavaScript，浏览器原生渲染优化&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;自适应&lt;/strong&gt;，配合 &lt;code&gt;auto-fill&lt;/code&gt;、&lt;code&gt;minmax()&lt;/code&gt; 即可响应式&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;排序可控&lt;/strong&gt;，支持 &lt;code&gt;grid-lane-order: column | row | shortest-column&lt;/code&gt; 等排列策略&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在 WebKit 的演示中，一个 200 张图片的瀑布流页面，从 JS 方案切换到 Grid Lanes 后，布局计算耗时从 &lt;strong&gt;~120ms 降至 ~4ms&lt;/strong&gt;。&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;2.2 完全自定义的 &lt;code&gt;&amp;lt;select&amp;gt;&lt;/code&gt; 元素&lt;/h3&gt;
&lt;p&gt;前端开发者与 &lt;code&gt;&amp;lt;select&amp;gt;&lt;/code&gt; 元素的战争已经持续了二十多年。Safari 27 终于给出了原生解决方案：&lt;code&gt;appearance: base-select&lt;/code&gt; + 一套全新的伪元素体系。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;新伪元素体系&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/* 启用新的可样式化 select */
select {
  appearance: base-select;
}

/* 下拉触发器（替代浏览器默认箭头） */
select::picker(select) {
  border-radius: 12px;
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.12);
  backdrop-filter: blur(20px);
}

/* 选项列表 */
select::picker(select) option {
  padding: 12px 16px;
  font-size: 15px;
  display: flex;
  align-items: center;
  gap: 8px;
}

/* 选中标记 */
select::checkmark {
  color: var(--accent-color);
  margin-left: auto;
}

/* 选中态 */
select::picker(select) option:checked {
  background: var(--accent-color-light);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;关键能力&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;伪元素 / 选择器&lt;/th&gt;
&lt;th&gt;作用&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;::picker()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;样式化下拉面板（背景、圆角、阴影、模糊）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;::picker-icon&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;自定义下拉箭头图标&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;::checkmark&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;自定义选中标记&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;option:checked&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;当前选中项的样式&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;option:hover&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;hover 状态&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;::picker(select)&lt;/code&gt; 内的 flex/grid&lt;/td&gt;
&lt;td&gt;选项布局完全自由&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;这意味着终于可以抛弃那些动辄几十 KB 的自定义 select 库（如 Choices.js、Select2、react-select 等），用纯原生 CSS 实现设计稿级别的下拉选择器。&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;2.3 &lt;code&gt;&amp;lt;model&amp;gt;&lt;/code&gt; 元素 — 网页内嵌 3D 模型&lt;/h3&gt;
&lt;p&gt;Safari 27 新增了 &lt;code&gt;&amp;lt;model&amp;gt;&lt;/code&gt; HTML 元素，允许在网页中直接嵌入交互式 3D 模型，无需任何 JavaScript 库或 WebGL 代码。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;基本用法&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;model
  src=&quot;airpods.usdz&quot;
  width=&quot;600&quot;
  height=&quot;400&quot;
  camera-controls
  auto-rotate
  ar
&amp;gt;
  &amp;lt;p&amp;gt;您的浏览器不支持 3D 模型显示，请升级 Safari 27&amp;lt;/p&amp;gt;
&amp;lt;/model&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;支持的功能&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;属性 / 能力&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;src&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;模型文件 URL（支持 USDZ、glTF 2.0、OBJ）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;camera-controls&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;用户可旋转/缩放/平移视角&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;auto-rotate&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;自动缓慢旋转展示&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ar&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;点击可启动 AR 查看（iOS/iPadOS 上的 Quick Look）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;environment&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;环境光照预设（&lt;code&gt;auto&lt;/code&gt; / &lt;code&gt;studio&lt;/code&gt; / &lt;code&gt;outdoor&lt;/code&gt;）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;poster&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;模型加载前的占位图 URL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;loading&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;懒加载（&lt;code&gt;lazy&lt;/code&gt; / &lt;code&gt;eager&lt;/code&gt;）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;JavaScript API&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;model&amp;gt;&lt;/code&gt; 元素暴露了完整的 JavaScript 控制接口：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const model = document.querySelector(&apos;model&apos;);

// 播放内置动画
model.playAnimation(&apos;idle&apos;);

// 监听加载状态
model.addEventListener(&apos;load&apos;, () =&amp;gt; {
  console.log(&apos;模型已加载，三角形数量：&apos;, model.triangleCount);
});

// 编程式控制相机
model.camera.orbit(0, 45, 2);  // theta, phi, radius
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;model&amp;gt;&lt;/code&gt; 元素最早在 iOS 上的 Quick Look 中预览 USDZ 文件时就已埋下伏笔，现在正式进入 Web 标准。对于电商、教育、产品展示类网站，这是一个重要工具。&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;2.4 visionOS 沉浸式网站环境&lt;/h3&gt;
&lt;p&gt;这是本次 WWDC 最具未来感的一项能力。Safari 27 在 visionOS 27 上支持&lt;strong&gt;空间 Web 体验&lt;/strong&gt;：网站可以声明自己是&quot;沉浸式&quot;的，从而在 Apple Vision Pro 上以空间化的方式呈现。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;声明沉浸式体验&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;meta name=&quot;apple-immersive&quot; content=&quot;full&quot;&amp;gt;
&amp;lt;meta name=&quot;apple-immersive-environment&quot; content=&quot;starry-night&quot;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;浏览器会将页面渲染为漂浮在用户空间中的面板，同时支持 &lt;strong&gt;WebXR&lt;/strong&gt; 标准的空间交互：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// 检测沉浸式 Web 支持
if (&apos;xr&apos; in navigator) {
  const session = await navigator.xr.requestSession(&apos;immersive-vr&apos;, {
    requiredFeatures: [&apos;hand-tracking&apos;],
  });

  // 使用 WebXR API 创建空间化的 UI 面板
  const layer = new XRWebGLLayer(session, gl);
  session.updateRenderState({ baseLayer: layer });
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;WebKit 团队强调，这不是创造一套新的&quot;visionOS-only&quot;标准，而是在现有 &lt;strong&gt;WebXR Device API&lt;/strong&gt; 标准上的扩展实现。这意味着同一个 WebXR 页面也可以在 Meta Quest、Pico 等设备上运行。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;实际应用场景&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;产品展示&lt;/strong&gt;：家居品牌让用户在空间中查看家具&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据可视化&lt;/strong&gt;：3D 图表和数据仪表盘&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;在线教育&lt;/strong&gt;：解剖模型、分子结构等立体教学&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;艺术展览&lt;/strong&gt;：空间化的 Web 艺术体验&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;2.5 跨浏览器 Web Extensions 打包&lt;/h3&gt;
&lt;p&gt;Safari 27 大幅简化了 Safari 扩展的开发和分发流程。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;主要变化&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;之前&lt;/th&gt;
&lt;th&gt;之后（Safari 27）&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;必须通过 Xcode 项目打包&lt;/td&gt;
&lt;td&gt;直接提交扩展文件包，无需 Xcode&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;只能在 Mac 上构建和提交&lt;/td&gt;
&lt;td&gt;任意平台均可构建和提交（通过 App Store Connect API）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Safari 专用 API 差异大&lt;/td&gt;
&lt;td&gt;更接近 Chrome/Firefox 扩展 API，遵循 W3C WebExtensions 社区组规范&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;无法跨浏览器复用&lt;/td&gt;
&lt;td&gt;一套代码 → Chrome + Firefox + Safari，零修改或极小修改&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;新的打包方式&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 无需 Xcode，直接用命令行工具打包
safari-web-extension build ./my-extension

# 通过 App Store Connect API 提交
xcrun altool --upload-app \
  -f my-extension.zip \
  -t osx \
  --apiKey YOUR_KEY \
  --apiIssuer YOUR_ISSUER
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这对独立开发者和开源项目尤其友好——以前为 Safari 维护扩展需要一台 Mac 和一个 Apple Developer 账号，现在通过 CI/CD 就能完成提交。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;3. 这些特性的意义&lt;/h2&gt;
&lt;p&gt;如果你把五大特性放在一起看，会发现它们指向同一个方向：&lt;strong&gt;Web 平台正在接管越来越多原本属于&quot;原生&quot;的领域&lt;/strong&gt;。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;取代了什么&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CSS Grid Lanes&lt;/td&gt;
&lt;td&gt;Masonry.js 及其他 JS 布局库&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;自定义 &lt;code&gt;&amp;lt;select&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;react-select、Choices.js、Select2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;model&amp;gt;&lt;/code&gt; 元素&lt;/td&gt;
&lt;td&gt;Three.js / model-viewer 的基础场景&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;沉浸式 Web&lt;/td&gt;
&lt;td&gt;原生 visionOS / iOS App 的独占体验&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Web Extensions 打包&lt;/td&gt;
&lt;td&gt;Xcode + Mac 的构建垄断&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;这是一种稳步推进的标准化策略：先让某个需求在社区中通过 JS 库解决（验证需求），再通过标准化 API 将其内建到平台中（提供原生性能和安全保障），让 JS 方案降级为降级兼容（polyfill）。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;4. 什么时候能用&lt;/h2&gt;
&lt;p&gt;WebKit 在 WWDC 现场的回应：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;时机&lt;/th&gt;
&lt;th&gt;可用性&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;现在&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Safari Technology Preview 中可测试所有新特性&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;2026 年 9 月&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Safari 27 随 iOS 27 / macOS 27 正式发布&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;跨浏览器&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Grid Lanes 规范已进入 W3C CSS WG 的 ED 阶段；&lt;code&gt;&amp;lt;select&amp;gt;&lt;/code&gt; 样式化在 Open UI CG 中有跨浏览器共识；&lt;code&gt;&amp;lt;model&amp;gt;&lt;/code&gt; 在 Immersive Web CG 中推进&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;需要注意的是，&lt;strong&gt;CSS Grid Lanes&lt;/strong&gt; 和&lt;strong&gt;自定义 &lt;code&gt;&amp;lt;select&amp;gt;&lt;/code&gt;&lt;/strong&gt; 是最有可能快速跨浏览器跟进的两个特性——Chrome 和 Firefox 的工程师已经在相关标准讨论中表达了支持意向。&lt;code&gt;&amp;lt;model&amp;gt;&lt;/code&gt; 元素目前在 Safari 独占，但 Google 在 Android 生态中有类似需求（Scene Viewer），标准化前景可期。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;5. 参考资料&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://webkit.org/blog/17974/web-technology-sessions-at-wwdc26/&quot;&gt;Web Technology Sessions at WWDC26 — WebKit Blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://drafts.csswg.org/css-grid-3/&quot;&gt;CSS Grid Lanes Specification — W3C Editor&apos;s Draft&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://open-ui.org/components/selectlist/&quot;&gt;Customizable &lt;code&gt;&amp;lt;select&amp;gt;&lt;/code&gt; — Open UI Community Group&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.w3.org/TR/webxr/&quot;&gt;WebXR Device API — W3C&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.apple.com/documentation/safariservices/safari_web_extensions&quot;&gt;Safari Web Extensions — Apple Developer Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>npm v12 默认禁止生命周期脚本执行：一次影响所有开发者的安全变革</title><link>https://www.hehonglei.cn/posts/npm-v12-lifecycle-scripts/</link><guid isPermaLink="true">https://www.hehonglei.cn/posts/npm-v12-lifecycle-scripts/</guid><description>npm v12 将于 2026 年 7 月发布，届时将默认禁止 install 生命周期脚本、Git 依赖和远程 URL 依赖的执行。本文详解三大破坏性变更的背景、影响范围及迁移方案，帮助团队在截止日期前完成适配。</description><pubDate>Mon, 15 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;1. 引言&lt;/h2&gt;
&lt;p&gt;2026 年 7 月，npm 将发布 &lt;strong&gt;v12 大版本&lt;/strong&gt;，带来 npm 历史上最激进的安全策略变更——&lt;strong&gt;默认禁止生命周期脚本执行&lt;/strong&gt;。这意味着任何依赖包的 &lt;code&gt;preinstall&lt;/code&gt;、&lt;code&gt;install&lt;/code&gt;、&lt;code&gt;postinstall&lt;/code&gt; 脚本将不再默认运行，Git 依赖和远程 URL 依赖也将被默认拦截。&lt;/p&gt;
&lt;p&gt;这是继 pnpm v10（2025 年 1 月）率先引入类似机制后，npm 作为最后一个主流 JavaScript 包管理器跟进这一安全实践。GitHub 在官方 Changelog 中明确指出：&lt;strong&gt;2025 年 npm 注册表上发布了约 455,000 个恶意包&lt;/strong&gt;，而实际只有约 2% 的 npm 包真正需要执行安装脚本——但 100% 的包都有能力在安装时运行任意代码。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;2. 三大破坏性变更&lt;/h2&gt;
&lt;p&gt;npm v12 引入了三项默认值变更，每一项都直接切断一条供应链攻击路径。&lt;/p&gt;
&lt;h3&gt;2.1 &lt;code&gt;allowScripts&lt;/code&gt; 默认关闭&lt;/h3&gt;
&lt;p&gt;这是影响最广的一项变更。从 npm v12 开始，以下生命周期脚本&lt;strong&gt;默认不再执行&lt;/strong&gt;：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;脚本&lt;/th&gt;
&lt;th&gt;触发时机&lt;/th&gt;
&lt;th&gt;受影响范围&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;preinstall&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;包安装前&lt;/td&gt;
&lt;td&gt;所有依赖&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;install&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;包安装时&lt;/td&gt;
&lt;td&gt;所有依赖&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;postinstall&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;包安装后&lt;/td&gt;
&lt;td&gt;所有依赖&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;prepare&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;git/file/link 依赖安装时&lt;/td&gt;
&lt;td&gt;git/file/link 依赖&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;值得注意的是，&lt;strong&gt;隐式的 &lt;code&gt;node-gyp&lt;/code&gt; 重建也会被阻止&lt;/strong&gt;——即使某个包没有显式声明 install 脚本，但只要包含 &lt;code&gt;binding.gyp&lt;/code&gt; 文件，安装时同样会触发原生模块编译，这在 v12 下也需要显式授权。&lt;/p&gt;
&lt;h3&gt;2.2 &lt;code&gt;--allow-git&lt;/code&gt; 默认值为 &lt;code&gt;none&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Git 依赖（&lt;code&gt;&quot;foo&quot;: &quot;git+https://github.com/user/repo.git&quot;&lt;/code&gt;）默认不再解析。这项变更关闭了一个关键的代码执行路径：&lt;strong&gt;Git 依赖的 &lt;code&gt;.npmrc&lt;/code&gt; 文件可以覆盖 Git 可执行文件路径&lt;/strong&gt;，攻击者可以借此绕过 &lt;code&gt;--ignore-scripts&lt;/code&gt; 的限制。&lt;/p&gt;
&lt;h3&gt;2.3 &lt;code&gt;--allow-remote&lt;/code&gt; 默认值为 &lt;code&gt;none&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;远程 URL 依赖（HTTPS tarball 等）同样默认不再解析，进一步缩小了未经审查的代码进入依赖树的窗口。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;3. 为什么必须这样做&lt;/h2&gt;
&lt;h3&gt;3.1 触目惊心的攻击数据&lt;/h3&gt;
&lt;p&gt;npm 生态在过去一年经历了前所未有的供应链攻击浪潮：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;事件&lt;/th&gt;
&lt;th&gt;时间&lt;/th&gt;
&lt;th&gt;影响&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Miasma 蠕虫&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2026 年 6 月&lt;/td&gt;
&lt;td&gt;利用 install 脚本自我传播的恶意软件&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Axios 投毒事件&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2026 年 3 月&lt;/td&gt;
&lt;td&gt;流行 HTTP 库被植入恶意代码&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;18 个包遭劫持&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2025 年 9 月&lt;/td&gt;
&lt;td&gt;包括 &lt;code&gt;debug&lt;/code&gt;、&lt;code&gt;chalk&lt;/code&gt; 在内的核心工具包被接管&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;全年恶意包&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2025 全年&lt;/td&gt;
&lt;td&gt;约 &lt;strong&gt;455,000&lt;/strong&gt; 个恶意包发布到 npm 注册表&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;3.2 不对称的信任模型&lt;/h3&gt;
&lt;p&gt;传统的 npm 安装模型存在根本性的信任不对称：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;只有 2% 的包&lt;/strong&gt;真正需要运行安装脚本（如原生模块编译、平台二进制下载）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;但 100% 的包&lt;/strong&gt;都有能力在安装时执行任意代码&lt;/li&gt;
&lt;li&gt;一个深度嵌套的传递依赖的 install 脚本，足以攻破整个系统&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这种&quot;默认信任一切&quot;的模型在当前的威胁环境下已经不可持续。&lt;/p&gt;
&lt;h3&gt;3.3 pnpm 已经验证了这条路&lt;/h3&gt;
&lt;p&gt;pnpm v10 在 2025 年 1 月率先实现了&lt;strong&gt;默认阻止生命周期脚本 + 显式许可名单&lt;/strong&gt;的安全模型。一年多的实践证明：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;绝大多数项目只需批准极少数的包（如 &lt;code&gt;esbuild&lt;/code&gt;、&lt;code&gt;sharp&lt;/code&gt;、&lt;code&gt;node-gyp&lt;/code&gt; 等需要原生编译的包）&lt;/li&gt;
&lt;li&gt;CI/CD 流程可以通过 &lt;code&gt;package.json&lt;/code&gt; 中的许可名单实现自动化&lt;/li&gt;
&lt;li&gt;开发者体验的影响远小于预期，安全收益巨大&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;npm v12 的变更本质上是在 npm 生态中全面推广这一已验证的安全模型。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;4. 迁移方案&lt;/h2&gt;
&lt;h3&gt;4.1 立即行动：升级到 npm 11.16.0+&lt;/h3&gt;
&lt;p&gt;npm 11.16.0（2026 年 6 月发布）已经包含了 v12 所有变更的&lt;strong&gt;预警机制&lt;/strong&gt;。升级后运行 &lt;code&gt;npm install&lt;/code&gt;，你会看到 v12 将阻止哪些脚本的警告信息，而不是直接在 7 月被硬阻断。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 升级到最新 npm 11
npm install -g npm@11

# 在项目中运行安装，观察警告
npm install
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.2 审查并建立许可名单&lt;/h3&gt;
&lt;p&gt;npm 11 提供了全新的审批工作流：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 查看所有有待审批安装脚本的包
npm approve-scripts --allow-scripts-pending

# 批准你信任的包（写入 package.json）
npm approve-scripts esbuild
npm approve-scripts sharp
npm approve-scripts node-gyp

# 拒绝不需要的包
npm deny-scripts some-suspicious-package
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.3 提交许可名单&lt;/h3&gt;
&lt;p&gt;审批结果会写入 &lt;code&gt;package.json&lt;/code&gt;，&lt;strong&gt;这是一个需要版本控制的团队决策&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;name&quot;: &quot;my-project&quot;,
  &quot;dependencies&quot;: {
    &quot;esbuild&quot;: &quot;^0.27.0&quot;,
    &quot;sharp&quot;: &quot;^0.34.0&quot;
  },
  &quot;allowScripts&quot;: {
    &quot;esbuild&quot;: true,
    &quot;sharp&quot;: true
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;许可名单的优势在于：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;可审查&lt;/strong&gt;：每次 PR 都能看到哪些包被授予了安装脚本权限&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可追溯&lt;/strong&gt;：Git 历史记录了每个信任决策的时间点和决策人&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可自动化&lt;/strong&gt;：CI/CD 直接读取 &lt;code&gt;package.json&lt;/code&gt;，无需额外配置&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4.4 处理 Git 依赖和远程依赖&lt;/h3&gt;
&lt;p&gt;如果你的项目依赖了 Git 仓库或远程 URL：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 在 .npmrc 或命令行中显式授权
npm install --allow-git=all          # 允许所有 Git 依赖
npm install --allow-git=foo/bar      # 只允许特定仓库
npm install --allow-remote=all       # 允许所有远程 URL 依赖
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;建议尽将 Git/远程依赖迁移到 npm 注册表的正式发布包，从根本上消除风险。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;5. 对 CI/CD 的影响&lt;/h2&gt;
&lt;h3&gt;5.1 Docker 镜像&lt;/h3&gt;
&lt;p&gt;如果你的 Dockerfile 中有 &lt;code&gt;npm install -g&lt;/code&gt; 全局安装，需要确认这些包是否包含安装脚本：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# npm v12 的 Docker 镜像（node:24+ 将内置 npm v12）
FROM node:24

# 需要显式审批全局包的脚本
RUN npm approve-scripts -g esbuild
RUN npm install -g esbuild
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.2 GitHub Actions / 其他 CI 环境&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# .github/workflows/ci.yml
- name: Install dependencies
  run: |
    # package.json 中的 allowScripts 会被自动读取
    npm install
    # 如果需要额外授权（不推荐），使用：
    # npm install --allow-scripts=all
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;推荐的做法是&lt;strong&gt;将 &lt;code&gt;allowScripts&lt;/code&gt; 写入 &lt;code&gt;package.json&lt;/code&gt; 并提交&lt;/strong&gt;，这样 CI 环境无需任何额外配置。&lt;/p&gt;
&lt;h3&gt;5.3 应急回退（不推荐）&lt;/h3&gt;
&lt;p&gt;如果项目暂时无法完成迁移，可以通过以下配置恢复到旧行为：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 全局恢复旧行为（高风险，不推荐）
npm install --allow-scripts=all --allow-git=all --allow-remote=all
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;但强烈建议这只是应急手段——&lt;strong&gt;攻击者正是依赖开发者长期使用这类&quot;全开&quot;配置。&lt;/strong&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;6. 变更不覆盖的场景&lt;/h2&gt;
&lt;p&gt;这项安全机制并非银弹，以下风险依然存在：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;运行时恶意代码&lt;/strong&gt;：安装脚本只是攻击入口之一，包在运行时执行的函数不受影响&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;维护者账号泄露&lt;/strong&gt;：攻击者获取维护者权限后直接修改包源码，不需要 install 脚本&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;拼写欺骗（Typosquatting）&lt;/strong&gt;：恶意包伪装成流行包名称，诱导手动安装&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;社会工程风险&lt;/strong&gt;：&lt;code&gt;npm approve-scripts --all&lt;/code&gt; 一键批准所有脚本，让安全机制形同虚设&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;7. 时间线与行动建议&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;时间&lt;/th&gt;
&lt;th&gt;事件&lt;/th&gt;
&lt;th&gt;行动&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;现在&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;npm 11.16.0 已发布&lt;/td&gt;
&lt;td&gt;升级到 npm@11，开始审查项目&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;现在 ~ 7 月&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;缓冲期&lt;/td&gt;
&lt;td&gt;建立许可名单，提交到 &lt;code&gt;package.json&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;2026 年 7 月&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;npm v12 正式发布&lt;/td&gt;
&lt;td&gt;确保所有 CI/CD 已适配&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;v12 之后&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;长期&lt;/td&gt;
&lt;td&gt;新项目默认安全，旧项目持续维护许可名单&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;立即行动清单&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;升级 npm&lt;/strong&gt;：&lt;code&gt;npm install -g npm@11&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;运行一次完整安装&lt;/strong&gt;：观察 v12 兼容性警告&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;审查安装脚本&lt;/strong&gt;：&lt;code&gt;npm approve-scripts --allow-scripts-pending&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;建立许可名单&lt;/strong&gt;：对每个需要脚本的包做出明确决策&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;提交到仓库&lt;/strong&gt;：将 &lt;code&gt;package.json&lt;/code&gt; 中的 &lt;code&gt;allowScripts&lt;/code&gt; 纳入版本控制&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;清理 Git/远程依赖&lt;/strong&gt;：尽可能迁移到 npm 注册表正式包&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h2&gt;8. 总结&lt;/h2&gt;
&lt;p&gt;npm v12 的这次变更，本质上是 JavaScript 生态对 **&quot;默认不安全&quot;**时代的终结。从&quot;默认信任所有包，出事再修&quot;转向&quot;默认不信任，显式授权可信包&quot;，这是一个迟到但必须发生的范式转移。&lt;/p&gt;
&lt;p&gt;对于绝大多数项目而言，实际影响并不大——只需审批 3-5 个真正需要原生编译的依赖包。真正需要投入的是&lt;strong&gt;团队的意识转变&lt;/strong&gt;：把安装脚本审批视为代码审查的一部分，把 &lt;code&gt;allowScripts&lt;/code&gt; 视为和 &lt;code&gt;dependencies&lt;/code&gt; 同等重要的安全配置。&lt;/p&gt;
&lt;p&gt;2026 年 7 月的截止日期并不遥远。现在花一小时完成迁移，远好于在截止日面对 CI 全线崩溃。&lt;/p&gt;
</content:encoded></item><item><title>苹果玻璃样式深度解析：从毛玻璃到 visionOS 的视觉设计哲学</title><link>https://www.hehonglei.cn/posts/apple-glass-style-analysis/</link><guid isPermaLink="true">https://www.hehonglei.cn/posts/apple-glass-style-analysis/</guid><description>深入分析苹果玻璃材质（Glass Morphism）设计语言从 iOS 7 到 visionOS 的演进历程，涵盖磨砂玻璃、动态模糊、色彩混合原理及 CSS/WebGL 实现方案</description><pubDate>Mon, 01 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;1. 引言&lt;/h2&gt;
&lt;p&gt;苹果的玻璃材质设计语言（Glass Morphism）自 2013 年 iOS 7 引入以来，经历了从备受争议到成为行业标杆的转变。2024 年 visionOS 发布后，玻璃材质更是被推向了新的高度——从二维平面的装饰性元素，升级为空间计算环境中的基本交互界面。&lt;/p&gt;
&lt;p&gt;本文将从设计哲学、视觉效果原理、技术实现三个维度，深度解析苹果玻璃样式背后的设计逻辑与工程实践。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;2. 苹果玻璃样式的三个阶段&lt;/h2&gt;
&lt;h3&gt;2.1 iOS 7 — 毛玻璃的诞生（2013）&lt;/h3&gt;
&lt;p&gt;iOS 7 是苹果从拟物化（Skeuomorphism）转向扁平化（Flat Design）的转折点。约翰尼·艾维（Jony Ive）主导的设计团队引入了&lt;strong&gt;高斯模糊叠加半透明&lt;/strong&gt;的毛玻璃效果，核心特征包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;控制中心/通知中心&lt;/strong&gt;：背景采用实时高斯模糊，模糊半径约 30-40px&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;色彩吸取&lt;/strong&gt;：模糊层会从背景中进行色彩混合，而非简单叠加纯色&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;层次感&lt;/strong&gt;：通过模糊强度区分内容层级，前景内容清晰锐利，背景柔和退远&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;技术上，iOS 7 使用 &lt;code&gt;UIBlurEffect&lt;/code&gt; + &lt;code&gt;UIVisualEffectView&lt;/code&gt;，底层基于 Metal 的&lt;strong&gt;实时帧缓冲采样&lt;/strong&gt;，对屏幕当前帧进行 GPU 加速的高斯模糊处理。&lt;/p&gt;
&lt;h3&gt;2.2 macOS — 微妙的玻璃层次&lt;/h3&gt;
&lt;p&gt;macOS 的玻璃样式更为内敛。Finder 侧边栏、Safari 工具栏等区域采用&lt;strong&gt;半透明侧板&lt;/strong&gt;设计：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;模糊强度低于 iOS，避免干扰桌面生产力场景的内容识别&lt;/li&gt;
&lt;li&gt;桌面壁纸的色彩被轻度透出，营造环境融入感&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Vibrancy&lt;/strong&gt; 效果：前景文字的亮度/色彩根据背景自适应调整，确保可读性&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这是玻璃材质从视觉装饰向&lt;strong&gt;功能性半透明&lt;/strong&gt;的关键转变——不是为了炫技，而是为了在有限屏幕空间中创造层次感。&lt;/p&gt;
&lt;h3&gt;2.3 visionOS — 空间玻璃的全新维度（2024）&lt;/h3&gt;
&lt;p&gt;visionOS 将玻璃设计推向了全新的空间维度。其设计文档明确指出玻璃材质在空间计算中的三个核心功能：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;轻量化存在感&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;visionOS App 窗口使用&lt;strong&gt;磨砂玻璃作为标准容器背景&lt;/strong&gt;。这不是为了好看，而是有明确的功能目的：允许用户透过 App 看到周围的物理环境，保持空间感知。玻璃材质让数字内容&quot;浮&quot;在真实世界之上而非完全遮挡。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;深度暗示&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;玻璃的光线折射、边缘亮度、环境光反射共同构成了空间深度暗示（Depth Cues）。当用户在空间中移动时，玻璃材质与真实环境光线的交互变化，帮助大脑理解窗口在空间中的位置关系。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;对比度自适应&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;visionOS 使用 &lt;code&gt;glassBackgroundEffect&lt;/code&gt; 材质，系统会根据后方内容的复杂程度动态调整模糊半径和色调，确保文字始终可读——无论是面对纯色背景还是杂乱的客厅场景。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;3. 玻璃材质的光学原理&lt;/h2&gt;
&lt;h3&gt;3.1 三层叠加模型&lt;/h3&gt;
&lt;p&gt;苹果的玻璃效果本质上是&lt;strong&gt;三层视觉信息的叠加&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;┌──────────────────┐
│  前景内容层（文字/图标）  │ ← 清晰锐利
├──────────────────┤
│  玻璃表层（半透明 + 饱和度） │ ← 材质本体
├──────────────────┤
│  模糊后的背景层         │ ← GPU 采样
└──────────────────┘
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.2 核心视觉参数&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;参数&lt;/th&gt;
&lt;th&gt;iOS 7-15&lt;/th&gt;
&lt;th&gt;macOS&lt;/th&gt;
&lt;th&gt;visionOS&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;模糊半径&lt;/td&gt;
&lt;td&gt;30-40px&lt;/td&gt;
&lt;td&gt;15-25px&lt;/td&gt;
&lt;td&gt;动态自适应&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;背景透明度&lt;/td&gt;
&lt;td&gt;0.6-0.85&lt;/td&gt;
&lt;td&gt;0.7-0.9&lt;/td&gt;
&lt;td&gt;0.3-0.6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;饱和度增强&lt;/td&gt;
&lt;td&gt;+20%&lt;/td&gt;
&lt;td&gt;0%&lt;/td&gt;
&lt;td&gt;+30%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;边框光效&lt;/td&gt;
&lt;td&gt;无&lt;/td&gt;
&lt;td&gt;细线高光&lt;/td&gt;
&lt;td&gt;边缘折射光&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;动态响应&lt;/td&gt;
&lt;td&gt;滚动时更新&lt;/td&gt;
&lt;td&gt;静态&lt;/td&gt;
&lt;td&gt;头部追踪实时刷新&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;3.3 色彩混合算法&lt;/h3&gt;
&lt;p&gt;苹果的玻璃材质并非简单叠加半透明白色。其核心算法包含三个步骤：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;高斯模糊&lt;/strong&gt;：对背景区域进行高斯核卷积，核大小由模糊半径决定&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;饱和度调整&lt;/strong&gt;：使用色彩矩阵对模糊后的像素进行饱和度增强，补偿模糊造成的色彩稀释&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Alpha 混合&lt;/strong&gt;：将调整后的背景与前景玻璃色进行 alpha 混合&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;用数学表达即：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;result = α · glass_color + (1 - α) · saturate(blur(background), s)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;其中 α 为玻璃透明度，s 为饱和度增强系数。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;4. Web 端实现方案&lt;/h2&gt;
&lt;h3&gt;4.1 CSS backdrop-filter 方案&lt;/h3&gt;
&lt;p&gt;现代浏览器通过 &lt;code&gt;backdrop-filter&lt;/code&gt; 原生支持毛玻璃效果，这是最直接的实现方式：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.glass-panel {
  background: rgba(255, 255, 255, 0.25);
  backdrop-filter: blur(20px) saturate(180%);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  border-radius: 16px;
  border: 1px solid rgba(255, 255, 255, 0.3);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;优势&lt;/strong&gt;：GPU 加速，性能优异，代码量极少。
&lt;strong&gt;局限&lt;/strong&gt;：模糊效果取决于浏览器实现，不同浏览器效果差异较大；不支持 Safari 的部分旧版本。&lt;/p&gt;
&lt;h3&gt;4.2 高级玻璃拟态（Glassmorphism）&lt;/h3&gt;
&lt;p&gt;完整的玻璃拟态效果需在基础毛玻璃之上叠加多层细节：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.glassmorphism-card {
  /* 基础玻璃层 */
  background: rgba(255, 255, 255, 0.15);
  backdrop-filter: blur(40px) saturate(180%);
  -webkit-backdrop-filter: blur(40px) saturate(180%);

  /* 边缘发光 — 模拟玻璃边缘的光线折射 */
  border: 1px solid rgba(255, 255, 255, 0.4);
  border-radius: 24px;

  /* 内部光晕 — 模拟玻璃厚度感 */
  box-shadow:
    0 8px 32px rgba(0, 0, 0, 0.1),
    inset 0 1px 0 rgba(255, 255, 255, 0.5);

  /* 微妙的渐变叠加 — 模拟光源方向 */
  background: linear-gradient(
    135deg,
    rgba(255, 255, 255, 0.25) 0%,
    rgba(255, 255, 255, 0.05) 100%
  );
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.3 visionOS 风格模拟&lt;/h3&gt;
&lt;p&gt;visionOS 的玻璃材质更加复杂，需要多层叠加：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.visionos-glass {
  position: relative;
  background: rgba(255, 255, 255, 0.18);
  backdrop-filter: blur(48px) saturate(200%) brightness(1.1);
  -webkit-backdrop-filter: blur(48px) saturate(200%) brightness(1.1);
  border-radius: 28px;

  /* 玻璃边缘折射光 */
  border: 1px solid rgba(255, 255, 255, 0.35);

  /* 环境光反射模拟 */
  box-shadow:
    0 4px 30px rgba(0, 0, 0, 0.12),
    0 1px 3px rgba(255, 255, 255, 0.3),
    inset 0 0 0 1px rgba(255, 255, 255, 0.15);

  /* 模拟光源渐变 */
  &amp;amp;::before {
    content: &apos;&apos;;
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: linear-gradient(
      160deg,
      rgba(255, 255, 255, 0.15) 0%,
      transparent 50%,
      rgba(255, 255, 255, 0.05) 100%
    );
    pointer-events: none;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.4 性能考量&lt;/h3&gt;
&lt;p&gt;玻璃效果的核心性能瓶颈在于 &lt;code&gt;backdrop-filter&lt;/code&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;模糊半径越大，GPU 开销越高&lt;/strong&gt;。40px 以上模糊在低端设备上可能引发掉帧&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;嵌套玻璃层&lt;/strong&gt;：避免在已有 &lt;code&gt;backdrop-filter&lt;/code&gt; 的元素内再嵌套模糊层，会触发二次采样&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;will-change 提示&lt;/strong&gt;：对于动画中的玻璃元素，添加 &lt;code&gt;will-change: backdrop-filter&lt;/code&gt; 提前分配 GPU 资源&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;移动端降级&lt;/strong&gt;：建议对低性能设备提供纯色半透明降级方案&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;/* 性能降级策略 */
@media (prefers-reduced-transparency: reduce) {
  .glass-panel {
    backdrop-filter: none;
    background: rgba(255, 255, 255, 0.85);
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;5. 设计趋势与展望&lt;/h2&gt;
&lt;h3&gt;5.1 从装饰到功能&lt;/h3&gt;
&lt;p&gt;苹果玻璃材质 11 年的演进揭示了一个清晰趋势：&lt;strong&gt;半透明材质从视觉装饰逐步成为功能性界面元素&lt;/strong&gt;。在空间计算时代，玻璃材质不再只是&quot;好看&quot;，而是解决&quot;如何让数字界面与物理空间共存&quot;这一根本问题的答案。&lt;/p&gt;
&lt;h3&gt;5.2 跨平台统一&lt;/h3&gt;
&lt;p&gt;随着 visionOS、iOS、macOS 设计语言的持续融合，玻璃材质在不同设备上的表现正在趋同。Apple Design Resources 中已出现 &lt;code&gt;Glass Background&lt;/code&gt; 通用材质，可跨平台使用。&lt;/p&gt;
&lt;h3&gt;5.3 对 Web 设计的启示&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;层次感优先于装饰&lt;/strong&gt;：半透明材质应服务于内容层级，而非单纯的视觉效果&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可访问性不可忽视&lt;/strong&gt;：始终提供 &lt;code&gt;prefers-reduced-transparency&lt;/code&gt; 降级方案&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GPU 预算意识&lt;/strong&gt;：玻璃效果是昂贵的，需权衡效果与性能&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;6. 结语&lt;/h2&gt;
&lt;p&gt;苹果玻璃样式的设计哲学可以概括为一句话：&lt;strong&gt;让界面变得轻盈，让内容成为唯一的主角&lt;/strong&gt;。从 iOS 7 的毛玻璃到 visionOS 的空间材质，苹果一直在追求一种&quot;消失的 UI&quot;——界面存在但不过度存在，容器可见但不遮挡背后。&lt;/p&gt;
&lt;p&gt;对于前端开发者，理解玻璃材质的设计原理不仅能写出更精致的 UI，更能提升对现代设计语言演进的洞察力。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;参考资料&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.apple.com/design/human-interface-guidelines/materials&quot;&gt;Apple Human Interface Guidelines — Materials (visionOS)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/backdrop-filter&quot;&gt;CSS backdrop-filter — MDN&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://ui.glass/generator/&quot;&gt;Glassmorphism CSS Generator&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>修复落地页加载白闪屏：CSS transition 引发的性能问题</title><link>https://www.hehonglei.cn/posts/fix-white-flash-on-load/</link><guid isPermaLink="true">https://www.hehonglei.cn/posts/fix-white-flash-on-load/</guid><description>排查并修复博客落地页在暗色模式下的加载白闪屏问题，根因是 html 标签上的 Tailwind transition class 导致首帧背景色动画化</description><pubDate>Wed, 27 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;问题描述&lt;/h2&gt;
&lt;p&gt;博客落地页在加载时会出现短暂的白闪屏，尤其在暗色模式下非常明显。页面打开瞬间先显示白色背景，然后才过渡为深色背景——这个闪烁持续约 150ms，对用户体验影响很大。&lt;/p&gt;
&lt;h2&gt;排查过程&lt;/h2&gt;
&lt;h3&gt;第一步：定位闪屏发生的时机&lt;/h3&gt;
&lt;p&gt;打开 DevTools Performance 面板录制加载过程，发现闪屏发生在首帧绘制（First Paint）阶段。此时页面背景色从亮色值突然切换到暗色值，且带有平滑过渡动画。&lt;/p&gt;
&lt;h3&gt;第二步：检查主题初始化逻辑&lt;/h3&gt;
&lt;p&gt;我的博客使用 Astro 构建，暗色模式通过给 &lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt; 添加 &lt;code&gt;.dark&lt;/code&gt; class 实现。CSS 变量使用 Stylus 的 &lt;code&gt;define&lt;/code&gt; mixin 分别定义亮色/暗色值：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;define({
  --page-bg: oklch(0.95 0.01 var(--hue)) oklch(0.16 0.014 var(--hue))
  --card-bg: white oklch(0.23 0.015 var(--hue))
  // ...
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;编译后生成：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;:root { --page-bg: oklch(0.95 0.01 var(--hue)); }
:root.dark { --page-bg: oklch(0.16 0.014 var(--hue)); }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在 &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; 中已经有一份内联脚本负责在页面渲染前从 &lt;code&gt;localStorage&lt;/code&gt; 读取主题偏好并设置 &lt;code&gt;dark&lt;/code&gt; class。逻辑本身没问题，脚本也确实在 &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; 渲染前执行了。&lt;/p&gt;
&lt;h3&gt;第三步：发现真凶&lt;/h3&gt;
&lt;p&gt;回头看 &lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt; 标签：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;html class=&quot;bg-[var(--page-bg)] transition ...&quot;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;transition&lt;/code&gt; 是 Tailwind 的 utility class&lt;/strong&gt;，展开后等价于：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 150ms;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;整个闪烁链路就清楚了：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;浏览器开始解析 HTML，CSS 变量初始为亮色值（&lt;code&gt;--page-bg: oklch(0.95 ...)&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;内联脚本执行，添加 &lt;code&gt;.dark&lt;/code&gt; class&lt;/li&gt;
&lt;li&gt;CSS 变量切换为暗色值（&lt;code&gt;--page-bg: oklch(0.16 ...)&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;因为 &lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt; 有 &lt;code&gt;transition&lt;/code&gt;，background-color 的变更被动画化&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;亮色背景 → 暗色背景，150ms 过渡 = 用户看到白闪&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;修复方案&lt;/h2&gt;
&lt;p&gt;在 &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; 最开头插入一个临时 &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt; 标签，在首帧渲染前&lt;strong&gt;禁用所有 transition&lt;/strong&gt;，首帧绘制完成后移除它，恢复正常的主题切换过渡：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!-- Layout.astro &amp;lt;head&amp;gt; 最开头 --&amp;gt;
&amp;lt;style id=&quot;prevent-flash&quot;&amp;gt;
  *, *::before, *::after {
    transition: none !important;
  }
&amp;lt;/style&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;配合 JavaScript 在首帧后清理：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;requestAnimationFrame(() =&amp;gt; {
  requestAnimationFrame(() =&amp;gt; {
    const preventFlash = document.getElementById(&apos;prevent-flash&apos;);
    if (preventFlash) preventFlash.remove();
  });
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;双 &lt;code&gt;requestAnimationFrame&lt;/code&gt; 的作用&lt;/strong&gt;：第一个 rAF 在浏览器下一次重绘前执行，第二个 rAF 确保浏览器已经完成了首帧绘制，此时移除防闪屏 style，后续的主题切换依然有平滑过渡。&lt;/p&gt;
&lt;h2&gt;总结&lt;/h2&gt;
&lt;p&gt;这个 bug 的根因很小——就是 &lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt; 上一个看似无害的 &lt;code&gt;transition&lt;/code&gt; class，但它的影响范围覆盖了整个页面的所有颜色属性。&lt;/p&gt;
&lt;p&gt;查 bug 时容易陷入&quot;逻辑正确就不该有问题&quot;的思维盲区。这个 case 里主题切换的逻辑完全正确，问题出在视觉层面——CSS 过渡与首帧绘制产生了意外的交互。&lt;/p&gt;
&lt;p&gt;关键心得：&lt;strong&gt;broad-scope CSS transitions（如给 &lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt; 或 &lt;code&gt;*&lt;/code&gt; 加 transition）在首帧加载时一定会产生视觉副作用&lt;/strong&gt;。要么别用，要么用防闪屏模式兜底。&lt;/p&gt;
</content:encoded></item><item><title>CSS in JS 技术详解：从 styled-components 到 Panda CSS</title><link>https://www.hehonglei.cn/posts/css-in-js-guide/</link><guid isPermaLink="true">https://www.hehonglei.cn/posts/css-in-js-guide/</guid><description>深入探讨 CSS in JS 技术的发展历程、核心方案对比（styled-components、Emotion、Vanilla Extract、Panda CSS），以及编译时零运行时方案的优势与选型建议</description><pubDate>Tue, 26 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;什么是 CSS in JS&lt;/h2&gt;
&lt;p&gt;CSS in JS 是一种将 CSS 样式编写在 JavaScript/TypeScript 文件中的技术方案。它允许开发者利用 JavaScript 的能力来管理样式，实现动态样式、主题切换、样式隔离等功能。自 2014 年 Facebook 的 Christopher Chedeau 在 NationJS 大会上提出这一概念以来，CSS in JS 已经成为现代前端开发的主流选择之一。&lt;/p&gt;
&lt;h2&gt;发展历程&lt;/h2&gt;
&lt;h3&gt;第一代：运行时方案&lt;/h3&gt;
&lt;p&gt;最早期的 CSS in JS 库如 &lt;strong&gt;styled-components&lt;/strong&gt; 和 &lt;strong&gt;Emotion&lt;/strong&gt; 采用运行时方案，样式在 JavaScript 运行时被注入到 DOM 中。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;核心特征：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;样式在 JS 运行时计算和注入&lt;/li&gt;
&lt;li&gt;利用模板字面量或对象语法定义样式&lt;/li&gt;
&lt;li&gt;支持基于 props 的动态样式&lt;/li&gt;
&lt;li&gt;自动处理浏览器前缀和关键帧动画&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;styled-components 示例&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;import styled from &apos;styled-components&apos;

const Button = styled.button`
  background: ${props =&amp;gt; props.primary ? &apos;#3b82f6&apos; : &apos;#fff&apos;};
  color: ${props =&amp;gt; props.primary ? &apos;#fff&apos; : &apos;#3b82f6&apos;};
  padding: 10px 20px;
  border-radius: 8px;
  border: 2px solid #3b82f6;
  cursor: pointer;
  font-size: 16px;
  transition: all 0.2s ease;

  &amp;amp;:hover {
    transform: translateY(-1px);
    box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3);
  }
`

// 使用时
&amp;lt;Button primary&amp;gt;提交&amp;lt;/Button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Emotion (CSS Prop 方式)&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;/** @jsxImportSource @emotion/react */
import { css } from &apos;@emotion/react&apos;

const buttonStyle = css`
  padding: 10px 20px;
  border-radius: 8px;
  font-size: 16px;
`

function App() {
  return (
    &amp;lt;button css={buttonStyle}&amp;gt;
      点击我
    &amp;lt;/button&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;第二代：编译时零运行时方案&lt;/h3&gt;
&lt;p&gt;随着性能要求的提升，&lt;strong&gt;编译时零运行时&lt;/strong&gt; 的 CSS in JS 方案开始兴起。这类方案在构建阶段将样式提取为静态 CSS 文件，运行时不再执行 JavaScript 来生成样式。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;核心优势：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;零运行时开销，打包体积更小&lt;/li&gt;
&lt;li&gt;样式在构建时提取为 .css 文件&lt;/li&gt;
&lt;li&gt;更好的 SSR 和 SSG 支持&lt;/li&gt;
&lt;li&gt;接近原生 CSS 的性能表现&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Vanilla Extract&lt;/h4&gt;
&lt;p&gt;Vanilla Extract 在 TypeScript 中编写类型安全的样式，编译时生成静态 CSS：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// styles.css.ts
import { style } from &apos;@vanilla-extract/css&apos;

export const button = style({
  padding: &apos;10px 20px&apos;,
  borderRadius: &apos;8px&apos;,
  fontSize: &apos;16px&apos;,
  border: &apos;none&apos;,
  cursor: &apos;pointer&apos;,
  transition: &apos;all 0.2s ease&apos;,

  &apos;:hover&apos;: {
    transform: &apos;translateY(-1px)&apos;,
    boxShadow: &apos;0 4px 12px rgba(0, 0, 0, 0.15)&apos;
  }
})

export const primary = style({
  background: &apos;#3b82f6&apos;,
  color: &apos;#fff&apos;
})
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Panda CSS&lt;/h4&gt;
&lt;p&gt;Panda CSS 是目前最受欢迎的零运行时方案，提供了完整的类型安全和设计令牌系统：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { css } from &apos;../styled-system/css&apos;

function App() {
  return (
    &amp;lt;button
      className={css({
        bg: &apos;blue.500&apos;,
        color: &apos;white&apos;,
        px: &apos;5&apos;,
        py: &apos;2.5&apos;,
        rounded: &apos;lg&apos;,
        cursor: &apos;pointer&apos;,
        _hover: {
          transform: &apos;translateY(-1px)&apos;,
          boxShadow: &apos;lg&apos;
        }
      })}
    &amp;gt;
      提交
    &amp;lt;/button&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Panda CSS 还可以配置设计令牌（Design Tokens），实现设计系统的一致化管理：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// panda.config.ts
import { defineConfig } from &apos;@pandacss/dev&apos;

export default defineConfig({
  theme: {
    tokens: {
      colors: {
        blue: {
          500: { value: &apos;#3b82f6&apos; }
        }
      },
      spacing: {
        5: { value: &apos;1.25rem&apos; },
        2.5: { value: &apos;0.625rem&apos; }
      }
    }
  }
})
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;主流方案对比&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;styled-components&lt;/th&gt;
&lt;th&gt;Emotion&lt;/th&gt;
&lt;th&gt;Vanilla Extract&lt;/th&gt;
&lt;th&gt;Panda CSS&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;运行方式&lt;/td&gt;
&lt;td&gt;运行时&lt;/td&gt;
&lt;td&gt;运行时&lt;/td&gt;
&lt;td&gt;编译时&lt;/td&gt;
&lt;td&gt;编译时&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;打包体积&lt;/td&gt;
&lt;td&gt;~14KB&lt;/td&gt;
&lt;td&gt;~8KB&lt;/td&gt;
&lt;td&gt;0 (运行时)&lt;/td&gt;
&lt;td&gt;0 (运行时)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TypeScript 支持&lt;/td&gt;
&lt;td&gt;中等&lt;/td&gt;
&lt;td&gt;中等&lt;/td&gt;
&lt;td&gt;完善&lt;/td&gt;
&lt;td&gt;完善&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;动态样式&lt;/td&gt;
&lt;td&gt;props&lt;/td&gt;
&lt;td&gt;props / css prop&lt;/td&gt;
&lt;td&gt;recipes&lt;/td&gt;
&lt;td&gt;recipes / cva&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SSR 友好度&lt;/td&gt;
&lt;td&gt;一般&lt;/td&gt;
&lt;td&gt;较好&lt;/td&gt;
&lt;td&gt;优秀&lt;/td&gt;
&lt;td&gt;优秀&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;学习成本&lt;/td&gt;
&lt;td&gt;低&lt;/td&gt;
&lt;td&gt;低&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;生态成熟度&lt;/td&gt;
&lt;td&gt;非常成熟&lt;/td&gt;
&lt;td&gt;成熟&lt;/td&gt;
&lt;td&gt;中等&lt;/td&gt;
&lt;td&gt;快速发展&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;零运行时方案为什么更优&lt;/h2&gt;
&lt;h3&gt;1. 性能提升&lt;/h3&gt;
&lt;p&gt;传统的运行时 CSS in JS 在组件渲染时需要计算样式哈希、插入样式标签，这些操作会消耗主线程时间。在大型应用中，这些开销会累积成明显的性能瓶颈。&lt;/p&gt;
&lt;p&gt;零运行时方案将这一过程移到了构建阶段，运行时直接使用预生成的 CSS 类名，配合浏览器的 CSS 解析引擎，性能更优。&lt;/p&gt;
&lt;h3&gt;2. 更好的 SSR 支持&lt;/h3&gt;
&lt;p&gt;运行时方案在服务端渲染时需要提取样式并注入到 HTML 中，这一过程需要额外的配置和处理。而零运行时方案生成的静态 CSS 文件可以直接通过 &lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt; 标签引入，SSR 的流程更加简洁自然。&lt;/p&gt;
&lt;h3&gt;3. 更小的打包体积&lt;/h3&gt;
&lt;p&gt;零运行时方案去除了样式运行时的库代码，JavaScript bundle 体积显著减小。对于性能敏感的应用来说，这是一个重要的优势。&lt;/p&gt;
&lt;h3&gt;4. 与 React Server Components 的良好兼容&lt;/h3&gt;
&lt;p&gt;React Server Components 在服务端渲染，不支持运行时 CSS in JS。零运行时方案天然兼容 RSC，是构建 Next.js 14+ 应用的理想选择。&lt;/p&gt;
&lt;h2&gt;选型建议&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;快速迭代的小型项目&lt;/strong&gt;：styled-components 或 Emotion 上手快，生态丰富&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;性能敏感的生产项目&lt;/strong&gt;：优先考虑 Vanilla Extract 或 Panda CSS&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;使用 Next.js 14+ 或 RSC&lt;/strong&gt;：选择编译时零运行时方案&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;需要完整设计系统&lt;/strong&gt;：Panda CSS 的设计令牌体系是最佳选择&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tailwind 用户迁移&lt;/strong&gt;：Panda CSS 的原子化 CSS 模式更容易上手&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;总结&lt;/h2&gt;
&lt;p&gt;CSS in JS 技术正在从运行时方案向编译时零运行时方案演进。如果你的项目对性能有较高要求，或者正在使用 React Server Components，强烈建议选择 Vanilla Extract 或 Panda CSS 这类编译时方案。它们保留了 TypeScript 类型安全和组件化样式的优势，同时消除了运行时的性能开销。&lt;/p&gt;
&lt;p&gt;未来，随着浏览器原生 CSS 能力的不断增强（CSS Nesting、CSS Layers、CSS Container Queries），CSS in JS 的方案可能会进一步与平台特性融合，让 Web 样式开发变得更加高效和可控。&lt;/p&gt;
</content:encoded></item><item><title>Ant Design X 2.7 发布：RICH 范式与 Hybrid UI 重塑 AI 界面开发</title><link>https://www.hehonglei.cn/posts/ant-design-x-introduction/</link><guid isPermaLink="true">https://www.hehonglei.cn/posts/ant-design-x-introduction/</guid><description>Ant Design X 是 Ant Design 生态面向 AI 驱动界面的 React 组件库，基于 RICH 交互范式与 Hybrid UI 理念，提供流式 Markdown 渲染、A2UI 动态卡片、AI SDK 等完整解决方案。</description><pubDate>Thu, 21 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;1. 什么是 Ant Design X？&lt;/h2&gt;
&lt;p&gt;Ant Design X（&lt;code&gt;@ant-design/x&lt;/code&gt;）是 Ant Design 团队推出的&lt;strong&gt;面向 AI 驱动界面的 React 组件库&lt;/strong&gt;。它并不是 Ant Design 5 的替代品，而是在原有设计体系之上，专为构建 AI 聊天、智能助手、Agent 控制台等场景设计的一套新组件体系。&lt;/p&gt;
&lt;p&gt;2026 年 4 月 30 日，Ant Design X 发布了 &lt;strong&gt;v2.7.0&lt;/strong&gt; 版本，生态已涵盖 5 个核心包：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;包名&lt;/th&gt;
&lt;th&gt;用途&lt;/th&gt;
&lt;th&gt;最新版本&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;@ant-design/x&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;核心 AI 界面组件库&lt;/td&gt;
&lt;td&gt;2.7.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;@ant-design/x-markdown&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;流式 Markdown 渲染器&lt;/td&gt;
&lt;td&gt;2.7.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;@ant-design/x-sdk&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;AI 数据流管理 SDK&lt;/td&gt;
&lt;td&gt;2.7.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;@ant-design/x-card&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A2UI 动态卡片渲染&lt;/td&gt;
&lt;td&gt;2.7.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;@ant-design/x-skill&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;AI 编码助手技能库&lt;/td&gt;
&lt;td&gt;2.7.0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;2. 设计哲学：RICH 交互范式&lt;/h2&gt;
&lt;p&gt;Ant Design X 的核心设计理念是 &lt;strong&gt;RICH 范式&lt;/strong&gt;，它将 AI 交互拆解为四个阶段：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;RICH 交互流程
├── R — Role（角色意图）
│   ├── Welcome 欢迎组件
│   └── Prompts 提示集
├── I — Intention（意图唤醒）
│   ├── Sender 输入框
│   ├── Attachment 附件
│   └── Suggestion 快捷建议
├── C — Conversation（会话沟通）
│   ├── Bubble 对话气泡
│   ├── Conversations 会话列表
│   └── Notification 通知
└── H — Hybrid UI（混合界面）
    ├── Think 思考过程
    ├── ThoughtChain 思维链
    ├── Actions 操作栏
    ├── FileCard 文件卡片
    ├── Sources 引用来源
    ├── Mermaid 图表渲染
    ├── Folder 文件树
    └── CodeHighlighter 代码高亮
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;RICH 不是线性流程，而是&lt;strong&gt;可组合的交互单元&lt;/strong&gt;。你可以单独使用某个阶段的组件，也可以将它们组合成完整的 AI 应用。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;3. Hybrid UI：融合 GUI 与自然语言&lt;/h2&gt;
&lt;p&gt;Ant Design X 提出的 &lt;strong&gt;Hybrid UI (HUI)&lt;/strong&gt; 概念试图解决一个核心矛盾：传统 GUI 操作效率高但学习成本大，自然语言交互灵活但意图表达模糊。&lt;/p&gt;
&lt;p&gt;HUI 将交互模式分为三种：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;模式&lt;/th&gt;
&lt;th&gt;特点&lt;/th&gt;
&lt;th&gt;适用场景&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Do-heavy&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;GUI 为主，AI 辅助&lt;/td&gt;
&lt;td&gt;结构化表单、数据录入&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Chat-heavy&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;自然语言为主&lt;/td&gt;
&lt;td&gt;开放式问答、内容生成&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;HUI 混合&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;GUI + Chat 自由切换&lt;/td&gt;
&lt;td&gt;智能客服、Agent 控制台&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;这种设计让同一个界面既能通过传统表单精准操作，也能通过自然语言灵活表达，「鱼与熊掌兼得」。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;4. 核心组件速览&lt;/h2&gt;
&lt;h3&gt;4.1 Bubble — 对话气泡&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;Bubble&lt;/code&gt; 是展示对话内容的基础组件，支持多种角色和内容类型：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { Bubble } from &apos;@ant-design/x&apos;;

&amp;lt;Bubble
  placement=&quot;start&quot;
  avatar={{ icon: &amp;lt;RobotOutlined /&amp;gt; }}
  content=&quot;你好，我是 AI 助手&quot;
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.2 Sender — 输入框&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;Sender&lt;/code&gt; 是一个增强型输入组件，支持附件上传、语音输入和快捷建议：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { Sender } from &apos;@ant-design/x&apos;;

&amp;lt;Sender
  onSubmit={(value) =&amp;gt; console.log(value)}
  placeholder=&quot;输入你的问题...&quot;
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.3 ThoughtChain — 思维链&lt;/h3&gt;
&lt;p&gt;展示 AI Agent 的思考过程，让用户理解 AI 的推理路径：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { ThoughtChain } from &apos;@ant-design/x&apos;;

&amp;lt;ThoughtChain
  items={[
    { title: &apos;分析问题&apos;, description: &apos;识别关键词...&apos;, status: &apos;success&apos; },
    { title: &apos;检索知识库&apos;, description: &apos;匹配到 3 条相关文档&apos;, status: &apos;success&apos; },
    { title: &apos;生成回答&apos;, status: &apos;pending&apos; },
  ]}
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.4 Sources — 引用来源&lt;/h3&gt;
&lt;p&gt;展示 AI 回答的参考来源，增强可信度：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { Sources } from &apos;@ant-design/x&apos;;

&amp;lt;Sources
  items={[
    { title: &apos;React 官方文档&apos;, url: &apos;https://react.dev&apos; },
    { title: &apos;Ant Design X 文档&apos;, url: &apos;https://x.ant.design&apos; },
  ]}
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;5. XMarkdown：流式 Markdown 渲染&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;@ant-design/x-markdown&lt;/code&gt; 是一个专为 AI 流式输出优化的 Markdown 渲染引擎。它解决了传统 Markdown 渲染器在流式场景下的三个核心问题：&lt;/p&gt;
&lt;h3&gt;5.1 不完整语法容错&lt;/h3&gt;
&lt;p&gt;当 AI 流式输出 &lt;code&gt;$$E = mc^&lt;/code&gt;（公式未闭合）时，XMarkdown 不会崩溃，而是优雅降级渲染：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { XMarkdown } from &apos;@ant-design/x-markdown&apos;;

&amp;lt;XMarkdown
  content={streamingText}
  streaming={{ tail: &apos;▋&apos; }} // 流式光标指示器
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.2 自定义流式尾部指示器&lt;/h3&gt;
&lt;p&gt;v2.6.0 新增的 &lt;code&gt;streaming.tail&lt;/code&gt; 配置支持自定义闪烁光标：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;XMarkdown
  content={streamingText}
  streaming={{
    tail: &apos;▋&apos;,
    tailComponent: &amp;lt;BlinkingCursor /&amp;gt;
  }}
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.3 安全渲染&lt;/h3&gt;
&lt;p&gt;v2.3.0 新增 &lt;code&gt;escapeRawHtml&lt;/code&gt; 属性，防止 XSS 攻击：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;XMarkdown
  content={untrustedContent}
  escapeRawHtml={true}
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;6. X SDK：AI 数据流管理&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;@ant-design/x-sdk&lt;/code&gt; 封装了与 AI 模型交互的完整数据流：&lt;/p&gt;
&lt;h3&gt;6.1 XRequest — 请求管理&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;import { XRequest } from &apos;@ant-design/x-sdk&apos;;

const request = XRequest({
  baseURL: &apos;https://api.openai.com/v1&apos;,
  model: &apos;gpt-4o&apos;,
  apiKey: process.env.OPENAI_API_KEY,
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;v2.2.0 支持&lt;strong&gt;断线重连&lt;/strong&gt;和&lt;strong&gt;自定义流分隔符&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;XRequest({
  baseURL: &apos;https://api.example.com&apos;,
  model: &apos;custom-model&apos;,
  streamSeparator: &apos;\n&apos;,      // 流分隔符
  partSeparator: &apos;data: &apos;,    // 部分分隔符
  kvSeparator: &apos;: &apos;,          // 键值分隔符
});
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.2 useXChat — 会话管理&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;import { useXChat } from &apos;@ant-design/x-sdk&apos;;

const { messages, onRequest } = useXChat({
  request,
  queueRequest: true, // v2.3.0 新增：支持请求队列
});
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;7. X Card：A2UI 动态卡片&lt;/h2&gt;
&lt;p&gt;v2.5.0 发布的 &lt;code&gt;@ant-design/x-card&lt;/code&gt; 是整个生态最亮眼的新成员。它基于 &lt;strong&gt;A2UI 协议&lt;/strong&gt;，允许 AI Agent 动态生成结构化 UI：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { XCard } from &apos;@ant-design/x-card&apos;;

&amp;lt;XCard
  // AI 返回的 A2UI JSON 描述
  a2ui={agentResponse}
  dataModel={userData}
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A2UI 的核心价值在于：&lt;strong&gt;AI 不只是返回文本，而是返回可交互的卡片&lt;/strong&gt;。例如，AI 可以返回一个包含表单、图表、按钮的完整交互界面，而不仅仅是文字描述。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;8. 快速上手&lt;/h2&gt;
&lt;h3&gt;8.1 安装&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 核心组件库
npm install @ant-design/x

# 流式 Markdown（可选）
npm install @ant-design/x-markdown

# AI SDK（可选）
npm install @ant-design/x-sdk
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;8.2 一个完整的 AI 聊天应用&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;import {
  Bubble,
  Conversations,
  Sender,
  XProvider,
} from &apos;@ant-design/x&apos;;
import { XMarkdown } from &apos;@ant-design/x-markdown&apos;;
import { useXChat, XRequest } from &apos;@ant-design/x-sdk&apos;;

export default function ChatApp() {
  const request = XRequest({
    baseURL: &apos;https://api.openai.com/v1&apos;,
    model: &apos;gpt-4o&apos;,
    apiKey: process.env.NEXT_PUBLIC_OPENAI_API_KEY,
  });

  const { messages, onRequest } = useXChat({ request });

  return (
    &amp;lt;XProvider&amp;gt;
      &amp;lt;div style={{ height: &apos;100vh&apos;, display: &apos;flex&apos;, flexDirection: &apos;column&apos; }}&amp;gt;
        &amp;lt;Conversations
          items={messages.map((msg) =&amp;gt; ({
            key: msg.id,
            label: msg.content.slice(0, 30),
          }))}
        /&amp;gt;
        &amp;lt;div style={{ flex: 1, overflow: &apos;auto&apos;, padding: 16 }}&amp;gt;
          {messages.map((msg) =&amp;gt; (
            &amp;lt;Bubble
              key={msg.id}
              placement={msg.role === &apos;user&apos; ? &apos;end&apos; : &apos;start&apos;}
              content={&amp;lt;XMarkdown content={msg.content} /&amp;gt;}
            /&amp;gt;
          ))}
        &amp;lt;/div&amp;gt;
        &amp;lt;Sender onSubmit={onRequest} /&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/XProvider&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;不到 40 行代码，就实现了一个带有流式 Markdown 渲染、会话管理、AI 对话的完整聊天应用。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;9. 2026 年版本演进&lt;/h2&gt;
&lt;p&gt;Ant Design X 在 2026 年保持了&lt;strong&gt;月度 minor 版本&lt;/strong&gt;的发布节奏：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;版本&lt;/th&gt;
&lt;th&gt;日期&lt;/th&gt;
&lt;th&gt;关键更新&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;v2.7.0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;4 月 30 日&lt;/td&gt;
&lt;td&gt;XProvider &lt;code&gt;zeroRuntime&lt;/code&gt;、XCard 路径引用解析&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;v2.6.0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;4 月 17 日&lt;/td&gt;
&lt;td&gt;XMarkdown 尾部指示器组件、x-components/x-card skill&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;v2.5.0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;3 月 31 日&lt;/td&gt;
&lt;td&gt;🔥 X Card 动态卡片模块发布&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;v2.4.0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;3 月 13 日&lt;/td&gt;
&lt;td&gt;🔥 Folder 文件树组件、x-markdown skill&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;v2.3.0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2 月 26 日&lt;/td&gt;
&lt;td&gt;useXChat &lt;code&gt;queueRequest&lt;/code&gt;、XMarkdown &lt;code&gt;escapeRawHtml&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;v2.2.0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1 月&lt;/td&gt;
&lt;td&gt;Mermaid 配置、XRequest 重连、XMarkdown 性能测试&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;可以看到，团队在持续探索 &lt;strong&gt;AI 界面即代码&lt;/strong&gt; 的边界——从流式 Markdown 到动态卡片渲染，每一步都在降低 AI 应用的开发门槛。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;10. 与竞品对比&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;维度&lt;/th&gt;
&lt;th&gt;Ant Design X&lt;/th&gt;
&lt;th&gt;Vercel AI SDK&lt;/th&gt;
&lt;th&gt;LangChain&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;定位&lt;/td&gt;
&lt;td&gt;UI 组件库 + 数据流&lt;/td&gt;
&lt;td&gt;数据流 + 轻量 UI&lt;/td&gt;
&lt;td&gt;AI 编排框架&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UI 体系&lt;/td&gt;
&lt;td&gt;✅ 完整组件库&lt;/td&gt;
&lt;td&gt;⚠️ 基础组件&lt;/td&gt;
&lt;td&gt;❌ 无&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;流式 Markdown&lt;/td&gt;
&lt;td&gt;✅ XMarkdown&lt;/td&gt;
&lt;td&gt;⚠️ 基础支持&lt;/td&gt;
&lt;td&gt;❌ 无&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;混合界面&lt;/td&gt;
&lt;td&gt;✅ Hybrid UI&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;框架绑定&lt;/td&gt;
&lt;td&gt;React 专属&lt;/td&gt;
&lt;td&gt;React/Vue/Svelte&lt;/td&gt;
&lt;td&gt;跨平台&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Ant Design X 的差异化优势在于&lt;strong&gt;完整的 UI 组件体系 + 流式渲染引擎&lt;/strong&gt;，而不仅仅是数据流管理层。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;11. 总结&lt;/h2&gt;
&lt;p&gt;Ant Design X 的定位非常清晰：&lt;strong&gt;不是又一个 AI SDK，而是一套完整的 AI 界面解决方案&lt;/strong&gt;。它的核心价值在于：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;RICH 范式&lt;/strong&gt;提供了 AI 交互的标准化设计语言&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hybrid UI&lt;/strong&gt;打破了 GUI 和 Chat 的界限&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;XMarkdown&lt;/strong&gt;解决了流式渲染的核心痛点&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;X Card&lt;/strong&gt;开启了 AI 动态生成 UI 的可能性&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;开箱即用&lt;/strong&gt;：与 Ant Design 生态无缝集成，React 开发者零学习成本&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;如果你正在开发 AI 聊天产品、Agent 控制台或智能助手界面，Ant Design X 是目前 React 生态中最成熟、最完整的选择。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;参考资料&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://x.ant.design&quot;&gt;Ant Design X 官网&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/ant-design/x&quot;&gt;Ant Design X GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://x.ant.design/changelog&quot;&gt;Ant Design X 更新日志&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://ant-design-x.antgroup.com/docs/spec/hybrid-ui-design&quot;&gt;RICH 交互范式介绍&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.npmjs.com/package/@ant-design/x&quot;&gt;npm @ant-design/x&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Copy Fail 漏洞（CVE-2026-31431）五大核心机制详解</title><link>https://www.hehonglei.cn/posts/copy-fail-cve-2026-31431/</link><guid isPermaLink="true">https://www.hehonglei.cn/posts/copy-fail-cve-2026-31431/</guid><description>从 setuid、splice、AF_ALG、algif_aead 到 authencesn，逐一拆解 Copy Fail 本地提权漏洞的技术链条。</description><pubDate>Mon, 11 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;1. 漏洞效果：越权写入 page cache&lt;/h2&gt;
&lt;p&gt;CVE-2026-31431 提权漏洞的影响效果可以理解为，让一个普通用户在没有写权限的情况下，临时改掉了系统内存里某些本不该被修改的文件内容，然后借助这个机会，通过任意代码执行获得 root 权限。&lt;/p&gt;
&lt;p&gt;正常情况下，文件有权限保护，普通用户无法写入高权限敏感目录，修改系统命令或者高权限的程序。&lt;/p&gt;
&lt;p&gt;问题在于，Linux 为了让系统跑得快一些，在用户需要读文件的时候，并不会每次都去硬盘上重新读一遍。在文件被频繁访问时，它会把文件放进内存缓存里，也就是 page cache。程序运行时，很多时候读到的其实是内存里的这个 page cache，可以理解为文件在内存中的映射或缓存表示。&lt;/p&gt;
&lt;p&gt;Copy Fail 漏洞的关键在于攻击者没有改硬盘上的文件，却改到了内存缓存里的文件内容，也就是这个缓存表示，最终成功完成了攻击。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;通俗类比&lt;/strong&gt;：把系统想象成图书馆，系统里的真正文件（原稿）放在库房里，普通读者只能看，不能改。为了方便读取，管理员把常用书复印了一份放在阅览室。正常规则应该是读者只能看复印件，也不能改复印件。&lt;/p&gt;
&lt;p&gt;这次的漏洞，可以看作系统在某个流程里把只能看的复印件误当成了可以涂写的草稿纸，于是读者虽然没有权限改库房里的原书，也没有权限改这个只读的复印件，但实际上却成功修改了这份复印件，完成了越权写入。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;2. 第一个核心机制：setuid&lt;/h2&gt;
&lt;p&gt;Linux 系统里有一些特殊程序，普通用户可以运行，但运行时会临时带有 root 权限，表面上看普通用户可以更高权限工作，有点像越权，但这是经过系统信任的。&lt;/p&gt;
&lt;p&gt;这里如果展开讲，那就涉及 Linux 权限模型中的一个核心机制 setuid。&lt;/p&gt;
&lt;p&gt;在 Linux 中，有一类程序，普通用户可以运行，但运行时会临时拥有程序文件所有者的权限，通常是 root。&lt;/p&gt;
&lt;p&gt;最典型的例子，就是 passwd。用户修改密码，本质上需要写 &lt;code&gt;/etc/shadow&lt;/code&gt;，这个文件只有 root 能写。解决办法就是 passwd 程序本身由 root 拥有，并设置 setuid 位。用户运行它时，这个程序在执行过程中具备 root 权限。&lt;/p&gt;
&lt;p&gt;系统认为这些程序是可信的，因为普通用户无法修改它们。不过，也就是这一点信任模型被攻击者利用了。&lt;/p&gt;
&lt;p&gt;Copy Fail 的攻击思路在于，先把这类程序在内存里的缓存表示改掉，再让系统执行它。系统以为自己执行的是原来的可信程序，实际跑的是被临时动过手脚的内存版本，结果普通用户就可能拿到 root 了。&lt;/p&gt;
&lt;h2&gt;3. 第二个核心机制：splice&lt;/h2&gt;
&lt;p&gt;为什么系统会把只读内存数据当成可写入内容呢？&lt;/p&gt;
&lt;p&gt;更准确点说，其核心原理在于避免数据拷贝，直接传递对内存页的引用。&lt;/p&gt;
&lt;p&gt;Linux 读取文件时，通常不会每次都直接访问磁盘，因为磁盘很慢，但是内存很快，所以内核会把文件内容按页缓存到内存中，这就是 page cache。一个文件被读过之后，它的内容可能已经存在于 page cache 里。下一次再读这个文件时，内核可以直接从 page cache 取数据。&lt;/p&gt;
&lt;p&gt;此外，因为内核空间和用户空间是隔离的，而 page cache 位于内核管理的内存区域，所以当用户程序在程序调用 &lt;code&gt;read(fd, buf, len)&lt;/code&gt; 正常读取文件时，内核要做的就是从 page cache 找到对应文件页，再把这些字节复制到用户提供的 buf 里。&lt;/p&gt;
&lt;p&gt;数据路径是先从磁盘文件 → page cache，然后 page cache → 拷贝 → 用户空间 buffer。如果文件已经在 page cache 中，第一步可以省掉，但第二步仍然需要，因为这是内核和用户程序之间的安全边界。&lt;/p&gt;
&lt;p&gt;这一步的目的主要在于安全方面，那就是用户程序不能直接修改内核缓存页，但代价就是每次都要复制数据，性能会受影响。&lt;/p&gt;
&lt;p&gt;于是 Linux 提供了一类零拷贝机制，其中一个就是 &lt;code&gt;splice()&lt;/code&gt; 机制，目的是在内核内部搬运数据时尽量避免复制。&lt;/p&gt;
&lt;p&gt;在普通的 &lt;code&gt;read()&lt;/code&gt; 流程中，数据会从 page cache 拷贝到用户空间 buffer。如果程序只是想把文件内容转发给另一个内核对象，比如 pipe、socket 或加密接口，那么这次先拷贝到用户空间、再从用户空间交回内核，就很浪费。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;splice()&lt;/code&gt; 的设计目标就是绕过这个过程，它可以把文件内容直接接入一个 pipe，让后续内核模块继续消费这份数据。&lt;/p&gt;
&lt;p&gt;具体来讲，&lt;code&gt;splice()&lt;/code&gt; 会把 page cache 中的文件页挂到 pipe 的缓冲区结构上，这个结构叫做 &lt;code&gt;pipe_buffer&lt;/code&gt;。&lt;code&gt;pipe_buffer&lt;/code&gt; 里有一个字段指向某个 &lt;code&gt;struct page&lt;/code&gt;。&lt;code&gt;struct page&lt;/code&gt; 是 Linux 内核用来描述物理内存页的核心结构。对于文件读取场景来说，这个 &lt;code&gt;struct page&lt;/code&gt; 对应的就是 page cache 中保存文件内容的那一页。&lt;/p&gt;
&lt;p&gt;也就是说，本来正常的读取应该是「page cache → 拷贝 → 用户空间 buffer」，但 &lt;code&gt;splice()&lt;/code&gt; 没有拷贝 page cache，只把 page cache 挂在 &lt;code&gt;pipe_buffer&lt;/code&gt; 上，&lt;code&gt;pipe_buffer&lt;/code&gt; 本身也没有保存一份新的文件数据，其只保存了一个对 page cache 页面的引用。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;数据没有被复制，仅仅是被引用了。&lt;/strong&gt; 后续如果把这个 pipe 交给其他内核模块，比如网络或加密接口，这些模块操作的其实是原始 page cache 页面。&lt;/p&gt;
&lt;p&gt;这个设计本身是合理的。只要后续模块把这份数据当成只读输入，就不会有问题。&lt;/p&gt;
&lt;p&gt;但问题就在于，后续模块不一定只读。&lt;/p&gt;
&lt;h2&gt;4. 第三个核心机制：内核加密接口 AF_ALG&lt;/h2&gt;
&lt;p&gt;Linux 内核里有一套密码学框架，供内核模块使用。为了让用户态程序也能调用这些能力，Linux 提供了 AF_ALG。它是一种 socket 地址族，用户程序可以通过类似 socket 的方式，把数据交给内核做哈希、加密、解密或认证。&lt;/p&gt;
&lt;p&gt;Copy Fail 漏洞涉及的是其中的 AEAD 类型。&lt;/p&gt;
&lt;p&gt;AEAD 是「Authenticated Encryption with Associated Data」的缩写，中文可以理解为「带关联数据认证的加密」。它同时解决两个问题：数据加密和数据完整性认证。&lt;/p&gt;
&lt;p&gt;在 AEAD 里，数据通常分成两部分，一部分是需要加密的数据，也就是真正的明文或密文内容。另一部分叫 associated data，简称 AD。它不一定需要加密，但需要参与认证。比如在网络协议里，某些头部字段可以明文存在，但接收方仍然要确认这些字段没有被篡改。&lt;/p&gt;
&lt;p&gt;用户可以把数据提交给 AF_ALG，让内核执行加密、解密或认证操作，Copy Fail 利用的就是这个路径，把来自 &lt;code&gt;splice()&lt;/code&gt; 的 page cache 数据送进内核处理链。&lt;/p&gt;
&lt;h2&gt;5. 第四个核心机制：algif_aead&lt;/h2&gt;
&lt;p&gt;当数据进入 AF_ALG 后，会先交由 algif_aead 处理，其将用户通过 AF_ALG 提交的数据，封装成 AEAD 请求，然后交给具体实现，比如 authencesn。&lt;/p&gt;
&lt;p&gt;在正常设计中，加密流程是先输入 buffer（只读） → 内核处理 → 输出 buffer（可写）。&lt;/p&gt;
&lt;p&gt;但是，在 2017 年的一个内核改动中，algif_aead 引入了一种性能优化机制，叫 &lt;strong&gt;in-place 操作&lt;/strong&gt;，这个操作允许输入和输出共用同一块内存，从而减少一次拷贝。&lt;/p&gt;
&lt;p&gt;这个优化带来了一个明显的隐患，那就是，在 in-place 下，内核假设调用方提供的是&lt;strong&gt;可写 buffer&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;对于普通用户空间 buffer，这个假设是成立的。但在 Copy Fail 场景中，这块内存来自 &lt;code&gt;splice()&lt;/code&gt;，实际指向的是 page cache。&lt;/p&gt;
&lt;h2&gt;6. 第五个核心机制：authencesn（真正的漏洞点）&lt;/h2&gt;
&lt;p&gt;authencesn 可以拆开理解。authenc 表示「认证 + 加密」的组合模式，esn 表示 Extended Sequence Number，也就是扩展序列号，其比较常用于类似 IPsec ESP 这样的协议场景，协议需要同时处理加密数据、认证数据和序列号相关字段。&lt;/p&gt;
&lt;p&gt;在这个处理过程中，authencesn 需要构造认证输入。为了让底层哈希或认证算法计算正确，它会在某个位置写入一个序列号字段。这个字段是 4 字节，也就是 32 bit。位置大致是：&lt;code&gt;offset = 关联数据长度 + 加密数据长度&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;在原本设计中，这个写入应该落在输出 buffer 或临时工作区里。因为输出 buffer 是可写的，所以写 4 字节没有问题。&lt;/p&gt;
&lt;p&gt;关键在于，algif_aead 启用了 in-place 处理，在 in-place 的优化下，&lt;strong&gt;输入 buffer == 输出 buffer&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;如果这块 buffer 是普通用户内存，写入仍然可控。如果这块 buffer 来自 &lt;code&gt;splice()&lt;/code&gt; 机制，它实际指向 &lt;code&gt;pipe_buffer&lt;/code&gt;，而 &lt;code&gt;pipe_buffer&lt;/code&gt; 是对 page cache 页面的引用。于是 authencesn 的 4 字节写入就落到了文件缓存页 page cache 上。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;这就是漏洞真正发生的地方&lt;/strong&gt;，源自于内核假设 buffer 可写，但实际上传入的是只读 page cache，由此导致了写操作污染文件缓存，造成越权写入。&lt;/p&gt;
&lt;p&gt;其中，还有一个隐蔽的细节，那就是，这个 4 字节的写入，发生在 authencesn 对认证 tag 做校验&lt;strong&gt;之前&lt;/strong&gt;。也就是说，即使攻击者提交的数据无法通过认证、内核最终返回 EBADMSG 报告解密失败，page cache 的污染也已经完成了。攻击者不需要构造一个合法的 AEAD 密文，失败的解密请求本身就足以触发写入。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;一句话总结&lt;/strong&gt;：内核以为自己在写一个可写的 AEAD 输出缓冲区，实际写到的是只读文件的 page cache。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;7. 完整攻击链&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;flowchart TB
    subgraph 攻击准备
        A[&quot;&amp;lt;b&amp;gt;setuid 程序&amp;lt;/b&amp;gt;&amp;lt;br/&amp;gt;（root 拥有，普通用户只读）&quot;]
    end

    subgraph 内核内存层
        B[&quot;&amp;lt;b&amp;gt;page cache&amp;lt;/b&amp;gt;&amp;lt;br/&amp;gt;（文件在内存中的缓存页）&quot;]
        C[&quot;&amp;lt;b&amp;gt;pipe_buffer&amp;lt;/b&amp;gt;&amp;lt;br/&amp;gt;（持有 page cache 页面引用）&quot;]
    end

    subgraph 内核加密框架
        D[&quot;&amp;lt;b&amp;gt;AF_ALG&amp;lt;/b&amp;gt;&amp;lt;br/&amp;gt;（用户态加密接口）&quot;]
        E[&quot;&amp;lt;b&amp;gt;algif_aead&amp;lt;/b&amp;gt;&amp;lt;br/&amp;gt;（in-place 优化）&amp;lt;br/&amp;gt;输入 buffer == 输出 buffer&quot;]
        F[&quot;&amp;lt;b&amp;gt;authencesn&amp;lt;/b&amp;gt;&amp;lt;br/&amp;gt;（AEAD 具体实现）&amp;lt;br/&amp;gt;写入 4 字节序列号&quot;]
    end

    subgraph 提权结果
        G[&quot;&amp;lt;b&amp;gt;page cache 被污染&amp;lt;/b&amp;gt;&amp;lt;br/&amp;gt;（越权写入成功）&quot;]
        H[&quot;&amp;lt;b&amp;gt;执行被篡改的 setuid 程序&amp;lt;/b&amp;gt;&amp;lt;br/&amp;gt;（以 root 身份运行）&quot;]
    end

    A --&amp;gt;|&quot;① splice() 传递引用&quot;| B
    B --&amp;gt;|&quot;② 引用挂入 pipe&quot;| C
    C --&amp;gt;|&quot;③ 送入 AF_ALG&quot;| D
    D --&amp;gt;|&quot;④ 封装 AEAD 请求&quot;| E
    E --&amp;gt;|&quot;⑤ in-place 零拷贝&quot;| F
    F --&amp;gt;|&quot;⑥ 写序列号到只读页&quot;| G
    G --&amp;gt;|&quot;⑦ 执行内存中被改写的程序&quot;| H

    style A fill:#f9f,stroke:#333
    style H fill:#f66,stroke:#333
    style F fill:#ff9,stroke:#333
    style G fill:#ff9,stroke:#333
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;所以，整个攻击过程大概就是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;攻击者首先选择一个自己可以读取、但没有写权限的文件。这个文件可能是某个 setuid 程序。普通权限模型下，攻击者只能读它，不能改它。&lt;/li&gt;
&lt;li&gt;攻击者通过 &lt;code&gt;splice()&lt;/code&gt; 机制把这个文件的一部分内容接入 pipe。此时 pipe 里的 &lt;code&gt;pipe_buffer&lt;/code&gt; 指向的是该文件在 page cache 中对应的 &lt;code&gt;struct page&lt;/code&gt;。在这个地方，数据没有复制，pipe 持有的是页面引用。&lt;/li&gt;
&lt;li&gt;攻击者把这个 pipe 中的数据交给 AF_ALG。在内核看来，这只是一段待处理的 AEAD 输入数据。&lt;/li&gt;
&lt;li&gt;algif_aead 按照 in-place 逻辑处理它。&lt;/li&gt;
&lt;li&gt;这里出问题的关键是，内核没有把来自 &lt;code&gt;splice()&lt;/code&gt; 的 page cache 页面和普通可写用户 buffer 区分开来处理，导致后续的悲剧——越权写入。&lt;/li&gt;
&lt;li&gt;AEAD 请求进入 authencesn。authencesn 为了构造认证数据，在计算出来的位置写入 4 字节的序列号字段。这个位置理论上属于可写输出区域，但是，由于前面的悲剧，导致这次写入实际上落在了 &lt;code&gt;pipe_buffer&lt;/code&gt; 引用的 page cache 页面上。&lt;/li&gt;
&lt;li&gt;结果就是，原本只读文件在内存中的缓存页被改了 4 个字节。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;不要小瞧四个字节&lt;/strong&gt;，在二进制程序里，少量字节就可能改变指令、跳转、条件判断或数据结构。如果攻击者能控制文件偏移和写入位置，就可能把 setuid 程序在内存中的行为改成自己想要的样子。此外，攻击者可以重复发起请求，每次写入不同偏移，从而对 setuid 程序的内存镜像做多处精准修改。&lt;/p&gt;
&lt;p&gt;最后，攻击者执行这个 setuid 程序。系统仍然认为它是 root 拥有的可信程序，因为磁盘文件没有被改，权限也没有变。但执行时命中的内容已经是 page cache 中被越权修改的版本，于是攻击者就有机会获得 root 权限。&lt;/p&gt;
&lt;h2&gt;8. Living off the Land&lt;/h2&gt;
&lt;p&gt;整个过程中，攻击者没有写磁盘，没有改变文件权限，也没有留下传统意义上的文件篡改痕迹，这就是所谓的 &lt;strong&gt;Living off the Land（LotL）&lt;/strong&gt;，属于不修改磁盘文件的内存级攻击方式，也不会触发依赖文件系统事件的安全监控工具。&lt;/p&gt;
&lt;h2&gt;9. 五条机制串联总结&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph 正常路径
        N1[&quot;文件&quot;] --&amp;gt;|read| N2[&quot;page cache&quot;]
        N2 --&amp;gt;|拷贝数据| N3[&quot;用户 buffer&amp;lt;br/&amp;gt;（可写）&quot;]
        N3 --&amp;gt;|加密请求| N4[&quot;AEAD 处理&quot;]
        N4 --&amp;gt;|写入序列号| N5[&quot;用户 buffer&amp;lt;br/&amp;gt;（安全）&quot;]
    end

    subgraph Copy Fail 攻击路径
        P1[&quot;setuid 文件&quot;] --&amp;gt;|splice| P2[&quot;page cache&quot;]
        P2 --&amp;gt;|传递引用| P3[&quot;pipe_buffer&amp;lt;br/&amp;gt;（指向只读页）&quot;]
        P3 --&amp;gt;|AF_ALG| P4[&quot;in-place 处理&quot;]
        P4 --&amp;gt;|写入序列号| P5[&quot;page cache&amp;lt;br/&amp;gt;（越权写入！）&quot;]
    end

    style N5 fill:#9f9,stroke:#333
    style P5 fill:#f66,stroke:#333
&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;机制&lt;/th&gt;
&lt;th&gt;作用&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;setuid&lt;/td&gt;
&lt;td&gt;使得普通用户程序在执行时以 root 权限运行&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;splice()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;使得传递过程为 page cache 页面的引用，而非其拷贝&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AF_ALG&lt;/td&gt;
&lt;td&gt;把用户提供的数据交给内核加密框架处理&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;algif_aead&lt;/td&gt;
&lt;td&gt;in-place 优化假设输入和输出可以共用一个可写内存&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;authencesn&lt;/td&gt;
&lt;td&gt;实现会在处理过程中写入一个 4 字节字段&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;这样下来，实现结果就是：对于一个普通用户，authencesn 修改了该程序在 page cache 中的内存映像，并以 root 权限执行了这个程序。&lt;/p&gt;
&lt;h2&gt;10. 防护措施&lt;/h2&gt;
&lt;p&gt;防护上最核心的就是&lt;strong&gt;更新内核&lt;/strong&gt;，取消 algif_aead 的 in-place 逻辑，恢复输入和输出分离，避免写入落在输入 buffer 上。&lt;/p&gt;
&lt;p&gt;如果无法升级，那就先限制 AF_ALG 接口，禁用相关模块。&lt;/p&gt;
&lt;p&gt;当然了，最一劳永逸的治本方法，自然还是打上内核补丁。&lt;/p&gt;
</content:encoded></item><item><title>Claude Code 创始人 Boris Cherny：我已半年没手写一行代码</title><link>https://www.hehonglei.cn/posts/boris-cherny-how-he-uses-claude/</link><guid isPermaLink="true">https://www.hehonglei.cn/posts/boris-cherny-how-he-uses-claude/</guid><description>Claude Code 之父 Boris Cherny 自 2024 年 11 月起 100% 由 AI 生成代码，日发 150 个 PR，用 iPhone 调度数百个 Agent。本文整理了他的工作流、设计哲学与对编程行业未来的判断。</description><pubDate>Fri, 08 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;1. 他是谁&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Boris Cherny&lt;/strong&gt;，34 岁，Anthropic 公司 Claude Code 的创始人与负责人，也是该产品的第一位工程师。&lt;/p&gt;
&lt;p&gt;他的背景并不算&quot;正统&quot;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;自学编程，加州大学圣地亚哥分校经济学专业辍学&lt;/li&gt;
&lt;li&gt;著有《Programming TypeScript》一书&lt;/li&gt;
&lt;li&gt;在 Meta 工作近 7 年，负责全公司代码质量&lt;/li&gt;
&lt;li&gt;2024 年 9 月加入 Anthropic，开始 hack Claude Code 原型&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;一个有趣的插曲：2025 年 7 月他曾短暂跳槽至竞争对手 Cursor（任首席架构师），不到两周即回归 Anthropic，理由是&quot;100% 因为想念使命&quot;。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;2. 编程已被&quot;解决&quot;了？&lt;/h2&gt;
&lt;p&gt;Boris 在 2026 年红杉 AI Ascent 大会上抛出了一个大胆的断言：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;编程已被解决。至少在 TypeScript / React 技术栈层面。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;自 &lt;strong&gt;2024 年 11 月以来，他没有手写过一行代码&lt;/strong&gt;，100% 由 AI 生成。他认为当前行业整体约有 &lt;strong&gt;50% 的编程已被解决&lt;/strong&gt;，剩余部分受限于超大规模遗留系统、低资源语言生态等。&lt;/p&gt;
&lt;p&gt;但他强调这并不意味着程序员会被淘汰——而是&lt;strong&gt;编程的门槛正在消失&lt;/strong&gt;，角色从&quot;写代码的人&quot;转变为&quot;决定要解决什么问题的人&quot;。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;3. 他如何使用 Claude Code&lt;/h2&gt;
&lt;h3&gt;3.1 极致并行：手机 + 数百个 Agent&lt;/h3&gt;
&lt;p&gt;Boris 的工作方式令人咋舌：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;主要工作设备是 iPhone&lt;/strong&gt;，通过 iOS 版 Claude 应用调度一切&lt;/li&gt;
&lt;li&gt;每日发起 &lt;strong&gt;10–150 个 PR&lt;/strong&gt;，单日最高记录 150 个&lt;/li&gt;
&lt;li&gt;同时并行运行 &lt;strong&gt;数百个 AI Agent&lt;/strong&gt;，每晚数千个执行深层任务&lt;/li&gt;
&lt;li&gt;本地终端同时开 &lt;strong&gt;5 个 tab&lt;/strong&gt;，Web 端再加 &lt;strong&gt;5–10 个会话&lt;/strong&gt;，轮流在各环境启动 Claude Code&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;他的 Ansible 和 Nginx 配置全是 Claude 生成的。&quot;从去年开始，这些我全都看不懂了。&quot;&lt;/p&gt;
&lt;h3&gt;3.2 Loop 模式：他最爱的功能&lt;/h3&gt;
&lt;p&gt;Loop 是基于 cron 的定时智能体调度机制，Boris 已部署数十个长期运行的 Loop 实例：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;PR 看护&lt;/strong&gt;：自动修复 CI 冲突、自动 rebase&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CI 健康维护&lt;/strong&gt;：自动修复 flaky tests&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;社交监听&lt;/strong&gt;：每 30 分钟抓取 Twitter 反馈并自动聚类整理&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;# 每 30 分钟检查一次 CI 状态并修复失败的测试
/loop 30m 检查最近的 CI 运行结果，如果存在 flaky test，自动修复并提 PR
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.3 先计划，再执行&lt;/h3&gt;
&lt;p&gt;Boris 的 session 80% 从 &lt;strong&gt;Plan Mode&lt;/strong&gt; 起步（快速按两次 Shift+Tab 进入）：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;与 Claude 反复沟通需求，直到生成满意的计划&lt;/li&gt;
&lt;li&gt;切换到自动执行模式，让 Claude 完成所有代码修改&lt;/li&gt;
&lt;li&gt;审查结果，必要时再迭代&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;不过他也提到，随着模型能力提升，&quot;一个月后他就不再需要 plan mode 了&quot;——模型会在思考过程中自行规划。&lt;/p&gt;
&lt;h3&gt;3.4 多 Agent 协作通信&lt;/h3&gt;
&lt;p&gt;最颠覆认知的一点：他的 Claude 会通过 &lt;strong&gt;Slack 直接给同事发消息&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;比如看到 &lt;code&gt;git blame&lt;/code&gt; 里有人最近改过相关代码，Claude 会自动发 Slack 消息询问澄清问题。Agent 之间可以自主组队、认领任务、分工协作。Boris 认为这是下一代编程工具的核心能力——&quot;让多个 AI 像一个团队一样工作&quot;。&lt;/p&gt;
&lt;h3&gt;3.5 共享记忆：CLAUDE.md&lt;/h3&gt;
&lt;p&gt;团队在 Git 仓库中维护共享的 &lt;code&gt;CLAUDE.md&lt;/code&gt;，记录开发命令、代码风格偏好、项目架构约定等。&lt;/p&gt;
&lt;p&gt;关键的机制是：&lt;strong&gt;每当发现 Claude 犯错，就在 PR 评论中 @Claude，让它自动更新 CLAUDE.md&lt;/strong&gt;。这样错误只会犯一次，知识在团队中持续沉淀。&lt;/p&gt;
&lt;h3&gt;3.6 Routines：离线也能跑&lt;/h3&gt;
&lt;p&gt;Routines 是服务端常驻例程，可在设备离线状态下持续运行。意味着即使 Boris 睡觉或坐飞机，他的 Agent 仍在工作——早上醒来时 PR 已经等着审查了。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;4. Claude Code 的发展时间线&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;时间&lt;/th&gt;
&lt;th&gt;里程碑&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;2024 年 9 月&lt;/td&gt;
&lt;td&gt;Boris 加入 Anthropic，开始 hack 原型&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2025 年 2 月&lt;/td&gt;
&lt;td&gt;Claude Code 正式上线，可用率仅约 10%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2025 年 5 月&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Opus 4&lt;/strong&gt; 发布，代码生成可用率跃升至 30%，产品进入指数增长&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2025 年 7 月&lt;/td&gt;
&lt;td&gt;Boris 短暂跳槽 Cursor，两周后回归&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2025 年 11 月&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Opus 4.5&lt;/strong&gt; 发布，AI 在软件工程领域达到人类水平；Boris 从此停止手写代码&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026 年&lt;/td&gt;
&lt;td&gt;Claude Code 年化收入达 &lt;strong&gt;300 亿美元&lt;/strong&gt;，推动 Anthropic 营收反超 OpenAI&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;5. 他的设计哲学&lt;/h2&gt;
&lt;h3&gt;5.1 为六个月后的模型做产品&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;我们不是为今天的模型做产品，而是为六个月后的模型做产品。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这是 Boris 最核心的产品理念。他拒绝为当前模型缺陷打补丁——&quot;补丁等新模型出来后直接变成负资产&quot;。与其把时间花在修复当前模型的局限性上，不如专注于模型能力溢出后仍然有竞争力的产品框架。&lt;/p&gt;
&lt;h3&gt;5.2 模型 vs 编排层&lt;/h3&gt;
&lt;p&gt;模型与产品设计的权重约 &lt;strong&gt;50/50&lt;/strong&gt;，但长期看，模型自身能力提升将降低编排层的必要性。&lt;/p&gt;
&lt;p&gt;他甚至预言 Claude Code 一年后可能&lt;strong&gt;只剩 100 行代码&lt;/strong&gt;——因为模型会越来越自主地做正确的事，不需要复杂的外部逻辑来引导它。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;6. 对行业未来的判断&lt;/h2&gt;
&lt;h3&gt;两类被削弱的护城河&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;转换成本&lt;/strong&gt;：跨平台迁移将自动化，锁定效应减弱&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;流程优势&lt;/strong&gt;：AI 可复现并优化复杂业务流程，曾经的&quot;独门运营&quot;不再稀缺&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;未来十年的颠覆&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;未来十年颠覆性软件公司数量将是过去十年的 &lt;strong&gt;10 倍&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;小团队借助 AI 可与大厂正面对抗&lt;/li&gt;
&lt;li&gt;&quot;软件工程师&quot;头衔可能消失，取而代之的是 &lt;strong&gt;Builder&lt;/strong&gt;：定义系统目标、审查输出、决定要解决什么问题&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;编程范式的根本转变&lt;/h3&gt;
&lt;p&gt;从&quot;人写代码、AI 辅助&quot;转向 &lt;strong&gt;&quot;AI 写代码、人做决策&quot;&lt;/strong&gt;。开发者的核心能力不再是语法熟练度，而是问题定义能力、系统设计品味、以及判断力。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;7. 启示&lt;/h2&gt;
&lt;p&gt;Boris Cherny 的工作方式不是科幻——它是正在发生的现实。他用自己的产品证明了：当一个工程师真正信任 AI、并建立起高效的人机协作体系后，生产力的天花板远比想象的高。&lt;/p&gt;
&lt;p&gt;几条可以立刻借鉴的实践：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;创建项目的 CLAUDE.md&lt;/strong&gt;，让 AI 每次都带着正确的上下文工作&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;每次发现 AI 犯错，写入 CLAUDE.md&lt;/strong&gt;——错误只犯一次&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;尝试 Loop 模式&lt;/strong&gt;自动化重复性任务&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;从 Plan Mode 开始复杂任务&lt;/strong&gt;，减少返工&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;接受角色转变&lt;/strong&gt;：从&quot;写代码的人&quot;变成&quot;定义问题和审查输出的人&quot;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;编程的门槛正在消失，但定义问题的能力比以往任何时候都更重要。&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>Claude Code 安装与使用教程：从零开始的 AI 编程助手</title><link>https://www.hehonglei.cn/posts/claude-code-install-guide/</link><guid isPermaLink="true">https://www.hehonglei.cn/posts/claude-code-install-guide/</guid><description>详细介绍 Claude Code 的安装方法、基础使用技巧与进阶工作流，帮助你快速将 AI 编程助手融入日常开发。</description><pubDate>Fri, 08 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;1. 什么是 Claude Code&lt;/h2&gt;
&lt;p&gt;Claude Code 是 Anthropic 推出的&lt;strong&gt;命令行 AI 编程助手&lt;/strong&gt;，与 Copilot（IDE 插件）或 Cursor（AI IDE）不同，它直接在终端中运行，能够理解整个项目上下文，执行文件操作、运行命令、管理 Git 等。&lt;/p&gt;
&lt;p&gt;它的核心差异在于：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;终端原生&lt;/strong&gt;：不需要离开命令行，适合习惯 CLI 的开发者&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;项目级理解&lt;/strong&gt;：能读取整个项目的文件结构和代码逻辑&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;自主行动&lt;/strong&gt;：不仅能回答问题，还能直接编辑文件、运行测试、提交代码&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;2. 安装&lt;/h2&gt;
&lt;h3&gt;2.1 前置条件&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Node.js 18 或更高版本&lt;/li&gt;
&lt;li&gt;一个 Anthropic API Key（在 &lt;a href=&quot;https://console.anthropic.com&quot;&gt;console.anthropic.com&lt;/a&gt; 获取）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2.2 全局安装&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;npm install -g @anthropic-ai/claude-code
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;安装完成后验证：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;claude --version
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2.3 配置 API Key&lt;/h3&gt;
&lt;p&gt;将 API Key 设置为环境变量：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# macOS / Linux — 添加到 ~/.bashrc 或 ~/.zshrc
export ANTHROPIC_API_KEY=&quot;sk-ant-xxx&quot;

# Windows PowerShell
$env:ANTHROPIC_API_KEY=&quot;sk-ant-xxx&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;或者使用 Claude Code 自带的登录方式：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;claude login
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这会打开浏览器引导你完成 OAuth 认证，无需手动处理 API Key。&lt;/p&gt;
&lt;h3&gt;2.4 更新&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;npm update -g @anthropic-ai/claude-code
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;3. 基础使用&lt;/h2&gt;
&lt;h3&gt;3.1 启动&lt;/h3&gt;
&lt;p&gt;在项目目录下运行：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;claude
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;你会看到一个交互式终端界面，可以直接用自然语言与 Claude 交流。&lt;/p&gt;
&lt;h3&gt;3.2 常用指令&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 初始化项目配置文件（生成 CLAUDE.md）
claude init

# 查看当前配置
claude config

# 更新到最新版本
claude update
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.3 典型工作流&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;代码审查&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; 审查当前分支的改动，重点关注安全问题
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Claude 会读取 &lt;code&gt;git diff&lt;/code&gt;，分析代码变更，指出潜在的安全隐患。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Bug 修复&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; 用户反馈登录后页面白屏，帮我排查原因
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Claude 会搜索相关文件、检查组件逻辑，定位问题并直接修复。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;功能开发&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; 在 API 中添加一个获取用户收藏列表的接口，包含分页
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Claude 会分析现有路由结构，生成路由定义、控制器逻辑和数据库查询。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;4. 进阶技巧&lt;/h2&gt;
&lt;h3&gt;4.1 CLAUDE.md 文件&lt;/h3&gt;
&lt;p&gt;在项目根目录创建 &lt;code&gt;CLAUDE.md&lt;/code&gt;，告诉 Claude 关于项目的关键信息：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 项目名称

## 技术栈
- 前端：React 18 + TypeScript + Tailwind
- 后端：Go + PostgreSQL
- 部署：Docker + K8s

## 代码规范
- 使用 Prettier 格式化，单引号，无分号
- 组件命名使用 PascalCase
- API 路由使用 kebab-case

## 注意事项
- 不要直接修改生成的代码文件
- 测试使用 Vitest，不要用 Jest
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;有了这份文件，Claude 每次启动时都会自动加载，减少反复解释。&lt;/p&gt;
&lt;h3&gt;4.2 权限控制&lt;/h3&gt;
&lt;p&gt;Claude Code 默认对敏感操作（如网络请求、文件写入）会请求确认。你可以通过 &lt;code&gt;/permissions&lt;/code&gt; 管理权限级别。&lt;/p&gt;
&lt;h3&gt;4.3 管道模式&lt;/h3&gt;
&lt;p&gt;Claude 也支持管道输入，适合脚本场景：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat error.log | claude &quot;分析这些日志，找出关键错误&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.4 会话管理&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 恢复上一次会话
claude --continue

# 以特定会话 ID 继续
claude --resume &amp;lt;session-id&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;5. Claude Code vs 其他 AI 编程工具&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;维度&lt;/th&gt;
&lt;th&gt;Claude Code&lt;/th&gt;
&lt;th&gt;GitHub Copilot&lt;/th&gt;
&lt;th&gt;Cursor&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;运行环境&lt;/td&gt;
&lt;td&gt;终端&lt;/td&gt;
&lt;td&gt;IDE 插件&lt;/td&gt;
&lt;td&gt;AI IDE&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;交互方式&lt;/td&gt;
&lt;td&gt;对话式&lt;/td&gt;
&lt;td&gt;代码补全 + 聊天&lt;/td&gt;
&lt;td&gt;对话式&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;文件操作&lt;/td&gt;
&lt;td&gt;可写&lt;/td&gt;
&lt;td&gt;只能写代码&lt;/td&gt;
&lt;td&gt;可写&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;命令执行&lt;/td&gt;
&lt;td&gt;支持&lt;/td&gt;
&lt;td&gt;不支持&lt;/td&gt;
&lt;td&gt;支持&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;上下文范围&lt;/td&gt;
&lt;td&gt;全项目&lt;/td&gt;
&lt;td&gt;当前文件 + 打开文件&lt;/td&gt;
&lt;td&gt;全项目&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;定价&lt;/td&gt;
&lt;td&gt;API 按量计费&lt;/td&gt;
&lt;td&gt;$10/月起&lt;/td&gt;
&lt;td&gt;$20/月起&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Claude Code 特别适合以下场景：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;需要多文件重构的大型任务&lt;/li&gt;
&lt;li&gt;日常重度使用终端的开发者&lt;/li&gt;
&lt;li&gt;希望 AI 自主处理&quot;跑测试 → 修复 → 再跑&quot;循环&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;6. 常见问题&lt;/h2&gt;
&lt;h3&gt;6.1 国内网络问题&lt;/h3&gt;
&lt;p&gt;如果在国内访问 Anthropic API 遇到网络问题，可以：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;使用 API 代理地址，设置环境变量 &lt;code&gt;ANTHROPIC_BASE_URL&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;配置 HTTPS 代理：&lt;code&gt;export HTTPS_PROXY=http://127.0.0.1:7890&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;6.2 成本控制&lt;/h3&gt;
&lt;p&gt;Claude Code 每次对话都会消耗 API token。控制成本的建议：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在 &lt;code&gt;.claude/settings.json&lt;/code&gt; 中设置最大 token 限制&lt;/li&gt;
&lt;li&gt;使用短会话，任务完成后及时 &lt;code&gt;exit&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;对于简单问题，直接在代码中加注释而不是启动完整会话&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;6.3 国内镜像加速&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# npm 安装时使用国内镜像
npm install -g @anthropic-ai/claude-code --registry=https://registry.npmmirror.com
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;7. 总结&lt;/h2&gt;
&lt;p&gt;Claude Code 代表了 AI 编程工具从&quot;IDE 内的辅助插件&quot;到&quot;终端中的自主助手&quot;的转变。它更强的项目理解能力和自主行动权限，让开发者能够把更多精力放在架构设计而非重复编码上。&lt;/p&gt;
&lt;p&gt;安装只需两条命令，值得每个习惯命令行的开发者尝试。&lt;/p&gt;
</content:encoded></item><item><title>Trae 请你喝咖啡：字节跳动 AI IDE 的诚意与野心</title><link>https://www.hehonglei.cn/posts/trae-coffee-event/</link><guid isPermaLink="true">https://www.hehonglei.cn/posts/trae-coffee-event/</guid><description>字节跳动旗下 AI IDE Trae 推出&quot;请你喝咖啡&quot;活动，新用户注册即送咖啡券。本文将带你深入了解 Trae 的产品定位、核心功能，以及它如何在 AI 编程工具的红海中突围。</description><pubDate>Wed, 06 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;1. 引言&lt;/h2&gt;
&lt;p&gt;2026 年 AI 编程工具的竞争已进入白热化阶段。Cursor、GitHub Copilot、Claude Code 等产品各有拥趸，而字节跳动旗下的 &lt;strong&gt;Trae&lt;/strong&gt; 则以一记&quot;接地气&quot;的营销切入市场——&lt;strong&gt;新用户注册就送咖啡券&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;这不仅仅是薅羊毛的机会，更值得关注的是 Trae 背后的产品逻辑与 AI 编程工具的未来走向。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;2. Trae 是什么？&lt;/h2&gt;
&lt;p&gt;Trae 是字节跳动推出的 &lt;strong&gt;AI 原生集成开发环境（IDE）&lt;/strong&gt;，基于 VS Code 内核深度定制，内置了自研的 AI 编程助手。它不像 Copilot 那样以插件形式存在，而是从底层将 AI 能力融入编辑器的每一个角落。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;Trae&lt;/th&gt;
&lt;th&gt;Cursor&lt;/th&gt;
&lt;th&gt;GitHub Copilot&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;底层基础&lt;/td&gt;
&lt;td&gt;VS Code 内核&lt;/td&gt;
&lt;td&gt;VS Code 内核&lt;/td&gt;
&lt;td&gt;VS Code 插件&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI 模型&lt;/td&gt;
&lt;td&gt;豆包大模型 + 多模型支持&lt;/td&gt;
&lt;td&gt;多模型支持&lt;/td&gt;
&lt;td&gt;GPT-4o 系列&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;中文体验&lt;/td&gt;
&lt;td&gt;原生中文优化&lt;/td&gt;
&lt;td&gt;一般&lt;/td&gt;
&lt;td&gt;一般&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;定价模式&lt;/td&gt;
&lt;td&gt;基础免费 + 付费计划&lt;/td&gt;
&lt;td&gt;免费 + Pro $20/月&lt;/td&gt;
&lt;td&gt;免费 + Pro $10/月&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;3. &quot;请你喝咖啡&quot;活动解析&lt;/h2&gt;
&lt;h3&gt;3.1 活动内容&lt;/h3&gt;
&lt;p&gt;活动期间，新用户完成注册即可获得一张 &lt;strong&gt;咖啡兑换券&lt;/strong&gt;。看似简单的促销，背后是字节跳动惯用的增长策略——用极低的获客成本撬动用户的首购行为。&lt;/p&gt;
&lt;h3&gt;3.2 为什么是咖啡？&lt;/h3&gt;
&lt;p&gt;程序员和咖啡，几乎是绑定关系。一杯咖啡的价格（15-30 元）恰好卡在一个微妙的心理价位：不高到让用户觉得&quot;肯定有套路&quot;，也不低到毫无感知。这种行为经济学上的精准定价，颇有字节产品的风格。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;4. Trae 的核心亮点&lt;/h2&gt;
&lt;h3&gt;4.1 多模型自由切换&lt;/h3&gt;
&lt;p&gt;Trae 内置了豆包大模型、DeepSeek、Claude 等主流 AI 模型，用户可以在不同场景下自由切换。比如写业务逻辑用豆包（上下文窗口大），做复杂算法推理用 Claude。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Trae 的 AI 面板可以在编辑器中直接对话
# 支持跨文件上下文感知

def fibonacci(n: int) -&amp;gt; int:
    &quot;&quot;&quot;Trae 可以帮你一键生成这个函数的文档和测试&quot;&quot;&quot;
    if n &amp;lt;= 1:
        return n
    return fibonacci(n - 1) + fibonacci(n - 2)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.2 中文生态深度优化&lt;/h3&gt;
&lt;p&gt;作为国内团队打造的产品，Trae 对中文技术文档、中文注释、中文问答的理解能力明显优于海外竞品。对于习惯用中文交流的开发者来说，这是一个实打实的效率提升。&lt;/p&gt;
&lt;h3&gt;4.3 字节内部验证&lt;/h3&gt;
&lt;p&gt;Trae 并非凭空出现——它在字节内部已经大规模使用了近两年，经过数万名工程师的真实场景验证。这意味着它的代码补全和对话质量经过了充分的&quot;实战&quot;打磨。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;5. AI IDE 的拐点&lt;/h2&gt;
&lt;p&gt;2026 年 AI IDE 领域正在经历一个关键转折：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;从辅助到主导&lt;/strong&gt;：AI 不再是&quot;帮你写一行代码&quot;，而是&quot;帮你完成一个功能模块&quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;从单一模型到多模型协作&lt;/strong&gt;：不同模型擅长不同任务，灵活编排成为刚需&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;从英文优先到多语言平等&lt;/strong&gt;：中文、日文、韩文等非英语开发者的需求被正视&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Trae 的&quot;咖啡策略&quot;也许只是营销手段，但它背后的产品方向——&lt;strong&gt;多模型、多语言、原生 AI 集成&lt;/strong&gt;——代表了 AI IDE 的主流趋势。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;6. 总结&lt;/h2&gt;
&lt;p&gt;不妨注册一个 Trae 账号，领杯咖啡，顺便体验一下字节的 AI 编程能力。即便最终你回到了自己熟悉的 IDE，这一杯咖啡的成本，换来的可能是对下一个编程时代的提前感知。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;咖啡会凉，但好工具的热度不会。&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>Node.js 26 正式发布：Temporal API 默认启用，最后一个奇偶版本</title><link>https://www.hehonglei.cn/posts/nodejs-26-release/</link><guid isPermaLink="true">https://www.hehonglei.cn/posts/nodejs-26-release/</guid><description>Node.js 26 正式发布，Temporal API 默认可用，V8 14.6、Undici 8、Map Upsert 正式落地。这是最后一个沿用奇偶策略的主版本，从 Node.js 27 开始将改为年度发布节奏，每个版本都将进入 LTS。</description><pubDate>Tue, 05 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;1. 引言&lt;/h2&gt;
&lt;p&gt;2026年5月5日，Node.js 团队正式发布了 &lt;strong&gt;Node.js 26.0.0&lt;/strong&gt;（Current），由核心开发者 Rafael Gonzaga 在 GitHub PR 中宣布。这个版本不仅是技术栈的一次重大升级，更标志着一个时代的终结——&lt;strong&gt;它是最后一个沿用奇偶版本策略的主版本&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;Node.js 26 的核心亮点是 &lt;strong&gt;Temporal API 默认可用&lt;/strong&gt;——无需任何实验性标志即可使用现代日期/时间 API，彻底告别 &lt;code&gt;Date&lt;/code&gt; 对象的种种痛点。与此同时，Node.js 团队正式宣布：从 &lt;strong&gt;Node.js 27&lt;/strong&gt; 开始，将改为&lt;strong&gt;每年一个主版本&lt;/strong&gt;的发布节奏，每个版本都将进入 LTS 阶段。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;2. 核心定位：承前启后的「终章」&lt;/h2&gt;
&lt;h3&gt;2.1 最后一个奇偶版本&lt;/h3&gt;
&lt;p&gt;自 Node.js 诞生以来，一直遵循&lt;strong&gt;奇偶版本策略&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;偶数版本&lt;/strong&gt;（22、24、26）→ LTS，推荐生产使用&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;奇数版本&lt;/strong&gt;（23、25）→ Current 实验版，不进入 LTS，新功能试水&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;研发运营了十余年的这套规则，将在 Node.js 26 之后画上句号。&lt;/p&gt;
&lt;h3&gt;2.2 为什么需要改变？&lt;/h3&gt;
&lt;p&gt;Node.js 官方博客解释了这次变革的四大驱动力：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;原因&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;奇数版本采用率极低&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;大多数用户和企业完全跳过奇数版本，等待 LTS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;社区长期困惑&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;新开发者对&quot;用偶数、跳奇数&quot;的规则感到困惑&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;维护者不可持续性&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;志愿者为主的团队需同时维护 4-5 个活跃版本线，负担过重&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;企业可预测性&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;固定的年度节奏让升级规划更为简单&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;2.3 Node.js 26 发布计划&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;里程碑&lt;/th&gt;
&lt;th&gt;时间&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;26.0.0 Current 发布&lt;/td&gt;
&lt;td&gt;2026年5月5日&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;进入 LTS&lt;/td&gt;
&lt;td&gt;2026年10月&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;进入维护期&lt;/td&gt;
&lt;td&gt;2027年10月&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;End of Life&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;2029年4月&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;3. Temporal API：现代日期时间的元年&lt;/h2&gt;
&lt;h3&gt;3.1 为什么需要 Temporal？&lt;/h3&gt;
&lt;p&gt;JavaScript 的 &lt;code&gt;Date&lt;/code&gt; 对象自 1995 年诞生以来，一直是开发者最频繁抱怨的 API 之一：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;月份从 0 开始&lt;/strong&gt;（0 = 一月），几乎每个人都踩过这个坑&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可变对象&lt;/strong&gt;：修改一个 Date 实例可能产生难以追踪的副作用&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;时区处理弱&lt;/strong&gt;：缺乏原生的时区感知能力&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;日期运算复杂&lt;/strong&gt;：计算&quot;30天后的日期&quot;需要手动处理跨月/跨年&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Temporal API 彻底解决了这些问题。在 Node.js 26 中，&lt;strong&gt;它已全面可用，无需任何实验性标志&lt;/strong&gt;。&lt;/p&gt;
&lt;h3&gt;3.2 核心类型体系&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;Temporal
├── PlainDate          — 纯日期（无时间、无时区）
├── PlainTime          — 纯时间（无日期、无时区）
├── PlainDateTime      — 日期 + 时间（无时区）
├── PlainYearMonth     — 年 + 月
├── PlainMonthDay      — 月 + 日
├── ZonedDateTime      — 日期 + 时间 + 时区（完整表示）
├── Instant            — 绝对时间点（纳秒精度，自 Unix epoch 起）
├── Duration           — 时间段（年/月/周/天/时/分/秒/毫秒/微秒/纳秒）
├── TimeZone           — 时区标识
└── Calendar           — 日历系统
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.3 实际使用对比&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;// ❌ 旧 Date API — 月份从 0 开始，修改是可变操作
const oldDate = new Date(2026, 4, 6);  // 4 = 五月？
oldDate.setDate(oldDate.getDate() + 30); // 修改了原对象

// ✅ 新 Temporal API — 语义清晰，不可变
const date = Temporal.PlainDate.from(&apos;2026-05-08&apos;);
const nextMonth = date.add({ days: 30 });  // 返回新对象，date 不变

// 时区感知
const meeting = Temporal.ZonedDateTime.from(&apos;2026-05-08T10:00[Asia/Shanghai]&apos;);
const inNY = meeting.withTimeZone(&apos;America/New_York&apos;);
console.log(inNY.toString()); // 2026-05-07T22:00:00-04:00[America/New_York]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.4 实现细节&lt;/h3&gt;
&lt;p&gt;Temporal 的底层实现使用了 Rust 语言编写的 &lt;code&gt;temporal_rs&lt;/code&gt; 库，并非仅仅依赖 V8 引擎。这意味着其他 JavaScript 引擎（如 JavaScriptCore、SpiderMonkey）也可以直接集成，为 Temporal 成为跨运行时标准奠定了基础。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;4. V8 14.6：引擎大升级&lt;/h2&gt;
&lt;p&gt;Node.js 26 搭载了 &lt;strong&gt;V8 14.6.202.33&lt;/strong&gt;（对应 Chromium 146），&lt;code&gt;NODE_MODULE_VERSION&lt;/code&gt; 升至 &lt;strong&gt;147&lt;/strong&gt;，所有原生 C++ 插件需要重新编译。&lt;/p&gt;
&lt;h3&gt;4.1 Map Upsert 方法（Stage 3+）&lt;/h3&gt;
&lt;p&gt;V8 14.6 带来了 TC39 Upsert 提案的原生支持：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// 传统写法：两次哈希查找
if (!map.has(key)) {
  map.set(key, computeExpensiveValue());
}
const value = map.get(key);

// 新写法：一次哈希查找
const value = map.getOrInsertComputed(key, () =&amp;gt; computeExpensiveValue());

// 或使用静态值
const value = map.getOrInsert(key, defaultValue);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;WeakMap&lt;/code&gt; 也获得了相同的 &lt;code&gt;getOrInsert&lt;/code&gt; / &lt;code&gt;getOrInsertComputed&lt;/code&gt; 方法。&lt;/p&gt;
&lt;h3&gt;4.2 Iterator 辅助方法&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;// Iterator.concat() — 合并多个迭代器为单一序列
const a = [1, 2, 3].values();
const b = [4, 5, 6].values();
const combined = Iterator.concat(a, b);

for (const n of combined) {
  console.log(n); // 1, 2, 3, 4, 5, 6
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.3 其他 V8 14.6 增强&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Error.isError()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;跨 Realm/Worker 的可靠错误检测&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;RegExp.escape()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;安全转义正则特殊字符&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Float16Array&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;16 位浮点 TypedArray（ML/AI 推理、WebGPU 互操作）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Promise.try()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;统一同步/异步函数调用包装&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;async/await 性能&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;约 15% 的性能提升&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;5. Undici 8 与 HTTP 层更新&lt;/h2&gt;
&lt;p&gt;Node.js 26 将内置 HTTP 客户端升级至 &lt;strong&gt;Undici 8.0.2&lt;/strong&gt;——这是 Node.js 全局 &lt;code&gt;fetch()&lt;/code&gt; 的底层实现。&lt;/p&gt;
&lt;h3&gt;5.1 核心改进&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;WHATWG Fetch 规范对齐&lt;/strong&gt;：行为更接近浏览器环境的 &lt;code&gt;fetch&lt;/code&gt; 语义&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HTTP/1.1 和 HTTP/2&lt;/strong&gt;：持久连接管理优化&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;连接池策略调整&lt;/strong&gt;：&lt;code&gt;Pool&lt;/code&gt; 和 &lt;code&gt;Agent&lt;/code&gt; 类的行为变更&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;错误对象格式统一&lt;/strong&gt;：错误处理更一致&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;5.2 直接依赖 Undici 的项目注意事项&lt;/h3&gt;
&lt;p&gt;如果在项目中直接 &lt;code&gt;import&lt;/code&gt; 了 &lt;code&gt;undici&lt;/code&gt;，升级 Node.js 26 后建议检查：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// 如果使用了 Undici 的底层 API
import { Pool, Agent, Dispatcher } from &apos;undici&apos;;

// 检查 Undici 8 的完整 changelog
// 特别关注 Pool 配置项和 Dispatcher 扩展点
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;6. 破坏性变更&lt;/h2&gt;
&lt;h3&gt;6.1 彻底移除的 API&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;移除项&lt;/th&gt;
&lt;th&gt;替代方案&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;http.Server.prototype.writeHeader()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;使用 &lt;code&gt;writeHead()&lt;/code&gt;（注意大小写）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;旧版 Stream 内部模块（&lt;code&gt;_stream_wrap&lt;/code&gt;、&lt;code&gt;_stream_readable&lt;/code&gt;、&lt;code&gt;_stream_writable&lt;/code&gt;、&lt;code&gt;_stream_duplex&lt;/code&gt;、&lt;code&gt;_stream_transform&lt;/code&gt;、&lt;code&gt;_stream_passthrough&lt;/code&gt;）&lt;/td&gt;
&lt;td&gt;使用现代 Stream API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--experimental-transform-types&lt;/code&gt; 标志&lt;/td&gt;
&lt;td&gt;TypeScript 转换功能已移除&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;crypto DEP0182&lt;/td&gt;
&lt;td&gt;已 End-of-Life，需迁移到新的 crypto API&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;6.2 新增运行时弃用&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;// module.register() — 进入运行时弃用
// 将输出弃用警告：DEP0201
&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;弃用项&lt;/th&gt;
&lt;th&gt;弃用编号&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;module.register()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;DEP0201&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stream 相关弃用&lt;/td&gt;
&lt;td&gt;DEP0203&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Crypto 相关弃用&lt;/td&gt;
&lt;td&gt;DEP0204&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;7. 构建与平台变更&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;变更项&lt;/th&gt;
&lt;th&gt;详情&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GCC 最低版本&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;GCC 13.2+（从 12 提升）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Python 要求&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Python 3.9 不再受支持，需 3.10+&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Windows SDK&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;升级至 SDK 11&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AIX / IBM i&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;迁移至 Power 9 硬件，旧版 Power 处理器不再支持&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Linux s390x&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;启用 V8 中间层优化编译器 Maglev&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ICU&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;更新至 78.3（国际化支持增强）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;libuv&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;更新至 1.52.1（底层 I/O 引擎）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;8. 其他值得关注的更新&lt;/h2&gt;
&lt;h3&gt;8.1 SQLite 增强&lt;/h3&gt;
&lt;p&gt;Node.js 26 为内置 &lt;code&gt;node:sqlite&lt;/code&gt; 模块启用了 Percentile 扩展，在数据分析和统计场景中尤为重要：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { DatabaseSync } from &apos;node:sqlite&apos;;

const db = new DatabaseSync(&apos;:memory:&apos;);
// Percentile 扩展已默认启用
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;8.2 Node.js 26.1.0：实验性 FFI&lt;/h3&gt;
&lt;p&gt;紧随 26.0.0，&lt;strong&gt;26.1.0&lt;/strong&gt; 引入了实验性的 &lt;code&gt;node:ffi&lt;/code&gt; 模块，允许直接从 JavaScript 调用原生动态库：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;node --experimental-ffi script.js
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这对高性能计算和系统级应用具有战略意义——JS 代码可以零开销调用 C/Rust 编写的原生函数。&lt;/p&gt;
&lt;h3&gt;8.3 安全修复&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;修复 &lt;strong&gt;CVE-2026-21717&lt;/strong&gt;：V8 数组索引哈希冲突漏洞&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;8.4 async/await 性能提升&lt;/h3&gt;
&lt;p&gt;得益于 V8 14.6 的优化，async/await 操作的性能提升了约 &lt;strong&gt;15%&lt;/strong&gt;，对重度使用异步操作的服务端应用是直接的利好。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;9. Node.js 27 与未来：年度发布新纪元&lt;/h2&gt;
&lt;h3&gt;9.1 新发布节奏&lt;/h3&gt;
&lt;p&gt;从 Node.js 27 开始，将采用&lt;strong&gt;三阶段&lt;/strong&gt;发布模型：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Alpha（6个月）     →  Current（6个月）    →  LTS（30个月）
   10月 ~ 3月           4月 ~ 10月              共计 2.5 年
   破坏性变更允许        稳定化阶段             安全修复
   灵活发布节奏         禁止破坏性变更          长期支持
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;9.2 Node.js 27 Alpha 即将开启&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;里程碑&lt;/th&gt;
&lt;th&gt;时间&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Alpha 开始&lt;/td&gt;
&lt;td&gt;2026年10月&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;27.0.0 Current&lt;/td&gt;
&lt;td&gt;2027年4月&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;进入 LTS&lt;/td&gt;
&lt;td&gt;2027年10月&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EOL&lt;/td&gt;
&lt;td&gt;2030年4月&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;关键变化：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;✅ &lt;strong&gt;每个版本都进入 LTS&lt;/strong&gt; —— 不再有&quot;跳过奇数版&quot;规则&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;版本号与年份对齐&lt;/strong&gt; —— 27 对应 2027，28 对应 2028&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Alpha 通道&lt;/strong&gt; —— 替代奇数版的实验角色，库作者可提前测试破坏性变更&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;活跃版本线减少&lt;/strong&gt; —— 从 4-5 个缩减至最多 3 个&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;9.3 未来十年路线图&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;版本&lt;/th&gt;
&lt;th&gt;Alpha&lt;/th&gt;
&lt;th&gt;Current&lt;/th&gt;
&lt;th&gt;LTS&lt;/th&gt;
&lt;th&gt;EOL&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;27.x&lt;/td&gt;
&lt;td&gt;2026年10月&lt;/td&gt;
&lt;td&gt;2027年4月&lt;/td&gt;
&lt;td&gt;2027年10月&lt;/td&gt;
&lt;td&gt;2030年4月&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;28.x&lt;/td&gt;
&lt;td&gt;2027年10月&lt;/td&gt;
&lt;td&gt;2028年4月&lt;/td&gt;
&lt;td&gt;2028年10月&lt;/td&gt;
&lt;td&gt;2031年4月&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;29.x&lt;/td&gt;
&lt;td&gt;2028年10月&lt;/td&gt;
&lt;td&gt;2029年4月&lt;/td&gt;
&lt;td&gt;2029年10月&lt;/td&gt;
&lt;td&gt;2032年4月&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;30.x&lt;/td&gt;
&lt;td&gt;2029年10月&lt;/td&gt;
&lt;td&gt;2030年4月&lt;/td&gt;
&lt;td&gt;2030年10月&lt;/td&gt;
&lt;td&gt;2033年4月&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;10. 升级指南&lt;/h2&gt;
&lt;h3&gt;10.1 从 Node.js 24/25 升级&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 使用 nvm
nvm install 26
nvm use 26

# 或使用 fnm
fnm install 26
fnm use 26

# 验证版本
node --version  # v26.0.0
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;10.2 升级检查清单&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;Node.js 26 升级检查清单
├── ☐ 运行 npx npm-check-updates 检查依赖兼容性
├── ☐ 检查原生 C++ 插件是否兼容 NODE_MODULE_VERSION 147
├── ☐ 搜索 writeHeader() 替换为 writeHead()
├── ☐ 检查是否直接 import &apos;undici&apos;（需查 Undici 8 changelog）
├── ☐ 移除 --experimental-transform-types 标志
├── ☐ 检查 crypto 旧 API 使用情况（DEP0182）
├── ☐ 验证 GCC 编译环境 ≥ 13.2（源码编译场景）
├── ☐ 将旧 Date 操作逐步迁移至 Temporal API
├── ☐ 在 CI 中加入 Node.js 26 测试矩阵
└── ☐ 短期：Node.js 24（活跃 LTS，最保守选择）
    中期：Node.js 26（10月进入 LTS，特性最先进）
    紧急：Node.js 22（维护 LTS，迁移窗口充裕）
    立即迁移：Node.js 20（已于 2026年4月30日 EOL！）
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;10.3 各版本线状态速查&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;版本&lt;/th&gt;
&lt;th&gt;状态&lt;/th&gt;
&lt;th&gt;EOL&lt;/th&gt;
&lt;th&gt;建议&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;20.x&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;EOL&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2026年4月30日&lt;/td&gt;
&lt;td&gt;⚠️ 立即迁移&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;22.x&lt;/td&gt;
&lt;td&gt;维护 LTS&lt;/td&gt;
&lt;td&gt;2027年4月30日&lt;/td&gt;
&lt;td&gt;安全，但建议迁移到 24&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;24.x&lt;/td&gt;
&lt;td&gt;活跃 LTS&lt;/td&gt;
&lt;td&gt;2028年4月30日&lt;/td&gt;
&lt;td&gt;✅ 当前生产推荐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;25.x&lt;/td&gt;
&lt;td&gt;维护期&lt;/td&gt;
&lt;td&gt;2026年6月1日&lt;/td&gt;
&lt;td&gt;即将 EOL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;26.x&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Current&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;2029年4月30日&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;🆕 10月进入 LTS&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;11. 总结&lt;/h2&gt;
&lt;p&gt;Node.js 26 是一个**&quot;清理 + 加速 + 终结&quot;**三位一体的版本：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;维度&lt;/th&gt;
&lt;th&gt;评价&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Temporal API&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;现代日期时间的起点，默认可用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;V8 14.6&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Map Upsert、Iterator.concat、15% async 性能提升&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Undici 8&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;HTTP 层持续演进，更规范、更高效&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;破坏性变更&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;清理旧 Stream/crypto/HTTP API 历史包袱&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;时代终结&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;最后一个奇偶版本，10月进入 LTS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;新时代&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Node.js 27 起年度发布，每个版本都是 LTS&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Node.js 26 是第一章的结尾，也是第二章的序章。&lt;/strong&gt; 它继承了十年来奇偶版本的成熟与稳定，同时开启了 Node.js 年度发行、全面 LTS 的新时代。无论你选择在当前就升级到 Node.js 26，还是继续建立在 Node.js 24 的生产基线上——关键在于理解这个分水岭版本的意义：&lt;strong&gt;Node.js 正在变得更加可预测、更可持续、更面向未来。&lt;/strong&gt;&lt;/p&gt;
</content:encoded></item><item><title>Linux 内核高危漏洞 CVE-2026-31431 (Copy Fail) 深度解析</title><link>https://www.hehonglei.cn/posts/linux-kernel-cve-2026-31431/</link><guid isPermaLink="true">https://www.hehonglei.cn/posts/linux-kernel-cve-2026-31431/</guid><description>2026年4月，Linux内核曝出潜伏9年的高危本地提权漏洞CVE-2026-31431。本文深入分析其技术原理、攻击链、影响范围，并提供完整的排查与修复指南。</description><pubDate>Thu, 30 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;1. 漏洞概述&lt;/h2&gt;
&lt;p&gt;2026年4月22日，Linux 内核披露了一个潜伏 &lt;strong&gt;9年&lt;/strong&gt; 的高危本地提权漏洞 CVE-2026-31431，代号 &lt;strong&gt;Copy Fail&lt;/strong&gt;。攻击者仅需一个 &lt;strong&gt;732字节&lt;/strong&gt; 的 Python 脚本，就能在几乎所有主流 Linux 发行版上将低权限用户提权至 root。&lt;/p&gt;
&lt;p&gt;该漏洞被 CNCERT（国家互联网应急中心）收录编号为 CNVD-2026-19044，CNTA-2026-0002，CVSS 3.1 评分 &lt;strong&gt;7.8（高危）&lt;/strong&gt;。更令人担忧的是，漏洞利用代码已公开，安天公司已监测到在野利用情况。&lt;/p&gt;
&lt;h3&gt;1.1 与历史漏洞对比&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;漏洞&lt;/th&gt;
&lt;th&gt;年份&lt;/th&gt;
&lt;th&gt;CVSS&lt;/th&gt;
&lt;th&gt;需要竞态条件&lt;/th&gt;
&lt;th&gt;利用难度&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Dirty COW (CVE-2016-5195)&lt;/td&gt;
&lt;td&gt;2016&lt;/td&gt;
&lt;td&gt;7.8&lt;/td&gt;
&lt;td&gt;需要&lt;/td&gt;
&lt;td&gt;中等&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dirty Pipe (CVE-2022-0847)&lt;/td&gt;
&lt;td&gt;2022&lt;/td&gt;
&lt;td&gt;7.8&lt;/td&gt;
&lt;td&gt;需要&lt;/td&gt;
&lt;td&gt;中等&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Copy Fail (CVE-2026-31431)&lt;/td&gt;
&lt;td&gt;2026&lt;/td&gt;
&lt;td&gt;7.8&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;不需要&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;极低&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;1.2 事件时间线&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;日期&lt;/th&gt;
&lt;th&gt;事件&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;2017年&lt;/td&gt;
&lt;td&gt;内核 commit 72548b093ee3 引入 algif_aead 原地优化&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026年4月22日&lt;/td&gt;
&lt;td&gt;漏洞公开，PoC 和 Exp 同步公开&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026年4月29日&lt;/td&gt;
&lt;td&gt;Openwall 邮件列表披露详情&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026年4月30日&lt;/td&gt;
&lt;td&gt;CNCERT 发布安全公告 CNTA-2026-0002&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026年4月30日&lt;/td&gt;
&lt;td&gt;奇安信 CERT 发布安全风险通告&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;2. 技术深度分析&lt;/h2&gt;
&lt;h3&gt;2.1 漏洞根因&lt;/h3&gt;
&lt;p&gt;Copy Fail 的利用链涉及三个关键内核组件的组合：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;AF_ALG 加密接口  +  splice() 系统调用  +  algif_aead 原地优化
        ↓                    ↓                    ↓
   用户态调用内核      将文件页缓存引用      允许在加密处理中
   crypto 能力         带入加密处理链        复用内存页
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2.2 攻击链&lt;/h3&gt;
&lt;p&gt;整个攻击过程分为四个阶段：&lt;/p&gt;
&lt;h4&gt;阶段一：创建 AF_ALG 套接字并绑定 authencesn&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;import socket

# 创建 AF_ALG 套接字，绑定带认证的加密算法
s = socket.socket(socket.AF_ALG, socket.SOCK_SEQPACKET, 0)
s.bind((&apos;authencesn&apos;, b&apos;hmac(sha256),cbc(aes)&apos;))
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;阶段二：通过 splice() 将 setuid 程序的页缓存引入加密路径&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;import os

# 打开 setuid 程序（如 /usr/bin/su）
fd = os.open(&apos;/usr/bin/su&apos;, os.O_RDONLY)

# 构造 splice 管道，触发页缓存引用
pipe_r, pipe_w = os.pipe()
os.splice(fd, 0, pipe_w, 0, 4096)
os.close(fd)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;阶段三：利用 algif_aead 原地优化写入受控 4 字节&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;# 发送恶意数据，利用 in-place 优化覆写页缓存
# 将本应是&quot;只读&quot;的页缓存变成了&quot;可写&quot;
s.sendmsg([b&apos;A&apos; * 4096], [(pipe_r, 0, 4096)])
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;阶段四：执行被篡改的 setuid 程序获得 root&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;# 执行 su，此时读取到的已是页缓存中的恶意代码
os.execve(&apos;/usr/bin/su&apos;, [], {})
# 直接获得 root shell
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2.3 为什么&quot;不需要竞态条件&quot;&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;此前同类漏洞&lt;/th&gt;
&lt;th&gt;Copy Fail&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;依赖内存操作时序窗口&lt;/td&gt;
&lt;td&gt;逻辑上直接的读写缺陷&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;需多次尝试提高成功率&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;一次即可成功，成功率 100%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;受系统负载影响&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;完全确定性利用&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;2.4 漏洞的技术本质&lt;/h3&gt;
&lt;p&gt;正常流程下，页缓存中的文件数据应该是 &lt;strong&gt;只读&lt;/strong&gt; 的。但 algif_aead 的 in-place 优化绕过了这个约束：它允许将一个只读页缓存的引用放入 scatterlist，而 scatterlist 在加密操作后会被 &lt;strong&gt;写回&lt;/strong&gt;。于是，攻击者就能向本属于 &lt;code&gt;/usr/bin/su&lt;/code&gt; 等 setuid 程序的页缓存中写入任意 4 字节，实现代码篡改。&lt;/p&gt;
&lt;p&gt;值得注意的是：&lt;strong&gt;漏洞仅修改内存页缓存，不直接写磁盘&lt;/strong&gt;。重启或缓存回收后篡改内容自动恢复，但这不影响利用——因为进程执行时读取的就是页缓存。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;3. 影响范围&lt;/h2&gt;
&lt;h3&gt;3.1 受影响的内核版本&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;commit 72548b093ee3 ≤ version &amp;lt; commit a664bf3d603d
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;内核 4.14 ~ 6.18.22（不含）、6.19.12（不含）以下均受影响。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;3.2 受影响的发行版&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;发行版&lt;/th&gt;
&lt;th&gt;受影响版本&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Ubuntu&lt;/td&gt;
&lt;td&gt;24.04 LTS 及以下&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RHEL&lt;/td&gt;
&lt;td&gt;8 / 9 / 10 及以下&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SUSE&lt;/td&gt;
&lt;td&gt;16 及以下&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Amazon Linux&lt;/td&gt;
&lt;td&gt;2023 及以下&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Debian / Arch / Fedora / Rocky / Alma / Oracle&lt;/td&gt;
&lt;td&gt;同期内核版本&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;3.3 安全版本&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;内核版本线&lt;/th&gt;
&lt;th&gt;安全版本&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;6.18 LTS&lt;/td&gt;
&lt;td&gt;≥ 6.18.22&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6.19 LTS&lt;/td&gt;
&lt;td&gt;≥ 6.19.12&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7.0&lt;/td&gt;
&lt;td&gt;≥ 7.0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;3.4 高危场景&lt;/h3&gt;
&lt;p&gt;该漏洞虽然在利用前需要本地低权限代码执行能力，但在以下场景中风险被显著放大：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;场景&lt;/th&gt;
&lt;th&gt;风险说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;共享服务器&lt;/td&gt;
&lt;td&gt;多租户主机、开发机、跳板机——任一用户可提权至 root&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kubernetes / 容器集群&lt;/td&gt;
&lt;td&gt;容器逃逸：容器内低权限用户可篡改宿主机页缓存&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CI/CD 执行器&lt;/td&gt;
&lt;td&gt;GitHub Actions、GitLab Runner、Jenkins 等构建环境&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;代码沙箱&lt;/td&gt;
&lt;td&gt;Notebook、在线评测平台、AI Agent 执行机&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;云服务器&lt;/td&gt;
&lt;td&gt;多租户共享宿主机的 VPS 环境&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;4. 自查指南&lt;/h2&gt;
&lt;h3&gt;4.1 检查内核版本&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 查看当前内核版本
uname -r

# 查看完整内核版本信息
cat /proc/version
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.2 检查 algif_aead 模块是否加载&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 检查模块是否已加载
lsmod | grep algif_aead

# 检查模块是否可用（即使未加载）
modinfo algif_aead 2&amp;gt;/dev/null &amp;amp;&amp;amp; echo &quot;模块可用，存在风险&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.3 检查 AF_ALG 套接字支持&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 检查内核是否编译了 AF_ALG 支持
grep CONFIG_CRYPTO_USER_API_AEAD /boot/config-$(uname -r)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.4 一键排查脚本&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/bash
echo &quot;=== CVE-2026-31431 Copy Fail 排查脚本 ===&quot;
echo &quot;&quot;

KERNEL=$(uname -r)
echo &quot;[*] 当前内核版本: $KERNEL&quot;

if lsmod | grep -q algif_aead; then
    echo &quot;[!] 高危: algif_aead 模块已加载！&quot;
else
    echo &quot;[*] algif_aead 模块未加载&quot;
fi

if modinfo algif_aead &amp;amp;&amp;gt;/dev/null; then
    echo &quot;[!] 高危: algif_aead 模块可用（即使未加载也可被触发加载）&quot;
else
    echo &quot;[*] algif_aead 模块不可用&quot;
fi

echo &quot;[*] 请手动对比内核版本是否在安全范围内&quot;
echo &quot;    安全版本: 6.18.22+ / 6.19.12+ / 7.0+&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;5. 修复与处置指南&lt;/h2&gt;
&lt;h3&gt;5.1 永久修复：升级内核（推荐）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# Ubuntu / Debian
sudo apt update &amp;amp;&amp;amp; sudo apt full-upgrade -y
sudo reboot

# RHEL / CentOS / Fedora
sudo dnf update kernel -y
sudo reboot

# SUSE / openSUSE
sudo zypper update kernel -y
sudo reboot

# Arch Linux
sudo pacman -S linux linux-lts
sudo reboot

# 重启后确认
uname -r
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.2 临时缓解措施：禁用 algif_aead 模块&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 1. 永久禁用模块
echo &quot;install algif_aead /bin/false&quot; | sudo tee /etc/modprobe.d/disable-algif-aead.conf

# 2. 立即卸载已加载的模块
sudo rmmod algif_aead 2&amp;gt;/dev/null

# 3. 确认模块已被禁用
sudo modprobe algif_aead 2&amp;gt;&amp;amp;1  # 应显示被 /bin/false 拦截
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.3 容器侧防护：阻断 AF_ALG 套接字&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 通过 seccomp 策略阻断容器内 AF_ALG socket 创建
# 在 Docker 运行参数中添加
--security-opt seccomp=/path/to/custom-seccomp.json

# 自定义 seccomp 规则示例：
# { &quot;names&quot;: [&quot;socket&quot;], &quot;action&quot;: &quot;ERRNO&quot;, &quot;args&quot;: [
#   { &quot;index&quot;: 0, &quot;value&quot;: 38, &quot;op&quot;: &quot;SCMP_CMP_EQ&quot; }
# ] }
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.4 事后排查：清理页缓存与检查后门&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 1. 释放页缓存（重启后自动恢复，无需此步骤）
sync &amp;amp;&amp;amp; echo 3 | sudo tee /proc/sys/vm/drop_caches

# 2. 检查异常进程
ps auxf | grep -E &quot;su|sudo|bash|sh&quot;

# 3. 检查临时目录后门
ls -la /tmp /var/tmp

# 4. 检查登录日志
last -n 50

# 5. 检查 setuid 程序哈希值
sha256sum /usr/bin/su /usr/bin/sudo /usr/bin/passwd
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;6. 安全启示&lt;/h2&gt;
&lt;h3&gt;6.1 为什么代码优化会成为安全漏洞&lt;/h3&gt;
&lt;p&gt;Copy Fail 的根源是 2017 年引入的 in-place 优化。该优化本身出发点是好的——减少内存拷贝、提升加密性能。但它在设计时没有充分考虑&lt;strong&gt;页缓存的安全边界&lt;/strong&gt;：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;设计假设&lt;/th&gt;
&lt;th&gt;实际情况&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;scatterlist 中的数据来自用户缓冲区&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;splice() 可引入页缓存引用&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;加密操作的目标内存可安全写入&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;页缓存不应被普通用户写入&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;in-place 优化节省一次复制&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;节省了一次复制，但破坏了只读语义&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;6.2 发现过程：AI + 人类协作&lt;/h3&gt;
&lt;p&gt;此漏洞的发现结合了人类洞察与 AI 工具：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;研究员 &lt;strong&gt;Taeyang Lee&lt;/strong&gt; 首先识别出 AF_ALG 加密接口 + splice() 的攻击面&lt;/li&gt;
&lt;li&gt;随后利用 AI 辅助审计工具 &lt;strong&gt;Xint Code&lt;/strong&gt; 扫描 crypto/子系统&lt;/li&gt;
&lt;li&gt;仅耗时约 &lt;strong&gt;1 小时&lt;/strong&gt; 便定位到此最高严重性漏洞&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这是安全领域 AI 辅助漏洞挖掘的成功案例。&lt;/p&gt;
&lt;h3&gt;6.3 防御深度&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;┌─────────────────────────────────┐
│  1. 及时升级内核版本（治本）       │
├─────────────────────────────────┤
│  2. 禁用不必要的内核模块           │
├─────────────────────────────────┤
│  3. 容器 Security Context 限制    │
├─────────────────────────────────┤
│  4. seccomp / AppArmor / SELinux │
├─────────────────────────────────┤
│  5. 文件完整性监控（AIDE/Samhain） │
└─────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;7. 总结&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;CVE-2026-31431 是 Dirty COW / Dirty Pipe 之后最严重的 Linux 本地提权漏洞&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;漏洞利用 &lt;strong&gt;无需竞态条件，成功率 100%，仅需 732 字节 Python 脚本&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;影响 &lt;strong&gt;2017 年以来几乎所有主流 Linux 发行版&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;容器环境下可实现 &lt;strong&gt;容器逃逸&lt;/strong&gt;，威胁云原生基础设施&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;立即升级内核至安全版本&lt;/strong&gt; 是最彻底的修复方案&lt;/li&gt;
&lt;li&gt;临时措施：&lt;code&gt;install algif_aead /bin/false&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h2&gt;参考资料&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.secrss.com/articles/89891&quot;&gt;CNCERT 安全公告 CNTA-2026-0002&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.secrss.com/articles/89880&quot;&gt;奇安信 CERT 安全风险通告&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.openwall.com/lists/oss-security/2026/04/29/23&quot;&gt;Openwall 漏洞披露&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/theori-io/copy-fail-CVE-2026-31431&quot;&gt;Copy Fail PoC (GitHub)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://git.kernel.org/stable/c/a664bf3d603dc3bdcf9ae47cc21e0daec706d7a5&quot;&gt;Linux Kernel 上游补丁 a664bf3d603d&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ithome.com/0/945/297.htm&quot;&gt;IT之家报道&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>2026 年 4 月，全球主流前端部署平台 Vercel 遭遇严重安全入侵</title><link>https://www.hehonglei.cn/posts/vercel-april-2026-security-incident/</link><guid isPermaLink="true">https://www.hehonglei.cn/posts/vercel-april-2026-security-incident/</guid><description>2026 年 4 月，全球主流前端部署平台 Vercel 遭遇严重安全入侵。攻击者通过第三方 AI 工具的 OAuth 漏洞切入，导致内部数据泄露并在黑市叫卖。本文基于多方安全报告，还原事件始末、分析攻击链条，并为开发者提供安全建议。</description><pubDate>Tue, 21 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Vercel 2026 年 4 月安全事件深度复盘：第三方 AI 工具引发的供应链危机&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;摘要&lt;/strong&gt;：2026 年 4 月，全球主流前端部署平台 Vercel 遭遇严重安全入侵。攻击者通过第三方 AI 工具的 OAuth 漏洞切入，导致内部数据泄露并在黑市叫卖。本文基于多方安全报告，还原事件始末、分析攻击链条，并为开发者提供安全建议。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h2&gt;1. 事件概述&lt;/h2&gt;
&lt;p&gt;2026 年 4 月 19 日至 20 日期间，开发基础设施巨头 &lt;strong&gt;Vercel&lt;/strong&gt;（Next.js 母公司）确认其内部系统遭到未授权访问。黑客组织在数据黑市论坛 BreachForums 上声称窃取了 Vercel 的访问密钥、源代码及数据库记录，并标价 &lt;strong&gt;200 万美元&lt;/strong&gt; 出售。&lt;/p&gt;
&lt;p&gt;此次事件被定性为典型的 &lt;strong&gt;供应链攻击&lt;/strong&gt;，攻击入口并非 Vercel 核心系统本身，而是其员工日常使用的一款第三方 AI 工具。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;发生时间&lt;/strong&gt;：2026 年 4 月中旬（公告发布于 4 月 19 日 -20 日）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;受影响平台&lt;/strong&gt;：Vercel 内部系统、部分客户环境&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;攻击源头&lt;/strong&gt;：第三方 AI 合作伙伴（报道指向 &lt;strong&gt;Context.ai&lt;/strong&gt;）的 Google Workspace OAuth 应用&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;安全状态&lt;/strong&gt;：Next.js 及 Turbopack 开源项目经审计确认安全，未发现 npm 投毒&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;2. 攻击链条还原&lt;/h2&gt;
&lt;p&gt;根据 Vercel 官方公告及安全研究人员分析，此次攻击链路如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;初始入侵&lt;/strong&gt;：攻击者攻破了 Vercel 员工正在使用的一款第三方 AI 工具（该工具拥有 Google Workspace OAuth 授权）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;权限滥用&lt;/strong&gt;：该第三方工具的 OAuth 应用被广泛泄露，影响数百个跨组织用户。攻击者利用此信任链获取了 Vercel 内部系统的访问权限。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据窃取&lt;/strong&gt;：攻击者横向移动，窃取了内部数据库记录、环境变量及部分凭证。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据变现&lt;/strong&gt;：攻击者自称 &lt;strong&gt;ShinyHunters&lt;/strong&gt;（曾入侵 Rockstar Games 的组织），在 BreachForums 叫卖数据。&lt;em&gt;注：后有真实 ShinyHunters 成员向媒体否认参与，攻击者可能为借名造势。&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;入侵指标 (IOC)&lt;/strong&gt;
Vercel 公布了关键的 OAuth Client ID，建议管理员自查：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;110671459871-30f1spbu0hptbs60cb4vsmv79i7bbvqj.apps.googleusercontent.com
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;3. 泄露数据与影响范围&lt;/h2&gt;
&lt;p&gt;关于泄露数据的具体内容，官方公告与黑市声称存在一定差异，综合多方信息如下：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;数据类型&lt;/th&gt;
&lt;th&gt;确认状态&lt;/th&gt;
&lt;th&gt;详细说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;员工信息&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ 确认&lt;/td&gt;
&lt;td&gt;员工姓名、电子邮箱地址、操作时间戳&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;环境变量&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;⚠️ 部分泄露&lt;/td&gt;
&lt;td&gt;标记为&quot;非敏感 (non-sensitive)&quot;的未加密变量泄露；&quot;敏感&quot;变量有加密保护，暂无证据被读取&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;源代码/密钥&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;⚠️ 声称&lt;/td&gt;
&lt;td&gt;黑市声称包含访问密钥、NPM 令牌、GitHub 令牌及源代码，官方未完全确认&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;内部系统记录&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;⚠️ 声称&lt;/td&gt;
&lt;td&gt;包含 Linear 项目管理系统的数据库记录，可能暴露内部安全评估历史&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;客户影响&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ 有限&lt;/td&gt;
&lt;td&gt;Vercel 称仅影响&quot;有限客户子集&quot;，已直接联系受影响客户&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;4. 官方响应与处置&lt;/h2&gt;
&lt;p&gt;Vercel 在事件曝光后迅速发布了安全公告（Bulletin），主要措施包括：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;直接沟通&lt;/strong&gt;：已识别并直接联系受波及的客户。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;凭证轮换&lt;/strong&gt;：建议所有用户核查并轮换环境变量、API 密钥和令牌。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;日志审计&lt;/strong&gt;：建议管理员检查操作日志，排查可疑行为。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;开源审计&lt;/strong&gt;：确认 Next.js 和 Turbopack 供应链安全，排除投毒风险。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;撤销授权&lt;/strong&gt;：立即审计并撤销了相关第三方 AI 工具的 OAuth 授权。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;5. 行业反思：谁该背锅？&lt;/h2&gt;
&lt;p&gt;此次事件在安全社区引发了关于&quot;供应链责任&quot;的激烈讨论：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;正方（Vercel 响应专业）&lt;/strong&gt;：Vercel 也是受害者，第三方 AI 工具被攻破属于连带风险。Vercel 披露迅速，提供了 IOC 和明确修复指南，态度值得肯定。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;反方（平台责任缺失）&lt;/strong&gt;：作为基础设施平台，Vercel 应对接入的第三方工具进行更严格的安全评估。OAuth 授权机制一旦断裂，信任链即失效，平台不能仅以&quot;有限影响&quot;搪塞。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;核心警示&lt;/strong&gt;：&lt;strong&gt;第三方 AI 工具链已成为新的安全软肋&lt;/strong&gt;。供应链中任何一个薄弱环节（如一个员工使用的 AI 插件）都可能成为整体系统的突破口。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;6. 给开发者的安全建议&lt;/h2&gt;
&lt;p&gt;基于此次事件，安全专家提出以下建议，供开发团队参考：&lt;/p&gt;
&lt;h3&gt;🛡️ 环境变量管理&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;敏感隔离&lt;/strong&gt;：凭证、令牌、签名密钥必须显式标注为&quot;敏感&quot;并加密存储。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;即时轮换&lt;/strong&gt;：一旦项目对外暴露或怀疑泄露，立即轮换环境变量，确保开发管道不留密钥痕迹。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;🔗 第三方集成管控&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;视为威胁&lt;/strong&gt;：将接入的第三方工具（尤其是 AI 工具）视为生产环境威胁。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;最小权限&lt;/strong&gt;：连接 OAuth 应用到托管/源码/CI 系统时，提高人工审批门槛，遵循最小权限原则。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;定期审计&lt;/strong&gt;：定期检查组织内的 OAuth 应用授权情况，撤销不再使用的第三方访问权限。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;📝 审计与追踪&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;行为留痕&lt;/strong&gt;：保留智能体会话、部署记录、权限授予的审计追踪。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;渗透测试&lt;/strong&gt;：不仅测试系统自身，还需涵盖供应链环节（API 接口、第三方集成、身份认证机制）。建议关键行业每季度进行一次全面渗透测试。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;7. 结语&lt;/h2&gt;
&lt;p&gt;Vercel 2026 年 4 月安全事件再次敲响了警钟：&lt;strong&gt;在攻击者面前，不存在绝对安全的系统&lt;/strong&gt;。随着 AI 工具深度融入开发工作流，供应链攻击面正在扩大。对于开发者而言，信任固然重要，但验证与防御才是保障安全的基石。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;em&gt;本文依据 2026 年 4 月 20 日发布的每日极客日报、IT 之家及安全社区报告整理。&lt;/em&gt;&lt;/p&gt;
</content:encoded></item><item><title>Apifox 供应链投毒事件深度解析</title><link>https://www.hehonglei.cn/posts/apifox-security-incident/</link><guid isPermaLink="true">https://www.hehonglei.cn/posts/apifox-security-incident/</guid><description>2026年3月，国内知名API协作平台Apifox遭遇严重的供应链投毒攻击。本文深入分析此次事件的技术细节、攻击链条、影响范围，并提供完整的排查与防护指南。</description><pubDate>Mon, 20 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;1. 事件概述&lt;/h2&gt;
&lt;p&gt;2026年3月，国内流行的API协作平台 Apifox 遭遇了一起严重的&lt;strong&gt;供应链投毒攻击&lt;/strong&gt;。攻击者通过篡改官方 CDN 托管的 JavaScript 文件，在桌面客户端中植入恶意代码，意图窃取开发者的核心凭证并实施远程控制。&lt;/p&gt;
&lt;p&gt;此次攻击从 &lt;strong&gt;2026年3月4日&lt;/strong&gt; 开始，持续活跃了 &lt;strong&gt;18天&lt;/strong&gt;，直到3月22日恶意域名才停止解析。由于 Apifox 被广泛应用于研发团队，此次事件的影响范围极广，Windows、macOS 和 Linux 平台用户均受影响。&lt;/p&gt;
&lt;h3&gt;1.1 事件时间线&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;日期&lt;/th&gt;
&lt;th&gt;事件&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;2026年3月4日&lt;/td&gt;
&lt;td&gt;攻击者篡改 Apifox 官方 CDN 上的 JS 文件，投毒攻击开始&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026年3月4日-22日&lt;/td&gt;
&lt;td&gt;恶意代码持续分发，攻击者迭代攻击载荷&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026年3月22日&lt;/td&gt;
&lt;td&gt;恶意域名 &lt;code&gt;apifox.it.com&lt;/code&gt; 下线，停止解析&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026年3月23日&lt;/td&gt;
&lt;td&gt;Apifox 发布 v2.8.19 修复版本&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026年3月25日&lt;/td&gt;
&lt;td&gt;安全研究人员披露事件，Apifox 官方发布安全公告&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;1.2 为什么这个事件很重要？&lt;/h3&gt;
&lt;p&gt;与传统的病毒传播不同，此次攻击属于典型的&lt;strong&gt;供应链攻击&lt;/strong&gt;。攻击者并未直接攻击用户，而是选择入侵 Apifox 的官方软件分发渠道，在用户毫不知情的情况下，将恶意代码&quot;合法&quot;地分发到受害者的电脑中。&lt;/p&gt;
&lt;p&gt;开发者的电脑中存储着通往企业核心资产的&quot;钥匙&quot;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SSH 私钥 → 直接登录生产服务器&lt;/li&gt;
&lt;li&gt;Git Token → 访问和修改代码仓库&lt;/li&gt;
&lt;li&gt;云服务 Access Key → 控制云基础设施&lt;/li&gt;
&lt;li&gt;数据库密码 → 访问敏感数据&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;一把泄露的密钥，可能导致整个企业内网被渗透。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;2. 技术深度分析&lt;/h2&gt;
&lt;h3&gt;2.1 攻击环境：Electron 框架的安全缺陷&lt;/h3&gt;
&lt;p&gt;Apifox 桌面客户端基于 &lt;strong&gt;Electron 框架&lt;/strong&gt;开发，存在以下安全问题：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;问题&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;th&gt;后果&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;未启用 sandbox&lt;/td&gt;
&lt;td&gt;渲染进程可访问 Node.js API&lt;/td&gt;
&lt;td&gt;前端 JS 可执行系统命令&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Node.js API 暴露&lt;/td&gt;
&lt;td&gt;可直接调用 &lt;code&gt;fs&lt;/code&gt;、&lt;code&gt;child_process&lt;/code&gt;、&lt;code&gt;os&lt;/code&gt; 等模块&lt;/td&gt;
&lt;td&gt;文件读写、命令执行、信息收集&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;核心漏洞点&lt;/strong&gt;：由于未严格启用沙盒（Sandbox），通过网络加载的恶意 JS 代码获得了本地 Node.js 环境的完整权限，可以直接读写本地文件系统和执行系统命令。&lt;/p&gt;
&lt;h3&gt;2.2 投毒机制&lt;/h3&gt;
&lt;h4&gt;被篡改的文件&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;URL: https://cdn.apifox.com/www/assets/js/apifox-app-event-tracking.min.js
正常大小: 约 34KB
恶意大小: 约 77KB
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;攻击者在原本用于事件追踪的 SDK 代码末尾，追加了约 &lt;strong&gt;42KB&lt;/strong&gt; 的高度混淆恶意代码。&lt;/p&gt;
&lt;h4&gt;CDN 信息&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;cdn.apifox.com → CNAME → qiniudns.com（七牛云 CDN）
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;关于投毒发生位置，目前存在两种可能：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;CDN 节点被篡改&lt;/strong&gt;：部分 CDN 节点上的文件被替换&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;链路劫持&lt;/strong&gt;：HTTPS 通信过程中被中间人篡改（但需绕过证书校验）&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;2.3 恶意域名&lt;/h3&gt;
&lt;p&gt;攻击者注册了极具迷惑性的域名：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apifox.it.com
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个域名模仿了官方域名格式，旨在绕过用户和部分安全软件的警惕。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;3. 攻击链完整流程&lt;/h2&gt;
&lt;h3&gt;3.1 攻击流程图&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;graph TD
    A[用户启动 Apifox 客户端] --&amp;gt; B[加载 CDN JS 文件]
    B --&amp;gt; C{文件是否被投毒?}
    C --&amp;gt;|是| D[执行恶意代码]
    C --&amp;gt;|否| E[正常运行]
    D --&amp;gt; F[收集主机信息]
    F --&amp;gt; G[生成主机指纹 SHA-256]
    G --&amp;gt; H[连接 C2 服务器 apifox.it.com]
    H --&amp;gt; I[下载第二阶段载荷]
    I --&amp;gt; J[RSA 解密载荷]
    J --&amp;gt; K[eval 执行恶意代码]
    K --&amp;gt; L[窃取敏感文件]
    L --&amp;gt; M[AES-256-GCM 加密数据]
    M --&amp;gt; N[回传到攻击者服务器]
    N --&amp;gt; O[30分钟-3小时后重复]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.2 攻击阶段详解&lt;/h3&gt;
&lt;h4&gt;第一阶段：投毒文件下发&lt;/h4&gt;
&lt;p&gt;Apifox 桌面客户端在启动时，会动态加载事件追踪脚本。攻击者在该文件末尾追加了高度混淆的恶意代码。当用户启动被投毒的客户端时，这段恶意代码便随之激活。&lt;/p&gt;
&lt;h4&gt;第二阶段：建立连接与载荷加载&lt;/h4&gt;
&lt;p&gt;恶意代码激活后：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;收集主机信息&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;主机名&lt;/li&gt;
&lt;li&gt;用户名&lt;/li&gt;
&lt;li&gt;MAC 地址&lt;/li&gt;
&lt;li&gt;CPU 型号&lt;/li&gt;
&lt;li&gt;操作系统版本&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;生成唯一标识&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SHA-256(mac + cpu + hostname + user + os)
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;连接 C2 服务器&lt;/strong&gt;：
向 &lt;code&gt;apifox.it.com&lt;/code&gt; 发送请求，获取第二阶段恶意载荷。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;解密执行&lt;/strong&gt;：
使用内嵌的 RSA-2048 私钥解密载荷，通过 &lt;code&gt;eval()&lt;/code&gt; 函数执行。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;第三阶段：核心数据窃取&lt;/h4&gt;
&lt;p&gt;第二阶段脚本会系统性地扫描并窃取以下敏感文件：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;类型&lt;/th&gt;
&lt;th&gt;路径&lt;/th&gt;
&lt;th&gt;风险&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SSH 私钥&lt;/td&gt;
&lt;td&gt;&lt;code&gt;~/.ssh/id_rsa&lt;/code&gt; 等&lt;/td&gt;
&lt;td&gt;直接登录服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Git 凭证&lt;/td&gt;
&lt;td&gt;&lt;code&gt;~/.git-credentials&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;访问代码仓库&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;命令行历史&lt;/td&gt;
&lt;td&gt;&lt;code&gt;~/.bash_history&lt;/code&gt;、&lt;code&gt;~/.zsh_history&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;可能包含明文密码&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;K8s 配置&lt;/td&gt;
&lt;td&gt;&lt;code&gt;~/.kube/*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;控制 Kubernetes 集群&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;npm 凭证&lt;/td&gt;
&lt;td&gt;&lt;code&gt;~/.npmrc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;访问私有包仓库&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;云 Access Key&lt;/td&gt;
&lt;td&gt;各种云服务商配置&lt;/td&gt;
&lt;td&gt;控制云基础设施&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;所有窃取的数据会被打包、使用 &lt;strong&gt;AES-256-GCM&lt;/strong&gt; 加密，然后回传到攻击者的服务器。&lt;/p&gt;
&lt;h3&gt;3.3 通信特征&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;低频 Beacon&lt;/strong&gt;：30分钟到3小时之间随机间隔&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;加密通信&lt;/strong&gt;：使用 RSA-2048 加密载荷&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;隐蔽传输&lt;/strong&gt;：自定义请求头，伪装正常流量&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;4. 影响范围&lt;/h2&gt;
&lt;h3&gt;4.1 受影响的版本&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;受影响版本&lt;/strong&gt;：Apifox SaaS 版桌面客户端 &lt;strong&gt;2.8.19 以下版本&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;受影响平台&lt;/strong&gt;：Windows、macOS、Linux 全平台&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;受影响时间&lt;/strong&gt;：2026年3月4日至3月22日&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4.2 不受影响的版本&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Web 版（浏览器访问）&lt;/li&gt;
&lt;li&gt;私有化部署版&lt;/li&gt;
&lt;li&gt;v2.8.19 及以上版本&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4.3 为什么开发者是高危目标？&lt;/h3&gt;
&lt;p&gt;攻击者的目标并非个人电脑中的照片或文档，而是开发者手中通往企业核心资产的&quot;钥匙&quot;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;开发者电脑 → SSH密钥 → 生产服务器
           → Git Token → 代码仓库
           → 云密钥 → 云基础设施
           → 数据库密码 → 敏感数据
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;开发者的电脑因此成为了攻击者&lt;strong&gt;横向移动&lt;/strong&gt;、&lt;strong&gt;渗透企业内网&lt;/strong&gt;的绝佳跳板。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;5. 自查指南&lt;/h2&gt;
&lt;h3&gt;5.1 Windows 用户&lt;/h3&gt;
&lt;p&gt;打开 PowerShell（管理员），执行：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Select-String -Path &quot;$env:APPDATA\apifox\Local Storage\leveldb\*&quot; -Pattern &quot;rl_mc&quot;,&quot;rl_headers&quot; -List | Select-Object Path
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.2 macOS 用户&lt;/h3&gt;
&lt;p&gt;打开终端，执行：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;grep -arlE &quot;rl_mc|rl_headers&quot; ~/Library/Application\ Support/apifox/Local\ Storage/leveldb
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.3 Linux 用户&lt;/h3&gt;
&lt;p&gt;打开终端，执行：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;grep -arlE &quot;rl_mc|rl_headers&quot; ~/.config/apifox/Local\ Storage/leveldb
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.4 结果判断&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;有输出具体文件&lt;/strong&gt; → 已中招，需要立即采取补救措施&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;无输出&lt;/strong&gt; → 可能未被感染，但仍建议执行防护措施&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：由于被检查的文件为缓存文件，存在假阴性可能。如果在攻击窗口期（3月4日-22日）曾使用过 Apifox 桌面客户端，有极大概率已遭到攻击。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h2&gt;6. 防护与处置措施&lt;/h2&gt;
&lt;h3&gt;6.1 立即升级客户端&lt;/h3&gt;
&lt;p&gt;这是阻断攻击最直接有效的方法。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;修复版本：v2.8.19 及以上
修复方式：废除在线动态加载 JS，改为本地内置打包
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.2 全面轮换敏感凭证&lt;/h3&gt;
&lt;p&gt;这是处置措施中&lt;strong&gt;最关键&lt;/strong&gt;的一步。你必须假设所有在受影响设备上存储过的凭证均已泄露。&lt;/p&gt;
&lt;h4&gt;必须重置的凭证&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;凭证类型&lt;/th&gt;
&lt;th&gt;操作&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SSH 密钥&lt;/td&gt;
&lt;td&gt;生成新密钥对，部署到所有服务器和代码托管平台&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Git Token&lt;/td&gt;
&lt;td&gt;吊销并重新生成所有 Personal Access Token&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;云服务密钥&lt;/td&gt;
&lt;td&gt;轮换 AWS、阿里云、腾讯云等的 Access Key&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;数据库密码&lt;/td&gt;
&lt;td&gt;修改所有本地或远程数据库的访问密码&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API Key&lt;/td&gt;
&lt;td&gt;检查并更换所有第三方服务 API Key&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;K8s Token&lt;/td&gt;
&lt;td&gt;重新生成 Kubernetes 集群访问凭证&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;SSH 密钥重置示例&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;# 备份旧密钥
mv ~/.ssh/id_rsa ~/.ssh/id_rsa.old
mv ~/.ssh/id_rsa.pub ~/.ssh/id_rsa.pub.old

# 生成新密钥
ssh-keygen -t ed25519 -C &quot;your_email@example.com&quot;

# 将新公钥部署到服务器
ssh-copy-id user@server
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.3 网络层面封禁&lt;/h3&gt;
&lt;p&gt;在网络层面封禁以下可疑域名：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apifox.it.com
cdn.openroute.dev
upgrade.feishu.it.com
system.toshinkyo.or.jp
ns.feishu.it.com
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.4 检查服务器日志&lt;/h3&gt;
&lt;p&gt;审查服务器登录日志，检查是否有异常 SSH 登录：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 查看最近的 SSH 登录记录
last -a | head -20

# 查看认证日志
grep &quot;Accepted&quot; /var/log/auth.log | tail -20
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;7. 安全启示&lt;/h2&gt;
&lt;h3&gt;7.1 供应链攻击的特点&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;隐蔽性强&lt;/strong&gt;：恶意代码混淆加密，难以察觉&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;自动执行&lt;/strong&gt;：客户端启动即触发，无需用户交互&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;概率性触发&lt;/strong&gt;：并非每次请求都返回恶意版本&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;精准定向&lt;/strong&gt;：明确针对开发人员的高价值资产&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;高权限运行&lt;/strong&gt;：利用框架漏洞获取系统级权限&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;7.2 开发者安全最佳实践&lt;/h3&gt;
&lt;h4&gt;客户端安全&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;✅ 及时更新软件到最新版本&lt;/li&gt;
&lt;li&gt;✅ 启用软件的安全沙盒功能&lt;/li&gt;
&lt;li&gt;✅ 定期检查软件的完整性（校验 Hash）&lt;/li&gt;
&lt;li&gt;✅ 使用官方渠道下载软件&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;凭证管理&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;✅ 使用 SSH 密钥而非密码认证&lt;/li&gt;
&lt;li&gt;✅ 为不同服务使用不同的密钥&lt;/li&gt;
&lt;li&gt;✅ 定期轮换敏感凭证&lt;/li&gt;
&lt;li&gt;✅ 使用密钥管理工具（如 1Password、Bitwarden）&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;网络安全&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;✅ 配置防火墙规则&lt;/li&gt;
&lt;li&gt;✅ 监控异常网络流量&lt;/li&gt;
&lt;li&gt;✅ 封禁可疑域名&lt;/li&gt;
&lt;li&gt;✅ 使用 DNS 过滤服务&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;代码安全&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;✅ 启用双因素认证（2FA）&lt;/li&gt;
&lt;li&gt;✅ 使用 Personal Access Token 而非密码&lt;/li&gt;
&lt;li&gt;✅ 定期审查代码仓库的访问权限&lt;/li&gt;
&lt;li&gt;✅ 启用代码提交签名验证&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;7.3 Electron 应用开发建议&lt;/h3&gt;
&lt;p&gt;如果你是 Electron 应用开发者，请注意：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// ✅ 启用沙盒
const win = new BrowserWindow({
  webPreferences: {
    sandbox: true,
    contextIsolation: true,
    nodeIntegration: false,
    preload: path.join(__dirname, &apos;preload.js&apos;)
  }
});

// ❌ 避免这样做
const win = new BrowserWindow({
  webPreferences: {
    nodeIntegration: true,
    contextIsolation: false
  }
});
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;启用 &lt;code&gt;sandbox&lt;/code&gt; 和 &lt;code&gt;contextIsolation&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;禁用 &lt;code&gt;nodeIntegration&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;使用 &lt;code&gt;preload&lt;/code&gt; 脚本安全地暴露必要 API&lt;/li&gt;
&lt;li&gt;避免从网络动态加载可执行代码&lt;/li&gt;
&lt;li&gt;实施内容安全策略（CSP）&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;8. 总结&lt;/h2&gt;
&lt;p&gt;Apifox 供应链投毒事件是一次针对开发者的精准攻击，利用了 Electron 框架的安全缺陷和 CDN 分发机制的漏洞。此次事件提醒我们：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;供应链安全至关重要&lt;/strong&gt;：任何依赖的第三方组件都可能成为攻击入口&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;开发者是高危目标&lt;/strong&gt;：手中掌握着企业核心资产的访问权限&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;及时更新是关键&lt;/strong&gt;：保持软件最新状态能有效防范已知漏洞&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;凭证管理不可忽视&lt;/strong&gt;：定期轮换密钥，最小化泄露影响&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;如果你曾在风险时间段（2026年3月4日至3月22日）使用过 Apifox 桌面客户端，请&lt;strong&gt;立即&lt;/strong&gt;执行本文提到的排查和处置措施。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;参考资料&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.apifox.com/8392582m0&quot;&gt;Apifox 官方安全公告&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.aliyun.com/article/1726660&quot;&gt;微步情报局分析报告&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://ncc.hust.edu.cn/info/1443/6691.htm&quot;&gt;华中科技大学网络安全提示&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.csdn.net/m0_71099018/article/details/159691630&quot;&gt;CSDN 深度分析报告&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>React 19 稳定版发布：Server Components 成为默认架构</title><link>https://www.hehonglei.cn/posts/react-19-stable-release/</link><guid isPermaLink="true">https://www.hehonglei.cn/posts/react-19-stable-release/</guid><description>React 19 稳定版正式发布，Server Components 结束实验阶段，成为官方推荐的默认渲染架构。React Compiler 自动优化，新 Hooks API，前端开发进入全栈新时代。</description><pubDate>Mon, 20 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;1. 引言&lt;/h2&gt;
&lt;p&gt;2026 年 Q1，&lt;strong&gt;React 19.2.3 稳定版&lt;/strong&gt;正式发布，持续迭代 5 年的 &lt;strong&gt;React Server Components (RSC)&lt;/strong&gt; 正式结束实验阶段，成为 React 官方推荐的默认渲染架构。&lt;/p&gt;
&lt;p&gt;紧随其后，Next.js 15、Remix 3、Vite 官方 RSC 插件全面实现生产级兼容，前端开发完成了从 &lt;strong&gt;CSR 客户端渲染&lt;/strong&gt; 到 &lt;strong&gt;SSR 服务端渲染&lt;/strong&gt;，再到 &lt;strong&gt;RSC 服务端组件原生架构&lt;/strong&gt; 的第三次范式革命。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;2. React Server Components：核心概念&lt;/h2&gt;
&lt;h3&gt;2.1 什么是 Server Components？&lt;/h3&gt;
&lt;p&gt;React Server Components 是一种&lt;strong&gt;只在服务器端运行&lt;/strong&gt;的特殊组件：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;组件代码&lt;strong&gt;永远不会打包到客户端 bundle&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;仅向客户端传输渲染后的 UI 结构（RSC Payload）&lt;/li&gt;
&lt;li&gt;客户端 React 无缝整合到 DOM 中&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2.2 核心优势&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;优势&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;th&gt;效果&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;零客户端 bundle 增长&lt;/td&gt;
&lt;td&gt;服务端逻辑不发送到客户端&lt;/td&gt;
&lt;td&gt;bundle 减少 50-80%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;原生数据访问&lt;/td&gt;
&lt;td&gt;直接访问数据库、文件系统&lt;/td&gt;
&lt;td&gt;无需 API 层&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;流式渲染&lt;/td&gt;
&lt;td&gt;逐步传输页面内容&lt;/td&gt;
&lt;td&gt;首屏加载更快&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;无 hydration&lt;/td&gt;
&lt;td&gt;无需客户端水合&lt;/td&gt;
&lt;td&gt;消除 hydration 不匹配&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;自动代码分割&lt;/td&gt;
&lt;td&gt;以组件为粒度分割&lt;/td&gt;
&lt;td&gt;无需手动 lazy&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;2.3 组件类型分类&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;React 组件类型
├── Server Component（服务端组件）
│   ├── 运行环境：服务器 / 边缘节点
│   ├── 能力：数据获取、服务端资源访问
│   └── 限制：不能使用 useState/useEffect
│
├── Client Component（客户端组件）
│   ├── 运行环境：浏览器
│   ├── 能力：状态管理、交互逻辑
│   └── 要求：顶部声明 &quot;use client&quot;
│
└── Shared Component（共享组件）
    ├── 运行环境：双端均可
    ├── 能力：无状态 UI 渲染
    └── 限制：遵守双端约束
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;3. 实战示例&lt;/h2&gt;
&lt;h3&gt;3.1 Server Components 最佳实践&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;// app/posts/page.tsx (服务端组件)
// 直接访问数据库，无需 API 层
async function PostsPage() {
  const posts = await db.posts.findMany({
    orderBy: { createdAt: &apos;desc&apos; },
    take: 20
  });

  return (
    &amp;lt;main&amp;gt;
      &amp;lt;h1&amp;gt;最新文章&amp;lt;/h1&amp;gt;
      {/* Server Components 直接传递数据给 Client Components */}
      &amp;lt;PostsList posts={posts} /&amp;gt;
      {/* 客户端交互组件 */}
      &amp;lt;CreatePostForm /&amp;gt;
    &amp;lt;/main&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.2 Client Components 交互&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;// app/components/CreatePostForm.tsx (客户端组件)
&apos;use client&apos;;

import { useState } from &apos;react&apos;;

export function CreatePostForm() {
  const [title, setTitle] = useState(&apos;&apos;);
  
  const handleSubmit = async (e: FormEvent) =&amp;gt; {
    e.preventDefault();
    // Server Actions - 直接调用服务端函数
    await createPost({ title });
  };
  
  return (
    &amp;lt;form onSubmit={handleSubmit}&amp;gt;
      &amp;lt;input 
        value={title}
        onChange={(e) =&amp;gt; setTitle(e.title.value)}
        placeholder=&quot;文章标题&quot;
      /&amp;gt;
      &amp;lt;button type=&quot;submit&quot;&amp;gt;发布&amp;lt;/button&amp;gt;
    &amp;lt;/form&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;4. Server Actions：表单处理革命&lt;/h2&gt;
&lt;h3&gt;4.1 传统方式 vs Server Actions&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;传统方式&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// 需要创建 API 路由
// /api/contact.ts
export async function POST(req: Request) {
  const body = await req.json();
  await sendEmail(body);
  return Response.json({ success: true });
}

// 组件中调用
const handleSubmit = async (e) =&amp;gt; {
  e.preventDefault();
  const formData = new FormData(e.target);
  await fetch(&apos;/api/contact&apos;, {
    method: &apos;POST&apos;,
    body: JSON.stringify(Object.fromEntries(formData)),
  });
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Server Actions 方式&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// app/actions.ts
&apos;use server&apos;;

export async function submitContactForm(formData: FormData) {
  const email = formData.get(&apos;email&apos;) as string;
  const message = formData.get(&apos;message&apos;) as string;
  
  // 直接在服务端处理
  await sendEmail({ to: &apos;contact@example.com&apos;, email, message });
  await db.contact.create({ data: { email, message } });
  
  revalidatePath(&apos;/contact&apos;);
  return { success: true };
}

// app/contact/page.tsx
import { submitContactForm } from &apos;../actions&apos;;

export default function ContactPage() {
  return (
    &amp;lt;form action={submitContactForm}&amp;gt;
      &amp;lt;input name=&quot;email&quot; type=&quot;email&quot; required /&amp;gt;
      &amp;lt;textarea name=&quot;message&quot; required /&amp;gt;
      &amp;lt;button type=&quot;submit&quot;&amp;gt;发送&amp;lt;/button&amp;gt;
    &amp;lt;/form&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;5. 新 Hooks API&lt;/h2&gt;
&lt;h3&gt;5.1 useActionState&lt;/h3&gt;
&lt;p&gt;替代 &lt;code&gt;useFormState&lt;/code&gt;，处理表单状态：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { useActionState } from &apos;react&apos;;

function ContactForm() {
  const [state, formAction] = useActionState(submitContactForm, null);
  
  return (
    &amp;lt;form action={formAction}&amp;gt;
      &amp;lt;input name=&quot;email&quot; type=&quot;email&quot; required /&amp;gt;
      &amp;lt;textarea name=&quot;message&quot; required /&amp;gt;
      &amp;lt;button type=&quot;submit&quot;&amp;gt;发送&amp;lt;/button&amp;gt;
      {state?.success &amp;amp;&amp;amp; &amp;lt;p&amp;gt;发送成功！&amp;lt;/p&amp;gt;}
      {state?.error &amp;amp;&amp;amp; &amp;lt;p&amp;gt;发送失败：{state.error}&amp;lt;/p&amp;gt;}
    &amp;lt;/form&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.2 useFormStatus&lt;/h3&gt;
&lt;p&gt;获取表单提交状态：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { useFormStatus } from &apos;react-dom&apos;;

function SubmitButton() {
  const { pending } = useFormStatus();
  
  return (
    &amp;lt;button type=&quot;submit&quot; disabled={pending}&amp;gt;
      {pending ? &apos;发送中...&apos; : &apos;发送&apos;}
    &amp;lt;/button&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.3 useOptimistic&lt;/h3&gt;
&lt;p&gt;乐观更新 UI：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { useOptimistic } from &apos;react&apos;;

function LikeButton({ postId, initialLikes }) {
  const [optimisticLikes, setOptimisticLikes] = useOptimistic(
    initialLikes
  );
  
  const handleLike = async () =&amp;gt; {
    // 立即更新 UI
    setOptimisticLikes(prev =&amp;gt; prev + 1);
    // 后台发送请求
    await likePost(postId);
  };
  
  return (
    &amp;lt;button onClick={handleLike}&amp;gt;
      👍 {optimisticLikes}
    &amp;lt;/button&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.4 use&lt;/h3&gt;
&lt;p&gt;新的条件读取 API：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { use } from &apos;react&apos;;

function UserProfile({ userPromise }) {
  const user = use(userPromise);
  
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h2&amp;gt;{user.name}&amp;lt;/h2&amp;gt;
      &amp;lt;p&amp;gt;{user.bio}&amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;6. React Compiler：自动优化&lt;/h2&gt;
&lt;h3&gt;6.1 什么是 React Compiler？&lt;/h3&gt;
&lt;p&gt;React Compiler 是一个&lt;strong&gt;编译器级别的优化&lt;/strong&gt;，可以自动消除不必要的重渲染：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;自动添加 memoization&lt;/li&gt;
&lt;li&gt;无需手动写 &lt;code&gt;useMemo&lt;/code&gt; 和 &lt;code&gt;useCallback&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;代码量减少 20-30%&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;6.2 使用方式&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# Next.js 15.3+ 已默认集成
npm install next@latest
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// 无需任何配置，编译器自动优化
function UserList({ users }) {
  // 不需要 useMemo
  const sortedUsers = users.sort((a, b) =&amp;gt; a.name.localeCompare(b.name));
  
  // 不需要 useCallback
  const handleClick = (user) =&amp;gt; {
    console.log(&apos;Clicked:&apos;, user.name);
  };
  
  return (
    &amp;lt;ul&amp;gt;
      {sortedUsers.map(user =&amp;gt; (
        &amp;lt;li key={user.id} onClick={() =&amp;gt; handleClick(user)}&amp;gt;
          {user.name}
        &amp;lt;/li&amp;gt;
      ))}
    &amp;lt;/ul&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.3 注意事项&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;违反 React Rules 的写法会暴露为编译错误&lt;/li&gt;
&lt;li&gt;建议新项目直接开启，老项目先在开发环境试跑&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;7. 性能对比&lt;/h2&gt;
&lt;h3&gt;7.1 实测数据&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;指标&lt;/th&gt;
&lt;th&gt;React 18 (CSR)&lt;/th&gt;
&lt;th&gt;React 19 (RSC)&lt;/th&gt;
&lt;th&gt;提升&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;bundle 体积&lt;/td&gt;
&lt;td&gt;~350KB&lt;/td&gt;
&lt;td&gt;~80KB&lt;/td&gt;
&lt;td&gt;77%↓&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;首屏加载&lt;/td&gt;
&lt;td&gt;2.5s&lt;/td&gt;
&lt;td&gt;0.8s&lt;/td&gt;
&lt;td&gt;3x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TTI&lt;/td&gt;
&lt;td&gt;4.2s&lt;/td&gt;
&lt;td&gt;2.5s&lt;/td&gt;
&lt;td&gt;40%↓&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;内存占用&lt;/td&gt;
&lt;td&gt;~180MB&lt;/td&gt;
&lt;td&gt;~90MB&lt;/td&gt;
&lt;td&gt;50%↓&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;7.2 测试项目&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;项目类型&lt;/strong&gt;：内容密集型应用&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;页面数量&lt;/strong&gt;：~50&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;组件数量&lt;/strong&gt;：~200&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据获取&lt;/strong&gt;：直接数据库访问&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;8. 安全注意事项&lt;/h2&gt;
&lt;h3&gt;8.1 Server Functions 安全&lt;/h3&gt;
&lt;p&gt;RSC 带来了新的安全挑战：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;风险&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;th&gt;防护&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;未授权调用&lt;/td&gt;
&lt;td&gt;Server Function 可被直接调用&lt;/td&gt;
&lt;td&gt;显式声明权限&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;输入校验&lt;/td&gt;
&lt;td&gt;缺少输入验证&lt;/td&gt;
&lt;td&gt;服务端校验&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;敏感数据泄露&lt;/td&gt;
&lt;td&gt;服务端数据意外暴露&lt;/td&gt;
&lt;td&gt;最小化数据传输&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;8.2 最佳实践&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;&apos;use server&apos;;

// ✅ 好的做法：显式权限检查
export async function deleteUser(userId: string) {
  const user = await getCurrentUser();
  if (!user.isAdmin) {
    throw new Error(&apos;Unauthorized&apos;);
  }
  
  // 输入校验
  if (!userId || typeof userId !== &apos;string&apos;) {
    throw new Error(&apos;Invalid userId&apos;);
  }
  
  await db.user.delete({ where: { id: userId } });
  revalidatePath(&apos;/users&apos;);
}

// ❌ 危险的做法：无权限检查
export async function deleteUser(userId: string) {
  await db.user.delete({ where: { id: userId } });
}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;9. 迁移指南&lt;/h2&gt;
&lt;h3&gt;9.1 从 React 18 升级&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 升级 React
npm install react@latest react-dom@latest

# 升级 Next.js（如使用）
npm install next@latest
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;9.2 迁移步骤&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;识别 Server Components&lt;/strong&gt;：将不需要交互的组件改为服务端组件&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;添加 &quot;use client&quot;&lt;/strong&gt;：为需要交互的组件添加标记&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;使用 Server Actions&lt;/strong&gt;：替换 API 路由&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;移除手动 memoization&lt;/strong&gt;：让 Compiler 自动优化&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;测试&lt;/strong&gt;：确保功能正常&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;9.3 常见问题&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;问题&lt;/th&gt;
&lt;th&gt;解决方案&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&quot;use client&quot; 忘记添加&lt;/td&gt;
&lt;td&gt;编译器会报错&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Server Action 权限&lt;/td&gt;
&lt;td&gt;添加权限检查&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;hydration 不匹配&lt;/td&gt;
&lt;td&gt;RSC 自动解决&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;第三方库不兼容&lt;/td&gt;
&lt;td&gt;使用 Client Component 包裹&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;10. 生态影响&lt;/h2&gt;
&lt;h3&gt;10.1 框架支持&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;框架&lt;/th&gt;
&lt;th&gt;RSC 支持&lt;/th&gt;
&lt;th&gt;状态&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Next.js 15&lt;/td&gt;
&lt;td&gt;✅ 默认支持&lt;/td&gt;
&lt;td&gt;生产就绪&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Remix 3&lt;/td&gt;
&lt;td&gt;✅ 支持&lt;/td&gt;
&lt;td&gt;生产就绪&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vite&lt;/td&gt;
&lt;td&gt;✅ 官方插件&lt;/td&gt;
&lt;td&gt;生产就绪&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gatsby&lt;/td&gt;
&lt;td&gt;❌ 不支持&lt;/td&gt;
&lt;td&gt;已停止维护&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;10.2 对开发者的影响&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;前端开发者需要掌握后端知识&lt;/strong&gt;：数据库、API 设计&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;全栈开发门槛降低&lt;/strong&gt;：无需额外搭建后端&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;性能优化更简单&lt;/strong&gt;：RSC 自动优化 bundle&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;10.3 对团队的影响&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;前后端联调成本降低&lt;/strong&gt;：直接数据库访问&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;部署架构变化&lt;/strong&gt;：需要支持 SSR/RSC 的部署平台&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;安全审查更严格&lt;/strong&gt;：Server Functions 需要安全审计&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;11. 未来展望&lt;/h2&gt;
&lt;h3&gt;11.1 React 路线图&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;React 20&lt;/strong&gt;：更强大的 Server Components&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Partial Prerendering&lt;/strong&gt;：混合静态和动态渲染&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Document Metadata&lt;/strong&gt;：更好的 SEO 支持&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;11.2 边缘计算集成&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Cloudflare Workers&lt;/strong&gt;：全球节点部署&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Vercel Edge Functions&lt;/strong&gt;：毫秒级响应&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;冷启动时间&lt;/strong&gt;：低至 5ms&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;12. 总结&lt;/h2&gt;
&lt;p&gt;React 19 的发布标志着前端开发进入了一个新时代：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Server Components 成为默认架构&lt;/strong&gt;：性能大幅提升&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Server Actions 简化全栈开发&lt;/strong&gt;：无需 API 层&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;React Compiler 自动优化&lt;/strong&gt;：减少手动优化工作&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;新 Hooks API 更强大&lt;/strong&gt;：useActionState、useOptimistic 等&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;如果你还在使用 React 18，强烈建议升级到 React 19。RSC 带来的性能提升和开发体验改善是实实在在的。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;参考资料&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://react.dev/blog/2026/03/react-19&quot;&gt;React 19 官方公告&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://react.dev/reference/rsc&quot;&gt;React Server Components 文档&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://react.dev/learn/react-compiler&quot;&gt;React Compiler 指南&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nextjs.org/blog/next-15&quot;&gt;Next.js 15 发布说明&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://juejin.cn/post/7626192281234309147&quot;&gt;2026 前端技术趋势解析&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Vite 8 正式发布：Rust 驱动的前端工业革命</title><link>https://www.hehonglei.cn/posts/vite-8-release/</link><guid isPermaLink="true">https://www.hehonglei.cn/posts/vite-8-release/</guid><description>Vite 8 正式发布，这是第一个使用 Rust 打包器 Rolldown 驱动的稳定版本。构建速度暴涨 10 倍，统一开发和构建流程，标志着前端工程化进入新纪元。</description><pubDate>Mon, 20 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;1. 引言&lt;/h2&gt;
&lt;p&gt;2026年，前端构建工具领域迎来了一个里程碑式的时刻——&lt;strong&gt;Vite 8 正式发布&lt;/strong&gt;。这是第一个使用 Rust 打包器 Rolldown 驱动的稳定版本，标志着前端工程化正式进入 Rust 时代。&lt;/p&gt;
&lt;p&gt;Vite 团队官宣，Vite 8 将底层的 &lt;code&gt;esbuild + rollup&lt;/code&gt; 双打包机制替换为 &lt;code&gt;Oxc + Rolldown&lt;/code&gt;，构建速度暴涨 &lt;strong&gt;10 倍&lt;/strong&gt;，同时彻底解决了长期存在的开发与构建不一致性问题。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;2. 为什么需要 Vite 8？&lt;/h2&gt;
&lt;h3&gt;2.1 Vite 7 及之前的架构痛点&lt;/h3&gt;
&lt;p&gt;在 Vite 8 之前，Vite 采用双打包机制：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;阶段&lt;/th&gt;
&lt;th&gt;工具&lt;/th&gt;
&lt;th&gt;语言&lt;/th&gt;
&lt;th&gt;特点&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;开发服务器&lt;/td&gt;
&lt;td&gt;esbuild&lt;/td&gt;
&lt;td&gt;Go&lt;/td&gt;
&lt;td&gt;快速编译，不打包&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;生产构建&lt;/td&gt;
&lt;td&gt;Rollup&lt;/td&gt;
&lt;td&gt;JavaScript&lt;/td&gt;
&lt;td&gt;优化打包，速度较慢&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;这种架构虽然在当时是最佳选择，但存在一个根本性问题：&lt;strong&gt;&quot;天衣有缝&quot;&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;两种流程始终存在不一致性：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;开发时能运行的代码，构建后可能报错&lt;/li&gt;
&lt;li&gt;插件在开发和构建阶段的行为可能不同&lt;/li&gt;
&lt;li&gt;开发者需要同时维护两套配置逻辑&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2.2 Rust 工具链的崛起&lt;/h3&gt;
&lt;p&gt;与此同时，Rust 在前端工具链领域迅速崛起：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;esbuild&lt;/strong&gt;（Go）已经证明了编译型语言在构建工具上的性能优势&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Turbopack&lt;/strong&gt;（Rust）展示了增量编译的可能性&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rspack&lt;/strong&gt;（Rust）证明了兼容 Webpack 生态的同时可以获得极致性能&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Rust 以 &lt;strong&gt;32%&lt;/strong&gt; 的项目占比，成为系统工具开发的首选语言。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;3. Rolldown：统一 Vite 的核心引擎&lt;/h2&gt;
&lt;h3&gt;3.1 什么是 Rolldown？&lt;/h3&gt;
&lt;p&gt;Rolldown 是由 Vite 作者尤雨溪发起的项目，目标是&lt;strong&gt;用 Rust 重写 Rollup&lt;/strong&gt;，实现：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;兼容 Rollup 插件 API&lt;/strong&gt;：无缝迁移现有生态&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;媲美 esbuild 的性能&lt;/strong&gt;：极致的构建速度&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;统一开发和构建流程&lt;/strong&gt;：消除不一致性&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;3.2 Rolldown 的技术优势&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;Rolldown 架构
├── Rust 核心引擎
│   ├── 快速解析
│   ├── 高效转换
│   └── 优化打包
├── Rollup 插件兼容层
│   ├── 插件 API 映射
│   └── 钩子系统适配
└── Vite 集成
    ├── 开发服务器
    └── 生产构建
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;性能对比&lt;/strong&gt;：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;指标&lt;/th&gt;
&lt;th&gt;Vite 7 (esbuild + Rollup)&lt;/th&gt;
&lt;th&gt;Vite 8 (Rolldown)&lt;/th&gt;
&lt;th&gt;提升&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;冷启动&lt;/td&gt;
&lt;td&gt;~500ms&lt;/td&gt;
&lt;td&gt;~50ms&lt;/td&gt;
&lt;td&gt;10x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HMR&lt;/td&gt;
&lt;td&gt;~100ms&lt;/td&gt;
&lt;td&gt;~10ms&lt;/td&gt;
&lt;td&gt;10x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;生产构建&lt;/td&gt;
&lt;td&gt;~30s&lt;/td&gt;
&lt;td&gt;~3s&lt;/td&gt;
&lt;td&gt;10x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;内存占用&lt;/td&gt;
&lt;td&gt;~500MB&lt;/td&gt;
&lt;td&gt;~200MB&lt;/td&gt;
&lt;td&gt;60%↓&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;4. Vite 8 新特性详解&lt;/h2&gt;
&lt;h3&gt;4.1 开发体验提升&lt;/h3&gt;
&lt;h4&gt;Vite Devtools&lt;/h4&gt;
&lt;p&gt;新增内置的开发工具，可以直接从开发服务器调试应用：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;组件树查看&lt;/li&gt;
&lt;li&gt;状态检查&lt;/li&gt;
&lt;li&gt;性能分析&lt;/li&gt;
&lt;li&gt;网络请求监控&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;浏览器控制台转发&lt;/h4&gt;
&lt;p&gt;支持将浏览器控制台输出转发到 CLI 终端，方便 AI 分析：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 终端中直接看到浏览器 console.log
$ pnpm dev

[vite] Browser console:
  → Component rendered in 12ms
  → API response: 200 OK
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.2 内置 TypeScript 支持&lt;/h3&gt;
&lt;p&gt;Vite 8 原生支持 TypeScript，无需额外配置：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// tsconfig.json
{
  &quot;compilerOptions&quot;: {
    &quot;paths&quot;: {
      &quot;@/*&quot;: [&quot;./src/*&quot;]  // ✅ Vite 8 原生支持
    },
    &quot;emitDecoratorMetadata&quot;: true  // ✅ 无需外部插件
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.3 @vitejs/plugin-react v6&lt;/h3&gt;
&lt;p&gt;React 插件迎来重大更新：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;集成 Oxc&lt;/strong&gt;：不再依赖 Babel&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;更快的编译速度&lt;/strong&gt;：Rust 驱动的转换&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;更小的依赖体积&lt;/strong&gt;：减少 node_modules 大小&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;// vite.config.ts
import { defineConfig } from &apos;vite&apos;;
import react from &apos;@vitejs/plugin-react&apos;;

export default defineConfig({
  plugins: [react()],  // 自动使用 Oxc 转换
});
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.4 WASM 支持增强&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;.wasm?init&lt;/code&gt; 导入现在可以在 SSR 环境运行：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// 客户端和 SSR 都能正常工作
import init from &apos;./module.wasm?init&apos;;

const instance = await init();
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.5 Vite Plugin 官网&lt;/h3&gt;
&lt;p&gt;新增 &lt;a href=&quot;https://vitejs.dev/plugins&quot;&gt;Vite Plugin 官网&lt;/a&gt;，方便搜索 Vite 生态的插件。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;5. 迁移指南&lt;/h2&gt;
&lt;h3&gt;5.1 升级步骤&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 1. 升级 Vite
npm install vite@latest

# 2. 升级 React 插件
npm install @vitejs/plugin-react@latest

# 3. 检查插件兼容性
npx vite --config vite.config.ts
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.2  breaking changes&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;变更&lt;/th&gt;
&lt;th&gt;影响&lt;/th&gt;
&lt;th&gt;解决方案&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;移除 esbuild&lt;/td&gt;
&lt;td&gt;部分 esbuild 特定配置失效&lt;/td&gt;
&lt;td&gt;使用 Rolldown 配置&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Babel 移除&lt;/td&gt;
&lt;td&gt;@vitejs/plugin-react 不再使用 Babel&lt;/td&gt;
&lt;td&gt;更新 Babel 配置为 Oxc 兼容&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;插件 API 调整&lt;/td&gt;
&lt;td&gt;少数插件可能需要更新&lt;/td&gt;
&lt;td&gt;联系插件作者&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;5.3 配置示例&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;// vite.config.ts
import { defineConfig } from &apos;vite&apos;;
import react from &apos;@vitejs/plugin-react&apos;;
import vue from &apos;@vitejs/plugin-vue&apos;;

export default defineConfig({
  plugins: [
    react(),  // 或 vue()
  ],
  
  // Vite 8 新配置
  future: {
    v6devTransformer: true,  // 启用新转换器
  },
  
  // Rolldown 构建配置
  build: {
    rollupOptions: {
      output: {
        format: &apos;es&apos;,
        sourcemap: true,
      },
    },
  },
});
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;6. 生态影响&lt;/h2&gt;
&lt;h3&gt;6.1 对开发者的影响&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;更快的开发体验&lt;/strong&gt;：HMR 降至 ~10ms，几乎即时反馈&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;更一致的构建&lt;/strong&gt;：开发和构建使用同一引擎&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;更简单的配置&lt;/strong&gt;：无需维护两套配置&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;6.2 对框架的影响&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;框架&lt;/th&gt;
&lt;th&gt;影响&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Vue&lt;/td&gt;
&lt;td&gt;Nuxt 已适配 Vite 8，性能显著提升&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;React&lt;/td&gt;
&lt;td&gt;Next.js、Remix 等框架将受益于更快的构建&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Svelte&lt;/td&gt;
&lt;td&gt;SvelteKit 构建速度提升明显&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;6.3 对插件生态的影响&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;现有 Rollup 插件大多兼容&lt;/li&gt;
&lt;li&gt;新插件可以直接使用 Rolldown API&lt;/li&gt;
&lt;li&gt;插件性能普遍提升 5-10 倍&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;7. 性能实测&lt;/h2&gt;
&lt;h3&gt;7.1 测试项目&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;项目类型&lt;/strong&gt;：中大型 React 应用&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;组件数量&lt;/strong&gt;：~500&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;代码行数&lt;/strong&gt;：~100,000&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;依赖数量&lt;/strong&gt;：~80&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;7.2 测试结果&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;操作&lt;/th&gt;
&lt;th&gt;Vite 7&lt;/th&gt;
&lt;th&gt;Vite 8&lt;/th&gt;
&lt;th&gt;提升&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;冷启动&lt;/td&gt;
&lt;td&gt;1.2s&lt;/td&gt;
&lt;td&gt;0.15s&lt;/td&gt;
&lt;td&gt;8x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HMR&lt;/td&gt;
&lt;td&gt;150ms&lt;/td&gt;
&lt;td&gt;12ms&lt;/td&gt;
&lt;td&gt;12.5x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;生产构建&lt;/td&gt;
&lt;td&gt;45s&lt;/td&gt;
&lt;td&gt;4.2s&lt;/td&gt;
&lt;td&gt;10.7x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;内存峰值&lt;/td&gt;
&lt;td&gt;680MB&lt;/td&gt;
&lt;td&gt;220MB&lt;/td&gt;
&lt;td&gt;67%↓&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;8. 未来展望&lt;/h2&gt;
&lt;h3&gt;8.1 VoidZero 计划&lt;/h3&gt;
&lt;p&gt;尤雨溪领导的 VoidZero 计划正在推进：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Rolldown&lt;/strong&gt;：统一构建工具&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Oxc&lt;/strong&gt;：快速 JavaScript 工具链&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nuxt 收购&lt;/strong&gt;：扩展 Vue 生态&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;8.2 Rust 工具链趋势&lt;/h3&gt;
&lt;p&gt;2026 年前端工具链 Rust 化已成定局：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;工具&lt;/th&gt;
&lt;th&gt;语言&lt;/th&gt;
&lt;th&gt;状态&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Rolldown&lt;/td&gt;
&lt;td&gt;Rust&lt;/td&gt;
&lt;td&gt;✅ Vite 8 采用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Turbopack&lt;/td&gt;
&lt;td&gt;Rust&lt;/td&gt;
&lt;td&gt;✅ Next.js 采用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rspack&lt;/td&gt;
&lt;td&gt;Rust&lt;/td&gt;
&lt;td&gt;✅ 字节跳动开源&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Biome&lt;/td&gt;
&lt;td&gt;Rust&lt;/td&gt;
&lt;td&gt;✅ ESLint/Prettier 替代&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lightning CSS&lt;/td&gt;
&lt;td&gt;Rust&lt;/td&gt;
&lt;td&gt;✅ Vite 采用&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;9. 总结&lt;/h2&gt;
&lt;p&gt;Vite 8 的发布不仅仅是一个版本号的更新，它代表了前端工程化的一个重要转折点：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Rust 成为基础设施语言&lt;/strong&gt;：性能不再是瓶颈&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;统一架构消除不一致性&lt;/strong&gt;：开发体验更流畅&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AI 友好&lt;/strong&gt;：控制台转发、更快的反馈循环&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;如果你还在使用 Vite 7 或更早版本，强烈建议升级到 Vite 8。构建速度的提升是实实在在的，而且迁移成本很低。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;参考资料&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://vitejs.dev/blog/&quot;&gt;Vite 8 官方公告&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/rolldown/rolldown&quot;&gt;Rolldown GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://voidzero.dev/&quot;&gt;VoidZero 计划&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://juejin.cn/post/7626192281234309147&quot;&gt;2026 前端技术趋势解析&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>TypeScript 6.0 正式发布：最后一个 JS 版本，为 Go 原生 7.0 铺路</title><link>https://www.hehonglei.cn/posts/typescript-6-0-release/</link><guid isPermaLink="true">https://www.hehonglei.cn/posts/typescript-6-0-release/</guid><description>TypeScript 6.0 正式发布，这是基于 JavaScript 代码库构建的最后一个主版本。strict 默认开启、types 默认清空、ES2025 支持、Temporal API，同时为即将到来的 Go 重写版 TypeScript 7.0 铺平道路。</description><pubDate>Mon, 23 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;1. 引言&lt;/h2&gt;
&lt;p&gt;2026年3月23日，微软正式发布了 &lt;strong&gt;TypeScript 6.0&lt;/strong&gt;，由 TypeScript 首席产品经理 Daniel Rosenwasser 在官方 DevBlog 上宣布。这是 TypeScript 发展历程中一个承前启后的&lt;strong&gt;里程碑版本&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;TypeScript 6.0 有一个非常特殊的身份——&lt;strong&gt;这是基于现有 JavaScript 代码库构建的最后一个主版本&lt;/strong&gt;。微软已确认，TypeScript 7.0 将使用 &lt;strong&gt;Go 语言&lt;/strong&gt;全面重写编译器和语言服务，代号 &lt;strong&gt;&quot;Project Corsa&quot;&lt;/strong&gt;，预计编译速度将&lt;strong&gt;提升 10 倍&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;TypeScript 6.0 的核心使命是：在彻底迁移到 Go 原生编译器之前，尽可能多地清理历史债务、调整默认行为、引入新的类型系统能力，让开发者&lt;strong&gt;平稳过渡&lt;/strong&gt;到即将到来的 TypeScript 7.0 时代。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;2. 核心定位：承前启后的「桥梁版本」&lt;/h2&gt;
&lt;h3&gt;2.1 为什么是最后一个 JS 版本？&lt;/h3&gt;
&lt;p&gt;TypeScript 自诞生以来，编译器一直使用 TypeScript/JavaScript 自举实现。随着项目规模的增长和用户基数的膨胀（全球超过 &lt;strong&gt;1000 万&lt;/strong&gt;开发者），JS 单线程性能瓶颈日益凸显。&lt;/p&gt;
&lt;p&gt;微软在 2025 年启动了 &lt;strong&gt;Project Corsa&lt;/strong&gt;——使用 Go 语言重写 TypeScript 编译器核心：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;维度&lt;/th&gt;
&lt;th&gt;当前 JS 编译器&lt;/th&gt;
&lt;th&gt;即将到来的 Go 编译器&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;并发模型&lt;/td&gt;
&lt;td&gt;单线程 + Worker&lt;/td&gt;
&lt;td&gt;共享内存多线程&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;编译速度&lt;/td&gt;
&lt;td&gt;基准线&lt;/td&gt;
&lt;td&gt;提升 &lt;strong&gt;10 倍&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;内存效率&lt;/td&gt;
&lt;td&gt;JS GC 管理&lt;/td&gt;
&lt;td&gt;原生内存管理&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LSP 响应&lt;/td&gt;
&lt;td&gt;取决于项目大小&lt;/td&gt;
&lt;td&gt;极低延迟&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;2.2 7.0 的开发进度&lt;/h3&gt;
&lt;p&gt;TypeScript 7.0 已经&quot;非常接近完成&quot;，Nightly Build 可通过以下方式提前体验：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm install -D @typescript/native-preview
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;同时 VS Code 用户可安装对应的 Nightly 扩展，在大型代码库上测试 Go 原生编译器的实际表现。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;3. 全新特性&lt;/h2&gt;
&lt;h3&gt;3.1 &lt;code&gt;es2025&lt;/code&gt; Target / Lib&lt;/h3&gt;
&lt;p&gt;TypeScript 6.0 新增了 &lt;code&gt;es2025&lt;/code&gt; 作为编译目标和库选项。&lt;code&gt;es2025&lt;/code&gt; 类型的核心内容来自已进入 &lt;strong&gt;Stage 4&lt;/strong&gt; 的 TC39 提案：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;RegExp.escape()&lt;/code&gt;&lt;/strong&gt;：安全转义正则表达式中的特殊字符&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;Promise.try()&lt;/code&gt;&lt;/strong&gt;：统一同步/异步函数调用的 Promise 包装&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Iterator 辅助方法&lt;/strong&gt;：&lt;code&gt;Iterator.prototype.map/filter/take/drop&lt;/code&gt; 等链式操作&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Set 方法&lt;/strong&gt;：&lt;code&gt;Set.prototype.union/intersection/difference/symmetricDifference&lt;/code&gt; 等集合运算&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;// es2025 新增能力示例
const escaped = RegExp.escape(&quot;foo.bar&quot;);  // &quot;foo\\.bar&quot;

const result = await Promise.try(() =&amp;gt; mayThrow());

const nums = new Set([1, 2, 3]);
const evens = new Set([2, 4, 6]);
const union = nums.union(evens);  // Set {1, 2, 3, 4, 6}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.2 Temporal API 类型支持&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;Temporal&lt;/code&gt; API 已进入 Stage 4，将成为 JavaScript 标准的日期时间处理方案。TypeScript 6.0 通过 &lt;code&gt;esnext.temporal&lt;/code&gt; lib 提供完整类型支持：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Temporal API — 现代 JavaScript 日期处理
const now = Temporal.Now.plainDateTimeISO();
const meeting = now.add({ hours: 2, minutes: 30 });

const duration = meeting.since(now);
console.log(duration.toString()); // &quot;PT2H30M&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.3 Map &quot;Upsert&quot; 方法&lt;/h3&gt;
&lt;p&gt;TypeScript 6.0 为 &lt;code&gt;Map&lt;/code&gt; 新增了两个实用的类型方法：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;getOrInsert(key, value)&lt;/code&gt;&lt;/strong&gt;：键不存在时插入默认值并返回&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;getOrInsertComputed(key, factory)&lt;/code&gt;&lt;/strong&gt;：键不存在时通过工厂函数计算并插入&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;const cache = new Map&amp;lt;string, number[]&amp;gt;();

// 传统写法
let items = cache.get(&quot;key&quot;);
if (!items) {
  items = [];
  cache.set(&quot;key&quot;, items);
}

// 6.0 新写法
const items = cache.getOrInsertComputed(&quot;key&quot;, () =&amp;gt; []);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.4 Subpath Imports (&lt;code&gt;#/&lt;/code&gt;)&lt;/h3&gt;
&lt;p&gt;TypeScript 6.0 在 &lt;code&gt;nodenext&lt;/code&gt; 和 &lt;code&gt;bundler&lt;/code&gt; 模块解析模式下，正式支持 Node.js 风格的包内导入路径：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// package.json
{
  &quot;imports&quot;: {
    &quot;#utils/*&quot;: &quot;./src/utils/*.ts&quot;,
    &quot;#components/*&quot;: &quot;./src/components/*.ts&quot;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// 使用 # 前缀简洁导入
import { formatDate } from &quot;#utils/date&quot;;
import { Button } from &quot;#components/Button&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.5 &lt;code&gt;--stableTypeOrdering&lt;/code&gt; 标志&lt;/h3&gt;
&lt;p&gt;TypeScript 6.0 新增了 &lt;code&gt;--stableTypeOrdering&lt;/code&gt; 迁移诊断标志。启用后，6.0 的类型排序算法与 7.0 的&lt;strong&gt;确定性排序算法&lt;/strong&gt;保持一致。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;⚠️ 注意：此标志可能导致类型检查速度降低 &lt;strong&gt;25%&lt;/strong&gt;，仅在准备迁移到 7.0 时使用。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;3.6 DOM 类型合并&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;dom.iterable&lt;/code&gt; 和 &lt;code&gt;dom.asynciterable&lt;/code&gt; 的内容已合并入 &lt;code&gt;dom&lt;/code&gt; lib，开发者不再需要为可迭代 DOM 类型单独声明。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;4. 重大 Breaking Changes&lt;/h2&gt;
&lt;h3&gt;4.1 默认值变更一览&lt;/h3&gt;
&lt;p&gt;这是 TypeScript 6.0 中影响最为广泛的变更——&lt;strong&gt;多个历史默认值被一举翻转&lt;/strong&gt;：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;配置项&lt;/th&gt;
&lt;th&gt;旧默认值&lt;/th&gt;
&lt;th&gt;新默认值&lt;/th&gt;
&lt;th&gt;影响&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;strict&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;false&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;true&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;所有严格检查默认开启&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;types&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;自动爬取 &lt;code&gt;@types&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;[]&lt;/code&gt;（空数组）&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;不再自动加载全局类型&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;module&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;commonjs&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;esnext&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;默认输出 ESM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;target&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;es5&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;es2025&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;默认目标最新标准&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rootDir&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;自动推断&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;.&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;输出结构明确控制&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;4.2 &lt;code&gt;types: []&lt;/code&gt; 的巨大影响&lt;/h3&gt;
&lt;p&gt;最受关注的变化当属 &lt;code&gt;types&lt;/code&gt; 默认值改为空数组。这意味着 &lt;strong&gt;&lt;code&gt;@types&lt;/code&gt; 包不再被自动发现并加载&lt;/strong&gt;，需要通过 &lt;code&gt;types&lt;/code&gt; 字段显式声明。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;微软团队透露，部分项目的冷构建时间因此缩短了 20%-50%。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;升级后必须立即检查 &lt;code&gt;tsconfig.json&lt;/code&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;compilerOptions&quot;: {
    &quot;types&quot;: [&quot;node&quot;]  // 必须显式声明
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;否则会出现大量 &lt;code&gt;Cannot find name &apos;console&apos;&lt;/code&gt;、&lt;code&gt;Cannot find name &apos;process&apos;&lt;/code&gt; 等标识符缺失错误。&lt;/p&gt;
&lt;h3&gt;4.3 &lt;code&gt;rootDir&lt;/code&gt; 默认改为 &lt;code&gt;.&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;这一变更会影响输出目录结构：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 旧行为（rootDir 自动推断为 src/）
# 输出：dist/index.js

# 新行为（rootDir 默认为 .）
# 输出：dist/src/index.js   ← 多了一层！
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;升级时建议显式设置：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;compilerOptions&quot;: {
    &quot;rootDir&quot;: &quot;./src&quot;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.4 &lt;code&gt;strict: true&lt;/code&gt; 默认开启&lt;/h3&gt;
&lt;p&gt;TypeScript 6.0 默认开启 &lt;code&gt;strict: true&lt;/code&gt;，这意味着以下所有子选项均默认启用：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;strictNullChecks&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;strictBindCallApply&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;strictFunctionTypes&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;strictPropertyInitialization&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;noImplicitAny&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;noImplicitThis&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;alwaysStrict&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;useUnknownInCatchVariables&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你的项目之前未启用 strict 模式，升级后可能会看到大量新的类型错误。&lt;strong&gt;大多数错误是合理的&lt;/strong&gt;，反映了代码中潜在的 bug。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;5. 已弃用配置（7.0 中将彻底移除）&lt;/h2&gt;
&lt;p&gt;TypeScript 6.0 中标记为&lt;strong&gt;弃用&lt;/strong&gt;的选项，将在 &lt;strong&gt;7.0 中彻底移除&lt;/strong&gt;。开发者应尽早迁移：&lt;/p&gt;
&lt;h3&gt;5.1 编译器选项&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;弃用项&lt;/th&gt;
&lt;th&gt;替代方案&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;target: es5&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;使用 &lt;code&gt;es2015&lt;/code&gt; 或更高版本&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--downlevelIteration&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;配合新 target 使用原生迭代&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;module: amd / umd / systemjs&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;使用 &lt;code&gt;esnext&lt;/code&gt; 或其他标准模块格式&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--moduleResolution node&lt;/code&gt; (node10)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;node16&lt;/code&gt; / &lt;code&gt;nodenext&lt;/code&gt; / &lt;code&gt;bundler&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--moduleResolution classic&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;任何现代解析策略&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--baseUrl&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;使用 &lt;code&gt;paths&lt;/code&gt; 替代&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--outFile&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;使用打包工具&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--esModuleInterop false&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;统一启用 &lt;code&gt;esModuleInterop&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--allowSyntheticDefaultImports false&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;统一启用默认导入&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--alwaysStrict false&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;遵守新的 &lt;code&gt;strict&lt;/code&gt; 默认值&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;5.2 语法弃用&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;模块命名空间语法&lt;/strong&gt;：&lt;code&gt;module Foo { }&lt;/code&gt; → 使用 &lt;code&gt;namespace Foo { }&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Import Assertions&lt;/strong&gt;：&lt;code&gt;import ... assert { type: &quot;json&quot; }&lt;/code&gt; → 使用 &lt;code&gt;import ... with { type: &quot;json&quot; }&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;5.3 如何应对&lt;/h3&gt;
&lt;p&gt;在 6.0 中，可通过配置暂时抑制弃用错误：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;compilerOptions&quot;: {
    &quot;ignoreDeprecations&quot;: &quot;6.0&quot;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;但请注意：&lt;strong&gt;7.0 将完全不再支持这些选项&lt;/strong&gt;，&lt;code&gt;ignoreDeprecations: &quot;6.0&quot;&lt;/code&gt; 届时也将失效。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;6. 升级指南&lt;/h2&gt;
&lt;h3&gt;6.1 最小化迁移步骤&lt;/h3&gt;
&lt;p&gt;将现有项目升级到 TypeScript 6.0 的建议流程：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 1. 升级 TypeScript
npm install -D typescript@latest

# 2. 检查 TypeScript 版本
npx tsc --version
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.2 必需配置调整&lt;/h3&gt;
&lt;p&gt;升级后，大多数项目需要&lt;strong&gt;立即进行两项配置调整&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;compilerOptions&quot;: {
    // 1. 显式声明类型来源（必须！）
    &quot;types&quot;: [&quot;node&quot;],

    // 2. 显式设置 rootDir（否则输出结构错乱）
    &quot;rootDir&quot;: &quot;./src&quot;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.3 推荐迁移路径&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;现有项目
  ├── 升级至 TypeScript 6.0
  ├── 处理 strict 默认开启带来的新错误
  ├── 显式设置 types、rootDir
  ├── 逐一消除弃用警告
  ├── 配置新的 module/target 默认值
  ├── （可选）启用 --stableTypeOrdering 测试 7.0 兼容性
  └── 准备迎接 TypeScript 7.0 Go 编译器
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.4 在大型项目中渐进式迁移&lt;/h3&gt;
&lt;p&gt;对于大型代码库，建议：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;先在 CI 中单独运行 6.0 编译&lt;/strong&gt;，不阻塞主流程&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;逐步修复 strict 错误&lt;/strong&gt;，按文件或目录分批进行&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;使用 &lt;code&gt;ignoreDeprecations&lt;/code&gt; 争取时间&lt;/strong&gt;，但要有明确的消除计划&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;尝鲜 &lt;code&gt;@typescript/native-preview&lt;/code&gt;&lt;/strong&gt;，提前评估 7.0 的兼容性&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h2&gt;7. 发布历程与展望&lt;/h2&gt;
&lt;h3&gt;7.1 时间线&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;日期&lt;/th&gt;
&lt;th&gt;里程碑&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;2026年2月11日&lt;/td&gt;
&lt;td&gt;TypeScript 6.0 &lt;strong&gt;Beta&lt;/strong&gt; 发布&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026年3月6日&lt;/td&gt;
&lt;td&gt;TypeScript 6.0 &lt;strong&gt;RC&lt;/strong&gt; 发布&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;2026年3月23日&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;TypeScript 6.0 正式 GA&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;未来几个月&lt;/td&gt;
&lt;td&gt;TypeScript 7.0 稳定版预计发布&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;7.2 对 TypeScript 7.0 的展望&lt;/h3&gt;
&lt;p&gt;TypeScript 7.0 将是一次&lt;strong&gt;彻底的编译器重写&lt;/strong&gt;——不是增量改进，而是用 Go 语言重新构建整个编译管线：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;共享内存多线程&lt;/strong&gt;：充分利用多核 CPU，而非 Worker 线程通信&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;原生代码性能&lt;/strong&gt;：远离 JS GC，获得确定性的内存管理&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;10 倍编译速度&lt;/strong&gt;：大型项目的编译时间将从分钟级降至秒级&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;极低 LSP 延迟&lt;/strong&gt;：代码补全、错误提示、重构——一切都将更快&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;7.3 生态影响&lt;/h3&gt;
&lt;p&gt;TypeScript 的 Go 重写不仅仅是一次性能升级，更标志着 JavaScript 工具链的&lt;strong&gt;系统编程语言化&lt;/strong&gt;趋势：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;工具链演进趋势：
JavaScript → TypeScript（自举）→ Go/Rust/Zig（系统语言）

已完成 / 进行中：
✅ esbuild（Go）    — 极速打包器
✅ Rolldown（Rust） — Vite 8 底层
✅ Oxc（Rust）      — 高性能解析器
✅ Turbopack（Rust）— Next.js 打包
🔄 TypeScript（Go） — 编译器 7.0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这一趋势意味着，前端工程化正在从 &quot;够用即可&quot; 转向 &quot;原生性能&quot;，开发者体验将迎来质的飞跃。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;8. 总结&lt;/h2&gt;
&lt;p&gt;TypeScript 6.0 是一个&lt;strong&gt;大胆而务实&lt;/strong&gt;的版本：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;维度&lt;/th&gt;
&lt;th&gt;评价&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;新能力&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;ES2025、Temporal API、Subpath Imports——保持与标准同步&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;默认值翻转&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;strict/types/module/target——一次性清理历史包袱&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;弃用清理&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;移除过时的模块格式和解析策略——为 Go 重写减负&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;桥梁角色&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;stableTypeOrdering&lt;/code&gt;、&lt;code&gt;ignoreDeprecations&lt;/code&gt;——平滑过渡&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;TypeScript 6.0 是终点，也是起点。&lt;/strong&gt; 它终结了 TypeScript 的 JavaScript 自举时代，同时开启了 Go 原生编译器的全新时代。对于开发者而言，现在就该开始升级和适配——因为当 TypeScript 7.0 到来时，你将站在一个&lt;strong&gt;快 10 倍的起跑线上&lt;/strong&gt;。&lt;/p&gt;
</content:encoded></item><item><title>Simple Guides for Fuwari</title><link>https://www.hehonglei.cn/posts/guide/</link><guid isPermaLink="true">https://www.hehonglei.cn/posts/guide/</guid><description>How to use this blog template.</description><pubDate>Mon, 01 Apr 2024 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;Cover image source: &lt;a href=&quot;https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/208fc754-890d-4adb-9753-2c963332675d/width=2048/01651-1456859105-(colour_1.5),girl,_Blue,yellow,green,cyan,purple,red,pink,_best,8k,UHD,masterpiece,male%20focus,%201boy,gloves,%20ponytail,%20long%20hair,.jpeg&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This blog template is built with &lt;a href=&quot;https://astro.build/&quot;&gt;Astro&lt;/a&gt;. For the things that are not mentioned in this guide, you may find the answers in the &lt;a href=&quot;https://docs.astro.build/&quot;&gt;Astro Docs&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Front-matter of Posts&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;---
title: My First Blog Post
published: 2023-09-09
description: This is the first post of my new Astro blog.
image: ./cover.jpg
tags: [Foo, Bar]
category: Front-end
draft: false
---
&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Attribute&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;title&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The title of the post.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;published&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The date the post was published.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;description&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A short description of the post. Displayed on index page.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;image&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The cover image path of the post.&amp;lt;br/&amp;gt;1. Start with &lt;code&gt;http://&lt;/code&gt; or &lt;code&gt;https://&lt;/code&gt;: Use web image&amp;lt;br/&amp;gt;2. Start with &lt;code&gt;/&lt;/code&gt;: For image in &lt;code&gt;public&lt;/code&gt; dir&amp;lt;br/&amp;gt;3. With none of the prefixes: Relative to the markdown file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tags&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The tags of the post.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;category&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The category of the post.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;draft&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;If this post is still a draft, which won&apos;t be displayed.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;Where to Place the Post Files&lt;/h2&gt;
&lt;p&gt;Your post files should be placed in &lt;code&gt;src/content/posts/&lt;/code&gt; directory. You can also create sub-directories to better organize your posts and assets.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;src/content/posts/
├── post-1.md
└── post-2/
    ├── cover.png
    └── index.md
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item></channel></rss>