Modern Web Guidance 如何实现代码库现代化,以及您为何应该这样做

大多数 Web 开发工作都不是从头开始的。这种情况发生在现有的代码库中,这些代码库积累了多年的旧版解决方法、polyfill 和 JavaScript 实用程序(自动调整大小、自定义复选框样式技巧、scrollHeight 监听器),用于处理浏览器现在原生处理的内容。但问题在于:旧代码不会中断。它能正常运行,所以没人提交 bug。重构工作代码(即使是旧代码)也需要信任,因此开发者不愿这样做也是可以理解的。

另一方面,如果不重构旧代码以使用现代 Web 功能,则会悄悄地增加软件包大小、页面响应速度和无障碍功能。更糟糕的是,当您在这些项目中使用编码智能体时,它们会复制周围的 2015 年惯例以及训练数据中的过时模式。

在构建新内容时,Modern Web Guidance 会引导智能体使用现代 Baseline 功能。对于现有代码,Modern Web Guidance 1.0 添加了现代化改造工作流,可扫描项目中的旧模式,并帮助智能体对其进行升级。

现代化改造工作流的作用

当您要求智能体对项目进行现代化改造时(或直接运行 legacy-scan 命令),其工作原理如下:

  • 确定性本地扫描:HTML、CSS、JavaScript/TypeScript、框架专用组件和 package.json 文件会使用抽象语法树 (AST)、DOM 和 CSS 解析器在本地快速扫描,无需调用 LLM 或消耗 token。
  • 旧版规则目录:如果扫描器在每次运行时标记过多内容,则会被忽略。我们在大约 45,000 个开源代码库中测试了候选规则,这些代码库被分成两半:规则在规则编写部分编写和调整,并在未见过的保留部分进行评分。我们舍弃的候选规则比保留的还要多,跳过了没有等效旧代码的功能,并淘汰了没有实际收益的纯语法替换(例如将有效的 + 或 ~ 同级选择器重写为 :has())。为了默认发布,规则必须在未见过的代码上达到至少 80% 的静态匹配器精确率和 90% 的验证后精确率。
  • 情境感知假正例过滤:每条规则匹配都附带明确的 keepWhen/dropWhen 评分标准。这会指示智能体评估周围的代码,并在呈现其发现结果之前舍弃有意设置的后备、CSS @supports 保护措施或类似内容。
  • 范围限定为高置信度旧版模式(且在不断增加):legacy-scan 会检查我们大约 200 个指南中的一部分(约 20%),在这些指南中,可以确定性地发现旧版代码,而不会出现假正例,并且我们会随着时间的推移扩大覆盖范围。对于目录中的其他内容,智能体会根据您的构建需求进行搜索和检索。

如何调用现代化改造工作流

如需使用 Modern Web Guidance 技能对代码进行现代化改造,需要使用 1.0 或更高版本。 使用 npm 或智能体的插件市场安装或更新它:

# Install Modern Web Guidance 1.0 in your project
npx modern-web-guidance@latest install

# Or update an existing installation
npx modern-web-guidance@latest update

由于现代化改造工作流是核心技能定义的一部分,因此您可以使用自然语言触发扫描器,只需让智能体在代码库或文件夹中检查“旧版模式”或进行“现代化改造”即可。

注意:如果仅命名单个组件,则会执行常规指南查找。

为便于演示,以下是扫描整个代码库的示例提示:

Modernize this repository using Modern Web Guidance. Scan our frontend files for legacy patterns, verify the findings, and propose a modernization plan before making any code edits.

您也可以将其指向特定文件夹:

Check src/components/forms for legacy web patterns that can be refactored to modern Baseline features.

虽然您目前可以在终端中手动运行 legacy-scan,但自动化 CI/CD 流水线集成目前正在开发中。

它会捕获并修复的示例模式

符合条件的规则针对四个领域的常见旧版反模式:表单和界面、对话框和控件、CSS 布局、排版和视觉设计以及安全性。下表列出了旧版模式示例及其现代替代模式:

网域 检测到旧版模式 现代替代方案
表单和界面 JS scrollHeight textarea 自动调整大小钩子 CSS field-sizing: content (form-fields-automatically-fit-contents)
表单和界面 输入 keydown 提交缺少 IME 保护的处理程序 if (e.isComposing || e.keyCode === 229) return; (ime-safe-enter-submit)
表单和界面 :invalid CSS 样式在加载时过早地设置了未轻触的输入 :user-invalid 和 :user-valid 伪类 (validate-input-after-interaction)
表单和界面 身份验证和结账表单中缺少 autocomplete 令牌 标准化的 autocomplete 值(autofill-sign-in-form、autofill-payment-form)
对话框和控件 e.target === dialog 个点击监听器会破坏拖动选择 <dialog closedby="any">,采用渐进增强的方式 (dialog)
对话框和控件 叠加层的命令式 addEventListener 点击监听器 声明式 popover 和 popovertarget 属性 (declarative-dialog-popover-control)
CSS 布局、排版和视觉设计 max-height: 9999px 个手风琴式折叠动画技巧 interpolate-size: allow-keywords 和 calc-size() (animate-to-intrinsic-sizes)
CSS 布局、排版和视觉设计 基于子级状态的 JS 父类切换 关系型 :has(:checked)/:has(:focus-visible) 选择器 (child-state-based-styling)
CSS 布局、排版和视觉设计 已复制 @media (prefers-color-scheme: dark) 个屏蔽设置 CSS light-dark() 函数(dark-mode、dark-mode-toggle)
安全 外部 CDN 脚本标记缺少子资源完整性 integrity 和 crossorigin="anonymous" 属性 (secure-external-subresources)

代码转换示例

收到提示后,您的编码代理可以通过现代化工作流将旧版反模式转换为现代反模式。以下是几个例子:

自动扩容的 <textarea> 元素

在每个 input 事件上测量 scrollHeight 的旧版 JavaScript 会强制执行布局抖动。这可能会导致性能问题,尤其是 Interaction to Next Paint (INP)。使用现代化工作流,您的代理可以修复该问题:

// Before: Imperative layout recalculation on every keystroke
textarea.addEventListener('input', () => {
  textarea.style.height = 'auto';
  textarea.style.height = `${textarea.scrollHeight}px`;
});

现在,您无需使用 JavaScript 即可实现此目的。现代化改造工作流会引导您的代理将其替换为 CSS:

/* After: Native declarative field sizing */
textarea {
  field-sizing: content;
  min-block-size: 3lh;
  max-block-size: 15lh;
}

声明式弹出式窗口

使用 JavaScript 事件监听器的自定义模态和弹出式窗口逻辑可以替换为标准 HTML 属性:

<!-- Before: a click listener that only calls showPopover() -->
<button id="openBtn">Open Menu</button>
<div id="menu" popover>Menu Content</div>
<script>
  openBtn.addEventListener('click', () => menu.showPopover());
</script>

<!-- After: declarative control, no JavaScript -->
<button popovertarget="menu">Open Menu</button>
<div id="menu" popover>Menu Content</div>

IME 安全 Enter 键提交

当用户使用日语、中文或韩语输入法 (IME) 输入内容时,未受保护的 Enter 键监听器会过早触发消息提交。

智能体添加了组合状态保护机制:

// Before: Fires mid-composition when confirming kanji/hanzi characters
textarea.addEventListener('keydown', (e) => {
  if (e.key === 'Enter' && !e.shiftKey) {
    e.preventDefault();
    sendMessage();
  }
});


// After: Accurately checks IME composition state
textarea.addEventListener('keydown', (e) => {
  if (e.key === 'Enter' && !e.shiftKey) {
    e.preventDefault();
    if (e.isComposing || e.keyCode === 229) return;
    sendMessage();
  }
});

运作方式:四步现代化改造工作流

重构现有应用中的工作代码需要信任,因为没有人希望出现自动流失或细微回归。这也是没有 --fix 标志的原因:即使是看似简单的现代化改造,也往往会变成跨层重构(例如删除命令式 JS 监听器或 npm 软件包,并将行为移至 HTML 和 CSS 中),并面临细微的行为和浏览器支持挑战。

而是由现代化改造工作流与编码代理一起运行一个四步循环:

  1. 扫描 (legacy-scan):代理会运行 npx modern-web-guidance legacy-scan <path> --json,该工具会预先筛选文件以查找相关子字符串,因此它只会针对候选文件和规则启动 AST、CSS 和 HTML 解析器。如果发现结果达到此阶段,则其不是假正例的可能性已经很高(约 92%)。每场比赛都包含一份针对代理的验证核对清单。
  2. 情境验证 (keepWhen/dropWhen):由于编码智能体已打开代码库,因此它会根据该规则的验证标准检查每个匹配项周围的代码。如果 scrollHeight 读取是虚拟化滚动的一部分,而不是 <textarea> 黑客攻击,或者如果 @supports 检查已经保护了该属性,则系统会静默丢弃该发现结果。
  3. 报告:智能体总结经过验证的发现结果(请注意,legacy-scan 涵盖具有确定性规则的指南子集,以及现代化改造计划 [如果您要求在进行修改之前先查看计划])。
  4. 指南检索、重构和测试验证:当收到现代化改造请求时,智能体会运行 npx modern-web-guidance retrieve <guide-id> 来提取适当的指南。它会根据指南的基准兼容性模式执行代码重构,并在修改后的文件上重新运行 legacy-scan <path>,同时运行项目的测试套件,以确认问题已解决。

试试看

无论是在终端中运行一次性 legacy-scan,还是让编码代理对旧模块进行现代化改造,现代化改造工作流都能帮助您偿还旧版 Web 平台债务,而不会产生传统 Linter 的干扰。

如果您想从静态代码现代化过渡到实时浏览器验证、基准测试和调试,请将 Modern Web Guidance 与面向智能体的 Chrome 开发者工具搭配使用。

后续步骤和资源