<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://oxc.rs</id>
    <title>The Oxidation Compiler Blog</title>
    <updated>2026-04-13T07:32:48.893Z</updated>
    <generator>https://github.com/jpmonette/feed</generator>
    <link rel="alternate" href="https://oxc.rs"/>
    <icon>https://cdn.jsdelivr.net/gh/oxc-project/oxc-assets/square.ico</icon>
    <rights>© 2026 VoidZero Inc. and Oxc contributors.</rights>
    <entry>
        <title type="html"><![CDATA[Oxlint 正式发布]]></title>
        <id>https://oxc.rs/blog/2023-12-12-announcing-oxlint</id>
        <link href="https://oxc.rs/blog/2023-12-12-announcing-oxlint"/>
        <updated>2023-12-12T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[<AppBlogPostHeader /><Alert type="info">
<p><strong>本文宣布 Oxlint 的初始正式发布版本。</strong> 对于具有更多显著功能和改进的最新稳定版本，请参阅 <a href="/blog/2025-06-10-oxlint-stable.html">Oxlint v1.0 稳定版公告</a>。</p>
</Alert>
<p>我们很高兴地宣布 oxlint 现在正式发布了！
这一里程碑标志着我们团队能够及时处理和甄别问题。</p>
<p>Oxlint 是一个 JavaScript linter，旨在捕获错误或无用的代码，默认情况下无需任何配置。</p>
<h2 id="如何使用" tabindex="-1">如何使用 <a class="header-anchor" href="#如何使用" aria-label="Permalink to “如何使用”">&#8203;</a></h2>
<p>在这个阶段，oxlint <strong>并非旨在完全取代 ESLint</strong>；当 ESLint 的速度成为工作流中的瓶颈时，它可作为一种增强手段。</p>
<p>为了更快的反馈循环，我们建议在 lint-staged 或 CI 设置中先运行 oxlint 再运行 ESLint，因为它在大型代码库上运行只需几秒钟。</p>
<p>要在您的 JavaScript / TypeScript 代码库中测试 oxlint，只需在仓库的根目录执行以下命令：</p>
<table><tbody><tr><td>npm</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;user-select:none;-webkit-user-select:none">$ </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">npx</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint@latest</span></span></code></pre>
</div></td></tr><tr><td>pnpm</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;user-select:none;-webkit-user-select:none">$ </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">pnpm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> dlx</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint@latest</span></span></code></pre>
</div></td></tr><tr><td>yarn</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;user-select:none;-webkit-user-select:none">$ </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">yarn</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> dlx</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint@latest</span></span></code></pre>
</div></td></tr><tr><td>bun</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;user-select:none;-webkit-user-select:none">$ </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">bunx</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint@latest</span></span></code></pre>
</div></td></tr><tr><td>deno</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;user-select:none;-webkit-user-select:none">$ </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">deno</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> run</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> npm:oxlint@latest</span></span></code></pre>
</div></td></tr></tbody></table>
<p>或者，参考 <a href="/docs/guide/usage/linter.html">安装指南</a> 获取详细说明。</p>
<h2 id="设计" tabindex="-1">设计 <a class="header-anchor" href="#设计" aria-label="Permalink to “设计”">&#8203;</a></h2>
<h3 id="比-eslint-快-50-100-倍" tabindex="-1">比 ESLint 快 50-100 倍 <a class="header-anchor" href="#比-eslint-快-50-100-倍" aria-label="Permalink to “比 ESLint 快 50-100 倍”">&#8203;</a></h3>
<p>在实际场景中，Shopify 报告称他们原本需要 75 分钟的 CI ESLint 运行现在只需 10 秒。</p>
<p>来自 Shopify DX 兼 Preact 创作者 Jason Miller：</p>
<blockquote>
<p>oxlint 对我们在 Shopify 来说是一个巨大的胜利。我们之前的 lint 设置运行需要 75 分钟，所以我们在 CI 中将其分散到 40+ 个 worker 上。</p>
<p>相比之下，oxlint 在单个 worker 上 lint 相同的代码库只需大约 10 秒，且输出更易于理解。</p>
<p>我们在迁移时甚至发现了一些被旧设置隐藏或跳过的问题！</p>
</blockquote>
<p>大部分性能提升源于 Oxlint 专为性能而设计，利用 Rust 和并行处理作为关键因素。</p>
<h3 id="专注于正确性的-lint" tabindex="-1">专注于正确性的 Lint <a class="header-anchor" href="#专注于正确性的-lint" aria-label="Permalink to “专注于正确性的 Lint”">&#8203;</a></h3>
<p>Oxlint 默认旨在识别错误、冗余或令人困惑的代码——优先保证正确性，而不是不必要的吹毛求疵的规则（分类为 <code>perf</code>、<code>suspicious</code>、<code>pedantic</code> 或 <code>style</code>），这些规则默认是禁用的。</p>
<h3 id="易于使用" tabindex="-1">易于使用 <a class="header-anchor" href="#易于使用" aria-label="Permalink to “易于使用”">&#8203;</a></h3>
<p>设置新的 JavaScript / TypeScript 代码库正变得日益复杂。
很有可能遇到工具之间的兼容性问题，从而导致浪费数小时的时间。</p>
<p>这就是为什么我们将 oxlint 设计为开箱即用的零配置；甚至不需要 Node.js。
大多数调整可以通过命令行完成，读取 ESLint 配置文件的功能目前正在进行中。</p>
<h3 id="增强的诊断信息" tabindex="-1">增强的诊断信息 <a class="header-anchor" href="#增强的诊断信息" aria-label="Permalink to “增强的诊断信息”">&#8203;</a></h3>
<p>理解 linter 消息可能具有挑战性。
Oxlint 旨在通过定位根本原因并提供有帮助的消息来简化这一点——消除了阅读冗长规则文档的需要，节省宝贵时间。</p>
<p>在 <a href="https://github.com/microsoft/vscode" target="_blank" rel="noreferrer">vscode 仓库</a> 中运行 <code>oxlint -D perf</code>：</p>
<img width="100%" src="https://github.com/oxc-project/oxc/assets/1430279/094a3b24-0433-42ae-aad2-48a7dec2b985" >
<h3 id="整合的规则" tabindex="-1">整合的规则 <a class="header-anchor" href="#整合的规则" aria-label="Permalink to “整合的规则”">&#8203;</a></h3>
<p>Oxlint 尚未提供插件系统，但我们正在积极整合来自流行插件的规则，如 TypeScript、React、Jest、Unicorn、JSX-a11y 和 Import。</p>
<p>我们认识到插件在 JavaScript 生态系统中的重要性，并且也在调查基于 DSL 的插件系统。</p>
<p>不过，您可能会欣赏独立的 linter——无需管理插件依赖列表，
浏览 <a href="https://github.com/antfu/eslint-ts-patch" target="_blank" rel="noreferrer">兼容性问题</a>，
或 <a href="https://github.com/import-js/eslint-plugin-import/pull/2504#issuecomment-1191057877" target="_blank" rel="noreferrer">因版本限制而使用分支插件</a>。</p>
]]></summary>
        <content type="html"><![CDATA[<AppBlogPostHeader /><Alert type="info">
<p><strong>本文宣布 Oxlint 的初始正式发布版本。</strong> 对于具有更多显著功能和改进的最新稳定版本，请参阅 <a href="/blog/2025-06-10-oxlint-stable.html">Oxlint v1.0 稳定版公告</a>。</p>
</Alert>
<p>我们很高兴地宣布 oxlint 现在正式发布了！
这一里程碑标志着我们团队能够及时处理和甄别问题。</p>
<p>Oxlint 是一个 JavaScript linter，旨在捕获错误或无用的代码，默认情况下无需任何配置。</p>
<h2 id="如何使用" tabindex="-1">如何使用 <a class="header-anchor" href="#如何使用" aria-label="Permalink to “如何使用”">&#8203;</a></h2>
<p>在这个阶段，oxlint <strong>并非旨在完全取代 ESLint</strong>；当 ESLint 的速度成为工作流中的瓶颈时，它可作为一种增强手段。</p>
<p>为了更快的反馈循环，我们建议在 lint-staged 或 CI 设置中先运行 oxlint 再运行 ESLint，因为它在大型代码库上运行只需几秒钟。</p>
<p>要在您的 JavaScript / TypeScript 代码库中测试 oxlint，只需在仓库的根目录执行以下命令：</p>
<table><tbody><tr><td>npm</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;user-select:none;-webkit-user-select:none">$ </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">npx</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint@latest</span></span></code></pre>
</div></td></tr><tr><td>pnpm</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;user-select:none;-webkit-user-select:none">$ </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">pnpm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> dlx</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint@latest</span></span></code></pre>
</div></td></tr><tr><td>yarn</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;user-select:none;-webkit-user-select:none">$ </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">yarn</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> dlx</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint@latest</span></span></code></pre>
</div></td></tr><tr><td>bun</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;user-select:none;-webkit-user-select:none">$ </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">bunx</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint@latest</span></span></code></pre>
</div></td></tr><tr><td>deno</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;user-select:none;-webkit-user-select:none">$ </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">deno</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> run</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> npm:oxlint@latest</span></span></code></pre>
</div></td></tr></tbody></table>
<p>或者，参考 <a href="/docs/guide/usage/linter.html">安装指南</a> 获取详细说明。</p>
<h2 id="设计" tabindex="-1">设计 <a class="header-anchor" href="#设计" aria-label="Permalink to “设计”">&#8203;</a></h2>
<h3 id="比-eslint-快-50-100-倍" tabindex="-1">比 ESLint 快 50-100 倍 <a class="header-anchor" href="#比-eslint-快-50-100-倍" aria-label="Permalink to “比 ESLint 快 50-100 倍”">&#8203;</a></h3>
<p>在实际场景中，Shopify 报告称他们原本需要 75 分钟的 CI ESLint 运行现在只需 10 秒。</p>
<p>来自 Shopify DX 兼 Preact 创作者 Jason Miller：</p>
<blockquote>
<p>oxlint 对我们在 Shopify 来说是一个巨大的胜利。我们之前的 lint 设置运行需要 75 分钟，所以我们在 CI 中将其分散到 40+ 个 worker 上。</p>
<p>相比之下，oxlint 在单个 worker 上 lint 相同的代码库只需大约 10 秒，且输出更易于理解。</p>
<p>我们在迁移时甚至发现了一些被旧设置隐藏或跳过的问题！</p>
</blockquote>
<p>大部分性能提升源于 Oxlint 专为性能而设计，利用 Rust 和并行处理作为关键因素。</p>
<h3 id="专注于正确性的-lint" tabindex="-1">专注于正确性的 Lint <a class="header-anchor" href="#专注于正确性的-lint" aria-label="Permalink to “专注于正确性的 Lint”">&#8203;</a></h3>
<p>Oxlint 默认旨在识别错误、冗余或令人困惑的代码——优先保证正确性，而不是不必要的吹毛求疵的规则（分类为 <code>perf</code>、<code>suspicious</code>、<code>pedantic</code> 或 <code>style</code>），这些规则默认是禁用的。</p>
<h3 id="易于使用" tabindex="-1">易于使用 <a class="header-anchor" href="#易于使用" aria-label="Permalink to “易于使用”">&#8203;</a></h3>
<p>设置新的 JavaScript / TypeScript 代码库正变得日益复杂。
很有可能遇到工具之间的兼容性问题，从而导致浪费数小时的时间。</p>
<p>这就是为什么我们将 oxlint 设计为开箱即用的零配置；甚至不需要 Node.js。
大多数调整可以通过命令行完成，读取 ESLint 配置文件的功能目前正在进行中。</p>
<h3 id="增强的诊断信息" tabindex="-1">增强的诊断信息 <a class="header-anchor" href="#增强的诊断信息" aria-label="Permalink to “增强的诊断信息”">&#8203;</a></h3>
<p>理解 linter 消息可能具有挑战性。
Oxlint 旨在通过定位根本原因并提供有帮助的消息来简化这一点——消除了阅读冗长规则文档的需要，节省宝贵时间。</p>
<p>在 <a href="https://github.com/microsoft/vscode" target="_blank" rel="noreferrer">vscode 仓库</a> 中运行 <code>oxlint -D perf</code>：</p>
<img width="100%" src="https://github.com/oxc-project/oxc/assets/1430279/094a3b24-0433-42ae-aad2-48a7dec2b985" >
<h3 id="整合的规则" tabindex="-1">整合的规则 <a class="header-anchor" href="#整合的规则" aria-label="Permalink to “整合的规则”">&#8203;</a></h3>
<p>Oxlint 尚未提供插件系统，但我们正在积极整合来自流行插件的规则，如 TypeScript、React、Jest、Unicorn、JSX-a11y 和 Import。</p>
<p>我们认识到插件在 JavaScript 生态系统中的重要性，并且也在调查基于 DSL 的插件系统。</p>
<p>不过，您可能会欣赏独立的 linter——无需管理插件依赖列表，
浏览 <a href="https://github.com/antfu/eslint-ts-patch" target="_blank" rel="noreferrer">兼容性问题</a>，
或 <a href="https://github.com/import-js/eslint-plugin-import/pull/2504#issuecomment-1191057877" target="_blank" rel="noreferrer">因版本限制而使用分支插件</a>。</p>
<hr>
<p>祝您 lint 愉快，节日快乐！</p>
<p>要开始使用，请遵循 <a href="/docs/guide/usage/linter.html">安装指南</a>，
了解更多关于 <a href="/docs/guide/introduction.html">oxc 项目</a>，
或在 <a href="https://news.ycombinator.com/item?id=38652887" target="_blank" rel="noreferrer">Hacker News</a> 上讨论。</p>
]]></content>
        <author>
            <name>Boshen</name>
            <uri>https://github.com/Boshen</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Oxlint Import 插件 Alpha 版]]></title>
        <id>https://oxc.rs/blog/2024-05-04-import-plugin-alpha</id>
        <link href="https://oxc.rs/blog/2024-05-04-import-plugin-alpha"/>
        <updated>2024-05-04T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[<AppBlogPostHeader /><p>我们很高兴宣布 <code>oxlint --import-plugin</code> 的 alpha 版本发布，它是 <a href="https://npmx.dev/package/eslint-plugin-import" target="_blank" rel="noreferrer"><code>eslint-plugin-import</code></a> 的移植版本。</p>
<p>此移植版本旨在解决与 <code>eslint-plugin-import</code> 相关的所有已知问题：</p>
<ul>
<li>性能 - 启用某些规则时执行时间超过一分钟</li>
<li>依赖大小 - 188 个依赖项，总计 30M</li>
<li>向后兼容性 - 需要 <a href="https://github.com/import-js/eslint-plugin-import/pull/2447#issuecomment-1117384140" target="_blank" rel="noreferrer">支持 Node.js v4.0.0</a></li>
<li>依赖兼容性 - 需要将其替换为 <a href="https://npmx.dev/package/eslint-plugin-import-x" target="_blank" rel="noreferrer"><code>eslint-plugin-import-x</code></a></li>
<li><a href="https://github.com/import-js/eslint-plugin-import/issues/2948" target="_blank" rel="noreferrer">升级到 ESLint v9</a></li>
</ul>
<h2 id="发布内容是什么" tabindex="-1">发布内容是什么？ <a class="header-anchor" href="#发布内容是什么" aria-label="Permalink to “发布内容是什么？”">&#8203;</a></h2>
<p>如果您的项目使用 ESM（ECMAScript 模块），预计此 alpha 版本可以正常工作。</p>
<p>如果需要通过 <a href="https://www.typescriptlang.org/tsconfig/#paths" target="_blank" rel="noreferrer">tsconfig.compilerOptions.paths</a> 配置路径别名（例如 <code>@/foo</code>），可以使用 <code>--tsconfig</code> 选项：</p>
<div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span>npx oxlint@latest --tsconfig ./tsconfig.json --import-plugin</span></span></code></pre>
</div><p>通过 <code>npx oxlint@latest --import-plugin</code> 默认启用的规则有：</p>
<ul>
<li><a href="https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/docs/rules/default.md" target="_blank" rel="noreferrer">default</a></li>
<li><a href="https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/docs/rules/named.md" target="_blank" rel="noreferrer">named</a></li>
<li><a href="https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/docs/rules/namespace.md" target="_blank" rel="noreferrer">namespace</a></li>
</ul>
<p>可以通过 <code>npx oxlint@latest --import-plugin -D rule-name</code> 选择性启用的规则有：</p>
<ul>
<li><a href="https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/docs/rules/no-named-as-default.md" target="_blank" rel="noreferrer">no-named-as-default</a></li>
<li><a href="https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/docs/rules/no-named-as-default-member.md" target="_blank" rel="noreferrer">no-named-as-default-member</a></li>
<li><a href="https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/docs/rules/no-self-import.md" target="_blank" rel="noreferrer">no-self-import</a></li>
<li><a href="https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/docs/rules/no-duplicates.md" target="_blank" rel="noreferrer">no-duplicates</a></li>
<li><a href="https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/docs/rules/no-amd.md" target="_blank" rel="noreferrer">no-amd</a></li>
<li><a href="https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/docs/rules/no-default-export.md" target="_blank" rel="noreferrer">no-default-export</a></li>
<li><a href="https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/docs/rules/no-cycle.md" target="_blank" rel="noreferrer">no-cycle</a></li>
</ul>
<p>这些规则也有所改进；例如，<code>no-cycle</code> 规则的诊断信息得到了改进：</p>
<div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span> ⚠ eslint-plugin-import(no-cycle): Dependency cycle detected</span></span>
<span class="line"><span>   ╭─[apps/web/playwright/lib/fixtures.ts:13:42]</span></span>
<span class="line"><span>12 │ import { createPaymentsFixture } from "../fixtures/payments";</span></span>
<span class="line"><span>13 │ import { createBookingPageFixture } from "../fixtures/regularBookings";</span></span>
<span class="line"><span>   ·                                          ─────────────────────────────</span></span>
<span class="line"><span>14 │ import { createRoutingFormsFixture } from "../fixtures/routingForms";</span></span>
<span class="line"><span>   ╰────</span></span>
<span class="line"><span> help: These paths form a cycle:</span></span>
<span class="line"><span>       -> ../fixtures/regularBookings - apps/web/playwright/fixtures/regularBookings.ts</span></span>
<span class="line"><span>       -> ./users - apps/web/playwright/fixtures/users.ts</span></span>
<span class="line"><span>       -> ../lib/testUtils - apps/web/playwright/lib/testUtils.ts</span></span>
<span class="line"><span>       -> ./fixtures - apps/web/playwright/lib/fixtures.ts</span></span></code></pre>
</div><p>这并不是一个很长的功能列表，但由于当前生态系统状态的复杂性，实现这些规则并确保它们正常工作需要大量的努力。</p>
<p>在过去的六个月里，我们利用业余时间工作，并成功完成了 <code>--import-plugin</code> 工作所需的所有先决条件：</p>
<ul>
<li>一个用于模块解析的 <a href="https://github.com/oxc-project/oxc-resolver" target="_blank" rel="noreferrer">resolver</a></li>
<li>一个小型 <a href="https://github.com/oxc-project/oxc/blob/main/crates/oxc_linter/src/service.rs" target="_blank" rel="noreferrer">&quot;runtime&quot;</a> 以最大化并行处理依赖文件</li>
<li>一个用于存储导入/导出信息的 <a href="https://github.com/oxc-project/oxc/blob/main/crates/oxc_syntax/src/module_record.rs" target="_blank" rel="noreferrer"><code>ModuleRecord</code></a> 数据结构，及其相应的 <a href="https://github.com/oxc-project/oxc/blob/main/crates/oxc_semantic/src/module_record/builder.rs" target="_blank" rel="noreferrer">builder</a></li>
</ul>
<h2 id="我如何提供帮助" tabindex="-1">我如何提供帮助？ <a class="header-anchor" href="#我如何提供帮助" aria-label="Permalink to “我如何提供帮助？”">&#8203;</a></h2>
<p>如果您是项目维护者（即配置工程师），并且没有时间和精力保持 ESLint 及其所有插件更新，您可以跟随 <a href="https://github.com/brooooooklyn" target="_blank" rel="noreferrer">@brooooooklyn</a> 的脚步，<a href="https://github.com/napi-rs/napi-rs/pull/2032" target="_blank" rel="noreferrer">在他所有的项目中用 oxlint 替换 ESLint</a>。</p>
<p>如果您是开源爱好者并愿意提供帮助，欢迎在 <a href="https://discord.gg/9uXCAwqQZW" target="_blank" rel="noreferrer">discord</a> 上与我们交谈，查看 <a href="https://github.com/oxc-project/oxc/issues/481" target="_blank" rel="noreferrer">linter 产品计划和进度问题</a>，或通过 <a href="https://github.com/oxc-project/oxc/issues/3161" target="_blank" rel="noreferrer">提议新的规则</a> 来帮助（那些被推迟的规则）。</p>
<p>如果您是工程经理，或者愿意将项目迁移到 oxlint（拥有 330 条规则且还在增长）以降低基础设施成本，您可以考虑 <a href="https://github.com/sponsors/Boshen" target="_blank" rel="noreferrer">赞助</a>，以便我们可以优先处理您的项目。</p>
<p>请记住 <code>oxlint</code> 目前是由社区驱动的，我相信只要有足够的资源，我们就可以在未来几个月内使 <code>--import-plugin</code> 普遍可用。</p>
]]></summary>
        <content type="html"><![CDATA[<AppBlogPostHeader /><p>我们很高兴宣布 <code>oxlint --import-plugin</code> 的 alpha 版本发布，它是 <a href="https://npmx.dev/package/eslint-plugin-import" target="_blank" rel="noreferrer"><code>eslint-plugin-import</code></a> 的移植版本。</p>
<p>此移植版本旨在解决与 <code>eslint-plugin-import</code> 相关的所有已知问题：</p>
<ul>
<li>性能 - 启用某些规则时执行时间超过一分钟</li>
<li>依赖大小 - 188 个依赖项，总计 30M</li>
<li>向后兼容性 - 需要 <a href="https://github.com/import-js/eslint-plugin-import/pull/2447#issuecomment-1117384140" target="_blank" rel="noreferrer">支持 Node.js v4.0.0</a></li>
<li>依赖兼容性 - 需要将其替换为 <a href="https://npmx.dev/package/eslint-plugin-import-x" target="_blank" rel="noreferrer"><code>eslint-plugin-import-x</code></a></li>
<li><a href="https://github.com/import-js/eslint-plugin-import/issues/2948" target="_blank" rel="noreferrer">升级到 ESLint v9</a></li>
</ul>
<h2 id="发布内容是什么" tabindex="-1">发布内容是什么？ <a class="header-anchor" href="#发布内容是什么" aria-label="Permalink to “发布内容是什么？”">&#8203;</a></h2>
<p>如果您的项目使用 ESM（ECMAScript 模块），预计此 alpha 版本可以正常工作。</p>
<p>如果需要通过 <a href="https://www.typescriptlang.org/tsconfig/#paths" target="_blank" rel="noreferrer">tsconfig.compilerOptions.paths</a> 配置路径别名（例如 <code>@/foo</code>），可以使用 <code>--tsconfig</code> 选项：</p>
<div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span>npx oxlint@latest --tsconfig ./tsconfig.json --import-plugin</span></span></code></pre>
</div><p>通过 <code>npx oxlint@latest --import-plugin</code> 默认启用的规则有：</p>
<ul>
<li><a href="https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/docs/rules/default.md" target="_blank" rel="noreferrer">default</a></li>
<li><a href="https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/docs/rules/named.md" target="_blank" rel="noreferrer">named</a></li>
<li><a href="https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/docs/rules/namespace.md" target="_blank" rel="noreferrer">namespace</a></li>
</ul>
<p>可以通过 <code>npx oxlint@latest --import-plugin -D rule-name</code> 选择性启用的规则有：</p>
<ul>
<li><a href="https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/docs/rules/no-named-as-default.md" target="_blank" rel="noreferrer">no-named-as-default</a></li>
<li><a href="https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/docs/rules/no-named-as-default-member.md" target="_blank" rel="noreferrer">no-named-as-default-member</a></li>
<li><a href="https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/docs/rules/no-self-import.md" target="_blank" rel="noreferrer">no-self-import</a></li>
<li><a href="https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/docs/rules/no-duplicates.md" target="_blank" rel="noreferrer">no-duplicates</a></li>
<li><a href="https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/docs/rules/no-amd.md" target="_blank" rel="noreferrer">no-amd</a></li>
<li><a href="https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/docs/rules/no-default-export.md" target="_blank" rel="noreferrer">no-default-export</a></li>
<li><a href="https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/docs/rules/no-cycle.md" target="_blank" rel="noreferrer">no-cycle</a></li>
</ul>
<p>这些规则也有所改进；例如，<code>no-cycle</code> 规则的诊断信息得到了改进：</p>
<div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span> ⚠ eslint-plugin-import(no-cycle): Dependency cycle detected</span></span>
<span class="line"><span>   ╭─[apps/web/playwright/lib/fixtures.ts:13:42]</span></span>
<span class="line"><span>12 │ import { createPaymentsFixture } from "../fixtures/payments";</span></span>
<span class="line"><span>13 │ import { createBookingPageFixture } from "../fixtures/regularBookings";</span></span>
<span class="line"><span>   ·                                          ─────────────────────────────</span></span>
<span class="line"><span>14 │ import { createRoutingFormsFixture } from "../fixtures/routingForms";</span></span>
<span class="line"><span>   ╰────</span></span>
<span class="line"><span> help: These paths form a cycle:</span></span>
<span class="line"><span>       -> ../fixtures/regularBookings - apps/web/playwright/fixtures/regularBookings.ts</span></span>
<span class="line"><span>       -> ./users - apps/web/playwright/fixtures/users.ts</span></span>
<span class="line"><span>       -> ../lib/testUtils - apps/web/playwright/lib/testUtils.ts</span></span>
<span class="line"><span>       -> ./fixtures - apps/web/playwright/lib/fixtures.ts</span></span></code></pre>
</div><p>这并不是一个很长的功能列表，但由于当前生态系统状态的复杂性，实现这些规则并确保它们正常工作需要大量的努力。</p>
<p>在过去的六个月里，我们利用业余时间工作，并成功完成了 <code>--import-plugin</code> 工作所需的所有先决条件：</p>
<ul>
<li>一个用于模块解析的 <a href="https://github.com/oxc-project/oxc-resolver" target="_blank" rel="noreferrer">resolver</a></li>
<li>一个小型 <a href="https://github.com/oxc-project/oxc/blob/main/crates/oxc_linter/src/service.rs" target="_blank" rel="noreferrer">&quot;runtime&quot;</a> 以最大化并行处理依赖文件</li>
<li>一个用于存储导入/导出信息的 <a href="https://github.com/oxc-project/oxc/blob/main/crates/oxc_syntax/src/module_record.rs" target="_blank" rel="noreferrer"><code>ModuleRecord</code></a> 数据结构，及其相应的 <a href="https://github.com/oxc-project/oxc/blob/main/crates/oxc_semantic/src/module_record/builder.rs" target="_blank" rel="noreferrer">builder</a></li>
</ul>
<h2 id="我如何提供帮助" tabindex="-1">我如何提供帮助？ <a class="header-anchor" href="#我如何提供帮助" aria-label="Permalink to “我如何提供帮助？”">&#8203;</a></h2>
<p>如果您是项目维护者（即配置工程师），并且没有时间和精力保持 ESLint 及其所有插件更新，您可以跟随 <a href="https://github.com/brooooooklyn" target="_blank" rel="noreferrer">@brooooooklyn</a> 的脚步，<a href="https://github.com/napi-rs/napi-rs/pull/2032" target="_blank" rel="noreferrer">在他所有的项目中用 oxlint 替换 ESLint</a>。</p>
<p>如果您是开源爱好者并愿意提供帮助，欢迎在 <a href="https://discord.gg/9uXCAwqQZW" target="_blank" rel="noreferrer">discord</a> 上与我们交谈，查看 <a href="https://github.com/oxc-project/oxc/issues/481" target="_blank" rel="noreferrer">linter 产品计划和进度问题</a>，或通过 <a href="https://github.com/oxc-project/oxc/issues/3161" target="_blank" rel="noreferrer">提议新的规则</a> 来帮助（那些被推迟的规则）。</p>
<p>如果您是工程经理，或者愿意将项目迁移到 oxlint（拥有 330 条规则且还在增长）以降低基础设施成本，您可以考虑 <a href="https://github.com/sponsors/Boshen" target="_blank" rel="noreferrer">赞助</a>，以便我们可以优先处理您的项目。</p>
<p>请记住 <code>oxlint</code> 目前是由社区驱动的，我相信只要有足够的资源，我们就可以在未来几个月内使 <code>--import-plugin</code> 普遍可用。</p>
<hr>
<p>要开始使用 <code>oxlint</code>，请遵循 <a href="/docs/guide/usage/linter.html">安装指南</a> 或了解更多关于 <a href="/docs/guide/introduction.html">oxc 项目</a> 的信息。</p>
]]></content>
        <author>
            <name>Boshen</name>
            <uri>https://github.com/Boshen</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Oxc Transformer Alpha 版本]]></title>
        <id>https://oxc.rs/blog/2024-09-29-transformer-alpha</id>
        <link href="https://oxc.rs/blog/2024-09-29-transformer-alpha"/>
        <updated>2024-09-29T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[<AppBlogPostHeader /><br />
<p>我们很高兴宣布 Oxc transform（又名 transpile）的 alpha 版本发布。</p>
<p>此版本包含三个主要功能：</p>
<ol>
<li>将 TypeScript 转换为 ESNext。</li>
<li>将 React JSX 转换为 ESNext，内置 React Refresh。</li>
<li><a href="https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-5.html#isolated-declarations" target="_blank" rel="noreferrer">TypeScript Isolated Declarations DTS 生成</a> 无需使用 TypeScript 编译器。</li>
</ol>
<p>在这个 alpha 阶段，我们建议尝试这些功能以加快构建速度。</p>
<p><a href="https://github.com/oxc-project/bench-transformer" target="_blank" rel="noreferrer">我们的基准测试</a> 显示：</p>
<ul>
<li>Transform：Oxc 比 SWC 快 3 倍 - 5 倍，内存使用减少 20%，包体积更小（2 MB 对比 SWC 的 37 MB）。</li>
<li>Transform：Oxc 比 Babel 快 20 倍 - 50 倍，内存使用减少 70%，体积小 19 MB，只需安装 2 个 npm 包，而 Babel 需要 170 个。</li>
<li>React 开发 + React Refresh：Oxc 比 SWC 快 5 倍，比 Babel 快 50 倍。</li>
<li>TS isolated declarations <code>.d.ts</code> 生成：Oxc 在典型文件上比 TSC 快 40 倍，在较大文件上快 20 倍。</li>
</ul>
<h2 id="使用示例" tabindex="-1">使用示例 <a class="header-anchor" href="#使用示例" aria-label="Permalink to “使用示例”">&#8203;</a></h2>
<h3 id="oxc-transform-npm-包" tabindex="-1"><a href="https://npmx.dev/package/oxc-transform" target="_blank" rel="noreferrer"><code>oxc-transform</code></a> npm 包 <a class="header-anchor" href="#oxc-transform-npm-包" aria-label="Permalink to “oxc-transform npm 包”">&#8203;</a></h3>
<p>Vue.js 目前在其构建管道中 <a href="https://github.com/vuejs/core/blob/0895b2624b707ea1e75c41f2e1f75388e7a6f101/scripts/build-types.js#L20" target="_blank" rel="noreferrer">实验</a> 使用 <a href="https://npmx.dev/package/oxc-transform" target="_blank" rel="noreferrer"><code>oxc-transform</code></a> npm 包进行 isolated declarations：</p>
<div class="language-javascript"><button title="Copy Code" class="copy"></button><span class="lang">javascript</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> { isolatedDeclaration } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> "oxc-transform"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> dts</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> isolatedDeclaration</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(filename, ts);</span></span></code></pre>
</div><p><a href="https://github.com/lukeed" target="_blank" rel="noreferrer">@lukeed</a> 和 <a href="https://github.com/maraisr" target="_blank" rel="noreferrer">@maraisr</a> 正在他们的包 <a href="https://github.com/lukeed/empathic" target="_blank" rel="noreferrer"><code>empathic</code></a> 和 <a href="https://github.com/maraisr/dldr" target="_blank" rel="noreferrer"><code>dldr</code></a> 中使用 <code>oxc-transform</code> 来 <a href="https://github.com/lukeed/empathic/blob/b83a360ff55051590dec19aa913cd12da97fa3f8/scripts/build.ts#L45-L52" target="_blank" rel="noreferrer">单步完成</a> 转换和生成 <code>.d.ts</code>。</p>
<p>以下示例演示了在单个转换步骤中发出 <code>.js</code> 和 <code>.d.ts</code>：</p>
<div class="language-javascript"><button title="Copy Code" class="copy"></button><span class="lang">javascript</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> { transform } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> "oxc-transform"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> transformed</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> transform</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(filePath, sourceCode, {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  typescript: {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    onlyRemoveTypeImports: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    declaration: { stripInternal: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">});</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">await</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> fs.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">writeFile</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"out.js"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, transformed.code);</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">await</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> fs.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">writeFile</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"out.d.ts"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, transformed.declaration);</span></span></code></pre>
</div><h3 id="unplugin-isolated-decl" tabindex="-1"><a href="https://npmx.dev/package/unplugin-isolated-decl" target="_blank" rel="noreferrer"><code>unplugin-isolated-decl</code></a> <a class="header-anchor" href="#unplugin-isolated-decl" aria-label="Permalink to “unplugin-isolated-decl”">&#8203;</a></h3>
<p><code>vue-macros</code> <a href="https://github.com/vue-macros/vue-macros/blob/4247c7ba9189c630111e058245ce1412c8da9229/tsup.config.ts#L10" target="_blank" rel="noreferrer">使用</a> <code>unplugin-isolated-decl</code> 作为其 esbuild 插件的集成工具。</p>
<p><a href="https://github.com/sxzz" target="_blank" rel="noreferrer">@sxzz</a> <a href="https://x.com/sanxiaozhizi/status/1821320327231893600" target="_blank" rel="noreferrer">报告</a> 他们的 <code>.d.ts</code> 生成时间从 76 秒减少到 16 秒。</p>
<h3 id="airtable-的-bazel-构建" tabindex="-1"><a href="https://github.com/Airtable" target="_blank" rel="noreferrer">Airtable</a> 的 Bazel 构建 <a class="header-anchor" href="#airtable-的-bazel-构建" aria-label="Permalink to “Airtable 的 Bazel 构建”">&#8203;</a></h3>
<p>来自 <a href="https://github.com/Airtable" target="_blank" rel="noreferrer">Airtable</a> 的 <a href="https://github.com/MichaelMitchell-at" target="_blank" rel="noreferrer">@michaelm</a> 正在其 <a href="https://github.com/aspect-build/rules_ts/pull/697" target="_blank" rel="noreferrer">Bazel 构建</a> 的 CI 管道中集成 Oxc 的 isolated declarations <code>.d.ts</code> 生成功能。</p>
<h3 id="rust-oxc-transformer-crate" tabindex="-1">Rust <a href="https://crates.io/crates/oxc_transformer" target="_blank" rel="noreferrer"><code>oxc_transformer</code></a> crate <a class="header-anchor" href="#rust-oxc-transformer-crate" aria-label="Permalink to “Rust oxc_transformer crate”">&#8203;</a></h3>
<p><a href="https://rolldown.rs" target="_blank" rel="noreferrer">Rolldown</a> 打包器 <a href="https://github.com/rolldown/rolldown/blob/3213e8fdb9e25f29295b6ec0d92fcc2ce03ce396/crates/rolldown/src/utils/pre_process_ecma_ast.rs#L67-L75" target="_blank" rel="noreferrer">直接</a> 使用 <code>oxc_transformer</code> Rust crate。</p>
<h2 id="基准测试结果" tabindex="-1">基准测试结果 <a class="header-anchor" href="#基准测试结果" aria-label="Permalink to “基准测试结果”">&#8203;</a></h2>
<p>基准测试设置位于 <a href="https://github.com/oxc-project/bench-transformer" target="_blank" rel="noreferrer">oxc-project/bench-transformer</a>
并且基准测试结果显示在其 <a href="https://github.com/oxc-project/bench-transformer/actions/workflows/ci.yml" target="_blank" rel="noreferrer">GitHub Actions</a> 中。</p>
<p>（欢迎纠正任何配置错误。）</p>
<p>在 <code>ubuntu-latest</code> 上，测量了不同代码行数的示例：</p>
<h3 id="转换" tabindex="-1">转换 <a class="header-anchor" href="#转换" aria-label="Permalink to “转换”">&#8203;</a></h3>
<p>| 行数   | oxc     | swc           | babel         |
|</p>
]]></summary>
        <content type="html"><![CDATA[<AppBlogPostHeader /><br />
<p>我们很高兴宣布 Oxc transform（又名 transpile）的 alpha 版本发布。</p>
<p>此版本包含三个主要功能：</p>
<ol>
<li>将 TypeScript 转换为 ESNext。</li>
<li>将 React JSX 转换为 ESNext，内置 React Refresh。</li>
<li><a href="https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-5.html#isolated-declarations" target="_blank" rel="noreferrer">TypeScript Isolated Declarations DTS 生成</a> 无需使用 TypeScript 编译器。</li>
</ol>
<p>在这个 alpha 阶段，我们建议尝试这些功能以加快构建速度。</p>
<p><a href="https://github.com/oxc-project/bench-transformer" target="_blank" rel="noreferrer">我们的基准测试</a> 显示：</p>
<ul>
<li>Transform：Oxc 比 SWC 快 3 倍 - 5 倍，内存使用减少 20%，包体积更小（2 MB 对比 SWC 的 37 MB）。</li>
<li>Transform：Oxc 比 Babel 快 20 倍 - 50 倍，内存使用减少 70%，体积小 19 MB，只需安装 2 个 npm 包，而 Babel 需要 170 个。</li>
<li>React 开发 + React Refresh：Oxc 比 SWC 快 5 倍，比 Babel 快 50 倍。</li>
<li>TS isolated declarations <code>.d.ts</code> 生成：Oxc 在典型文件上比 TSC 快 40 倍，在较大文件上快 20 倍。</li>
</ul>
<h2 id="使用示例" tabindex="-1">使用示例 <a class="header-anchor" href="#使用示例" aria-label="Permalink to “使用示例”">&#8203;</a></h2>
<h3 id="oxc-transform-npm-包" tabindex="-1"><a href="https://npmx.dev/package/oxc-transform" target="_blank" rel="noreferrer"><code>oxc-transform</code></a> npm 包 <a class="header-anchor" href="#oxc-transform-npm-包" aria-label="Permalink to “oxc-transform npm 包”">&#8203;</a></h3>
<p>Vue.js 目前在其构建管道中 <a href="https://github.com/vuejs/core/blob/0895b2624b707ea1e75c41f2e1f75388e7a6f101/scripts/build-types.js#L20" target="_blank" rel="noreferrer">实验</a> 使用 <a href="https://npmx.dev/package/oxc-transform" target="_blank" rel="noreferrer"><code>oxc-transform</code></a> npm 包进行 isolated declarations：</p>
<div class="language-javascript"><button title="Copy Code" class="copy"></button><span class="lang">javascript</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> { isolatedDeclaration } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> "oxc-transform"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> dts</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> isolatedDeclaration</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(filename, ts);</span></span></code></pre>
</div><p><a href="https://github.com/lukeed" target="_blank" rel="noreferrer">@lukeed</a> 和 <a href="https://github.com/maraisr" target="_blank" rel="noreferrer">@maraisr</a> 正在他们的包 <a href="https://github.com/lukeed/empathic" target="_blank" rel="noreferrer"><code>empathic</code></a> 和 <a href="https://github.com/maraisr/dldr" target="_blank" rel="noreferrer"><code>dldr</code></a> 中使用 <code>oxc-transform</code> 来 <a href="https://github.com/lukeed/empathic/blob/b83a360ff55051590dec19aa913cd12da97fa3f8/scripts/build.ts#L45-L52" target="_blank" rel="noreferrer">单步完成</a> 转换和生成 <code>.d.ts</code>。</p>
<p>以下示例演示了在单个转换步骤中发出 <code>.js</code> 和 <code>.d.ts</code>：</p>
<div class="language-javascript"><button title="Copy Code" class="copy"></button><span class="lang">javascript</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> { transform } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> "oxc-transform"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> transformed</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> transform</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(filePath, sourceCode, {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  typescript: {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    onlyRemoveTypeImports: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    declaration: { stripInternal: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">});</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">await</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> fs.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">writeFile</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"out.js"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, transformed.code);</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">await</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> fs.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">writeFile</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"out.d.ts"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, transformed.declaration);</span></span></code></pre>
</div><h3 id="unplugin-isolated-decl" tabindex="-1"><a href="https://npmx.dev/package/unplugin-isolated-decl" target="_blank" rel="noreferrer"><code>unplugin-isolated-decl</code></a> <a class="header-anchor" href="#unplugin-isolated-decl" aria-label="Permalink to “unplugin-isolated-decl”">&#8203;</a></h3>
<p><code>vue-macros</code> <a href="https://github.com/vue-macros/vue-macros/blob/4247c7ba9189c630111e058245ce1412c8da9229/tsup.config.ts#L10" target="_blank" rel="noreferrer">使用</a> <code>unplugin-isolated-decl</code> 作为其 esbuild 插件的集成工具。</p>
<p><a href="https://github.com/sxzz" target="_blank" rel="noreferrer">@sxzz</a> <a href="https://x.com/sanxiaozhizi/status/1821320327231893600" target="_blank" rel="noreferrer">报告</a> 他们的 <code>.d.ts</code> 生成时间从 76 秒减少到 16 秒。</p>
<h3 id="airtable-的-bazel-构建" tabindex="-1"><a href="https://github.com/Airtable" target="_blank" rel="noreferrer">Airtable</a> 的 Bazel 构建 <a class="header-anchor" href="#airtable-的-bazel-构建" aria-label="Permalink to “Airtable 的 Bazel 构建”">&#8203;</a></h3>
<p>来自 <a href="https://github.com/Airtable" target="_blank" rel="noreferrer">Airtable</a> 的 <a href="https://github.com/MichaelMitchell-at" target="_blank" rel="noreferrer">@michaelm</a> 正在其 <a href="https://github.com/aspect-build/rules_ts/pull/697" target="_blank" rel="noreferrer">Bazel 构建</a> 的 CI 管道中集成 Oxc 的 isolated declarations <code>.d.ts</code> 生成功能。</p>
<h3 id="rust-oxc-transformer-crate" tabindex="-1">Rust <a href="https://crates.io/crates/oxc_transformer" target="_blank" rel="noreferrer"><code>oxc_transformer</code></a> crate <a class="header-anchor" href="#rust-oxc-transformer-crate" aria-label="Permalink to “Rust oxc_transformer crate”">&#8203;</a></h3>
<p><a href="https://rolldown.rs" target="_blank" rel="noreferrer">Rolldown</a> 打包器 <a href="https://github.com/rolldown/rolldown/blob/3213e8fdb9e25f29295b6ec0d92fcc2ce03ce396/crates/rolldown/src/utils/pre_process_ecma_ast.rs#L67-L75" target="_blank" rel="noreferrer">直接</a> 使用 <code>oxc_transformer</code> Rust crate。</p>
<h2 id="基准测试结果" tabindex="-1">基准测试结果 <a class="header-anchor" href="#基准测试结果" aria-label="Permalink to “基准测试结果”">&#8203;</a></h2>
<p>基准测试设置位于 <a href="https://github.com/oxc-project/bench-transformer" target="_blank" rel="noreferrer">oxc-project/bench-transformer</a>
并且基准测试结果显示在其 <a href="https://github.com/oxc-project/bench-transformer/actions/workflows/ci.yml" target="_blank" rel="noreferrer">GitHub Actions</a> 中。</p>
<p>（欢迎纠正任何配置错误。）</p>
<p>在 <code>ubuntu-latest</code> 上，测量了不同代码行数的示例：</p>
<h3 id="转换" tabindex="-1">转换 <a class="header-anchor" href="#转换" aria-label="Permalink to “转换”">&#8203;</a></h3>
<table tabindex="0">
<thead>
<tr>
<th>行数</th>
<th>oxc</th>
<th>swc</th>
<th>babel</th>
</tr>
</thead>
<tbody>
<tr>
<td>~100</td>
<td>0.14 ms</td>
<td>0.7 ms (5x)</td>
<td>11.5 ms (82x)</td>
</tr>
<tr>
<td>~1000</td>
<td>0.9 ms</td>
<td>5.7 ms (6.3x)</td>
<td>38.7 ms (43x)</td>
</tr>
<tr>
<td>~10000</td>
<td>14.9 ms</td>
<td>35.9 ms(2.4x)</td>
<td>492 ms (33x)</td>
</tr>
</tbody>
</table>
<h3 id="isolated-declarations" tabindex="-1">Isolated Declarations <a class="header-anchor" href="#isolated-declarations" aria-label="Permalink to “Isolated Declarations”">&#8203;</a></h3>
<table tabindex="0">
<thead>
<tr>
<th>行数</th>
<th>oxc</th>
<th>tsc</th>
</tr>
</thead>
<tbody>
<tr>
<td>~100</td>
<td>0.1 ms</td>
<td>23.1 ms (231x)</td>
</tr>
<tr>
<td>~1000</td>
<td>3.1 ms</td>
<td>26.8 ms (8.6x)</td>
</tr>
<tr>
<td>~10000</td>
<td>3.5 ms</td>
<td>115.2 ms (33x)</td>
</tr>
</tbody>
</table>
<h2 id="包大小" tabindex="-1">包大小 <a class="header-anchor" href="#包大小" aria-label="Permalink to “包大小”">&#8203;</a></h2>
<p>Oxc 仅下载 2 个 npm 包，总共 2 MB。</p>
<table tabindex="0">
<thead>
<tr>
<th>包</th>
<th>大小</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>@oxc-transform/binding-darwin-arm64</code></td>
<td><a href="https://npmx.dev/package/@oxc-transform/binding-darwin-arm64" target="_blank" rel="noreferrer">2.0 MB</a></td>
</tr>
<tr>
<td><code>@swc/core-darwin-arm64</code></td>
<td><a href="https://npmx.dev/package/@swc/core-darwin-arm64" target="_blank" rel="noreferrer">37.5 MB</a></td>
</tr>
<tr>
<td><code>@babel/core</code> + <code>@babel/preset-env</code> + <code>@babel/preset-react</code> + <code>@babel/preset-typescript</code></td>
<td><a href="https://npmx.dev/package/@babel/core" target="_blank" rel="noreferrer">21 MB 和 170 个包</a></td>
</tr>
</tbody>
</table>
<h2 id="内存使用" tabindex="-1">内存使用 <a class="header-anchor" href="#内存使用" aria-label="Permalink to “内存使用”">&#8203;</a></h2>
<p>Oxc 使用更少的内存。</p>
<p>转换 <code>parser.ts</code>（10777 行）的内存使用 - 使用 <code>/usr/bin/time -alh node</code> 测量：</p>
<table tabindex="0">
<thead>
<tr>
<th></th>
<th>最大 RSS</th>
</tr>
</thead>
<tbody>
<tr>
<td>oxc</td>
<td>51 MB</td>
</tr>
<tr>
<td>swc</td>
<td>67 MB</td>
</tr>
<tr>
<td>babel</td>
<td>172 MB</td>
</tr>
</tbody>
</table>
<h2 id="下一个版本" tabindex="-1">下一个版本 <a class="header-anchor" href="#下一个版本" aria-label="Permalink to “下一个版本”">&#8203;</a></h2>
<p>我们的下一个版本将包括目标降级到 ES6 和 <code>@babel/plugin-transform-modules-commonjs</code>。</p>
<h2 id="致谢" tabindex="-1">致谢 <a class="header-anchor" href="#致谢" aria-label="Permalink to “致谢”">&#8203;</a></h2>
<p>感谢 <a href="https://github.com/dunqing" target="_blank" rel="noreferrer">@Dunqing</a> 和 <a href="https://github.com/overlookmotel" target="_blank" rel="noreferrer">@overlookmotel</a> 为本版本发布所做的所有辛勤工作。</p>
<p>感谢 <a href="https://snyder.tech" target="_blank" rel="noreferrer">snyder.tech</a>、<a href="https://schoolhouse.world" target="_blank" rel="noreferrer">schoolhouse.world</a>、<a href="https://github.com/lukeed" target="_blank" rel="noreferrer">@lukeed</a> 和 <a href="https://github.com/maraisr" target="_blank" rel="noreferrer">@maraisr</a> 的慷慨 <a href="https://github.com/sponsors/boshen" target="_blank" rel="noreferrer">赞助</a>。</p>
]]></content>
        <author>
            <name>Boshen</name>
            <uri>https://github.com/Boshen</uri>
        </author>
        <author>
            <name>Dunqing</name>
            <uri>https://github.com/dunqing</uri>
        </author>
        <author>
            <name>overlookmotel</name>
            <uri>https://github.com/overlookmotel</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Oxlint v0.10 迁移指南]]></title>
        <id>https://oxc.rs/blog/2024-10-18-oxlint-v0.10-release</id>
        <link href="https://oxc.rs/blog/2024-10-18-oxlint-v0.10-release"/>
        <updated>2024-10-18T00:00:00.000Z</updated>
        <content type="html"><![CDATA[<AppBlogPostHeader /><Alert type="info">
<p><strong>本迁移指南适用于较旧版本的 Oxlint。</strong> 有关最新稳定版 v1.0 发布的信息，请参阅 <a href="/blog/2025-06-10-oxlint-stable.html">Oxlint v1.0 稳定版公告</a>。</p>
</Alert>
<p>Oxlint v0.10.0 来了！此版本包含几个令人兴奋的功能，包括对配置文件的许多改进。</p>
<h2 id="新功能" tabindex="-1">新功能 <a class="header-anchor" href="#新功能" aria-label="Permalink to “新功能”">&#8203;</a></h2>
<!-- todo: 其他功能 -->
<h3 id="新规则" tabindex="-1">新规则 <a class="header-anchor" href="#新规则" aria-label="Permalink to “新规则”">&#8203;</a></h3>
<p>此版本包含以下新规则：</p>
<ul>
<li><code>promise/no-callback-in-promise</code></li>
<li><code>react/iframe-missing-sandbox</code></li>
<li><code>node/no-new-require</code></li>
</ul>
<p>并为以下规则添加了自动修复/建议：</p>
<ul>
<li><code>eslint/no-plusplus</code></li>
</ul>
<h3 id="按类别启用-禁用规则" tabindex="-1">按类别启用/禁用规则 <a class="header-anchor" href="#按类别启用-禁用规则" aria-label="Permalink to “按类别启用/禁用规则”">&#8203;</a></h3>
<p>现在，您可以在配置文件中使用 <code>categories</code> 字段来启用或禁用整个类别的规则。</p>
<p>现在，无需运行此命令：</p>
<div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">oxlint</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -D</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> correctness</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -W</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> suspicious</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -c</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint.json</span></span></code></pre>
</div><p>您可以向 <code>oxlint.json</code> 添加一个 <code>categories</code> 字段：</p>
<table><tbody><tr><td>oxlintrc.json</td><td><div class="language-jsonc"><button title="Copy Code" class="copy"></button><span class="lang">jsonc</span><pre class="shiki shiki-themes github-light github-dark has-diff" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">{</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">  "categories"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: {</span></span>
<span class="line diff add"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "correctness"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"deny"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span></span>
<span class="line diff add"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "suspicious"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"warn"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span></span>
<span class="line diff add"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  }, </span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">  "rules"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: {</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "no-const-assign"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "import/no-cycle"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span></code></pre>
</div></td></tr></tbody></table>
<p>并去掉 <code>-D</code> 和 <code>-W</code> 标志。</p>
<h3 id="配置文件中现在支持-plugins" tabindex="-1">配置文件中现在支持 <code>plugins</code> <a class="header-anchor" href="#配置文件中现在支持-plugins" aria-label="Permalink to “配置文件中现在支持 plugins”">&#8203;</a></h3>
<p>配置文件现在支持来自 ESLint v8 配置的 <code>plugins</code> 数组。
这允许您无需 CLI 参数即可启用插件，从而可以在 VSCode 中使用插件。</p>
<table><tbody><tr><td>oxlintrc.json</td><td><div class="language-jsonc"><button title="Copy Code" class="copy"></button><span class="lang">jsonc</span><pre class="shiki shiki-themes github-light github-dark has-diff" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">{</span></span>
<span class="line diff add"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">  "plugins"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"import"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">], </span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">  "categories"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: {</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "correctness"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"deny"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "suspicious"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"warn"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">  "rules"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: {</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "react/jsx-uses-react"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"off"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "react/react-in-jsx-scope"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"off"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span></code></pre>
</div></td></tr></tbody></table>
<p>这与 <code>categories</code> 配合良好，因为启用/禁用的类别也会影响插件。</p>
<table><tbody><tr><td>oxlintrc.json</td><td><div class="language-jsonc"><button title="Copy Code" class="copy"></button><span class="lang">jsonc</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">{</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">  "plugins"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"import"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">],</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">  // `categories` 影响所有启用的插件</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">  "categories"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: {</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "correctness"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"allow"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "suspicious"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"warn"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">  "rules"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: {</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "no-const-assign"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "import/no-cycle"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span></code></pre>
</div></td></tr></tbody></table>
<h2 id="破坏性变更和迁移指南" tabindex="-1">破坏性变更和迁移指南 <a class="header-anchor" href="#破坏性变更和迁移指南" aria-label="Permalink to “破坏性变更和迁移指南”">&#8203;</a></h2>
<h3 id="cli-与配置文件规则优先级" tabindex="-1">CLI 与配置文件规则优先级 <a class="header-anchor" href="#cli-与配置文件规则优先级" aria-label="Permalink to “CLI 与配置文件规则优先级”">&#8203;</a></h3>
<p>以前，配置文件会覆盖 CLI 参数中设置的规则。例如，运行此命令：</p>
<div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">oxlint</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -A</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> correctness</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -c</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlintrc.json</span></span></code></pre>
</div><p>使用此配置文件</p>
<table><tbody><tr><td>oxlintrc.json</td><td><div class="language-jsonc"><button title="Copy Code" class="copy"></button><span class="lang">jsonc</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">{</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">  "rules"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: {</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "no-const-assign"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span></code></pre>
</div></td></tr></tbody></table>
<p>将导致仅有一条规则 <code>no-const-assign</code> 在错误级别开启，而所有其他规则被禁用（即设置为 &quot;allow&quot;）。</p>
<p>现在，<strong>CLI 参数将覆盖配置文件</strong>。相同的命令配合相同的配置文件将导致 <strong>所有规则被禁用</strong>。要获得与之前相同的行为，请在配置文件中启用和禁用类别，而不是使用 CLI 参数。</p>
<div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">oxlint</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -c</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint.json</span></span></code></pre>
</div><table><tbody><tr><td>oxlintrc.json</td><td><div class="language-jsonc"><button title="Copy Code" class="copy"></button><span class="lang">jsonc</span><pre class="shiki shiki-themes github-light github-dark has-diff" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">{</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">  "categories"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: {</span></span>
<span class="line diff add"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "correctness"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"allow"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span></span>
<span class="line diff add"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  }, </span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">  "rules"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: {</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "no-const-assign"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span></code></pre>
</div></td></tr></tbody></table>
]]></content>
        <author>
            <name>Don</name>
            <uri>https://github.com/donisaac</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Oxc Minifier Alpha 版]]></title>
        <id>https://oxc.rs/blog/2025-03-13-minifier-alpha</id>
        <link href="https://oxc.rs/blog/2025-03-13-minifier-alpha"/>
        <updated>2025-03-13T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[<AppBlogPostHeader /><br />
<p>我们很高兴宣布 <a href="https://npmx.dev/package/oxc-minify" target="_blank" rel="noreferrer"><code>oxc-minify</code></a> 的 Alpha 版本发布。</p>
<p>虽然缺少一些高级压缩技术，
但当前版本在性能和压缩大小方面已经优于 <code>esbuild</code>，
正如 <a href="https://github.com/privatenumber/minification-benchmarks" target="_blank" rel="noreferrer">minification-benchmarks</a> 所示。</p>
<p>在 <code>typescript.js</code> 上对比广泛使用的压缩器：</p>
<div align="center">
<p>| 产物                                                                                                                            |                        原始大小 |                         Gzip 大小 |                                   |
| :</p>
]]></summary>
        <content type="html"><![CDATA[<AppBlogPostHeader /><br />
<p>我们很高兴宣布 <a href="https://npmx.dev/package/oxc-minify" target="_blank" rel="noreferrer"><code>oxc-minify</code></a> 的 Alpha 版本发布。</p>
<p>虽然缺少一些高级压缩技术，
但当前版本在性能和压缩大小方面已经优于 <code>esbuild</code>，
正如 <a href="https://github.com/privatenumber/minification-benchmarks" target="_blank" rel="noreferrer">minification-benchmarks</a> 所示。</p>
<p>在 <code>typescript.js</code> 上对比广泛使用的压缩器：</p>
<div align="center">
<table tabindex="0">
<thead>
<tr>
<th style="text-align:left">产物</th>
<th style="text-align:right">原始大小</th>
<th style="text-align:right">Gzip 大小</th>
<th style="text-align:right"></th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left"><a href="https://npmx.dev/package/typescript/v/4.9.5" target="_blank" rel="noreferrer">typescript v4.9.5</a> (<a href="https://unpkg.com/typescript@4.9.5/lib/typescript.js" target="_blank" rel="noreferrer">源码</a>)</td>
<td style="text-align:right"><code>10.95 MB</code></td>
<td style="text-align:right"><code>1.88 MB</code></td>
<td style="text-align:right"></td>
</tr>
<tr>
<td style="text-align:left"><strong>压缩器</strong></td>
<td style="text-align:right"><strong>压缩后大小</strong></td>
<td style="text-align:right"><strong>Gzip 压缩后大小</strong></td>
<td style="text-align:right"><strong>时间</strong></td>
</tr>
<tr>
<td style="text-align:left"><a href="packages/minifiers/minifiers/swc.ts">@swc/core</a></td>
<td style="text-align:right"><strong><sup>🏆-70% </sup><code>3.32 MB</code></strong></td>
<td style="text-align:right"><strong><sup>🏆-54% </sup><code>858.29 kB</code></strong></td>
<td style="text-align:right"><sup><em>5x</em> </sup><code>2,179 ms</code></td>
</tr>
<tr>
<td style="text-align:left"><a href="packages/minifiers/minifiers/oxc-minify.ts">oxc-minify</a></td>
<td style="text-align:right"><sup>-69% </sup><code>3.35 MB</code></td>
<td style="text-align:right"><sup>-54% </sup><code>860.67 kB</code></td>
<td style="text-align:right">🏆 <code>444 ms</code></td>
</tr>
<tr>
<td style="text-align:left"><a href="packages/minifiers/minifiers/terser.ts">terser (不压缩)</a></td>
<td style="text-align:right"><sup>-68% </sup><code>3.53 MB</code></td>
<td style="text-align:right"><sup>-53% </sup><code>879.30 kB</code></td>
<td style="text-align:right"><sup><em>14x</em> </sup><code>6,433 ms</code></td>
</tr>
<tr>
<td style="text-align:left"><a href="packages/minifiers/minifiers/esbuild.ts">esbuild</a></td>
<td style="text-align:right"><sup>-68% </sup><code>3.49 MB</code></td>
<td style="text-align:right"><sup>-51% </sup><code>915.55 kB</code></td>
<td style="text-align:right"><sup><em>1x</em> </sup><code>492 ms</code></td>
</tr>
<tr>
<td style="text-align:left"><a href="packages/minifiers/minifiers/terser.ts">terser</a> <sub title="失败：超时">❌ 超时</sub></td>
<td style="text-align:right">-</td>
<td style="text-align:right">-</td>
<td style="text-align:right"><sup>⚠️</sup> <code>+10,000 ms</code></td>
</tr>
</tbody>
</table>
</div>
<h2 id="oxc-minify-使用示例" tabindex="-1"><a href="https://npmx.dev/package/oxc-minify" target="_blank" rel="noreferrer"><code>oxc-minify</code></a> 使用示例 <a class="header-anchor" href="#oxc-minify-使用示例" aria-label="Permalink to “oxc-minify 使用示例”">&#8203;</a></h2>
<div class="language-typescript"><button title="Copy Code" class="copy"></button><span class="lang">typescript</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> { minify } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> "oxc-minify"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> filename</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> "test.js"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> code</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> "const x = 'a' + 'b'; console.log(x);"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> options</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  compress: {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    target: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"esnext"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  mangle: {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    toplevel: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">false</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  codegen: {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    removeWhitespace: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  sourcemap: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">};</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> result</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> minify</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(filename, code, options);</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">log</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(result.code);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">log</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(result.map);</span></span></code></pre>
</div><h2 id="下一步发布计划" tabindex="-1">下一步发布计划 <a class="header-anchor" href="#下一步发布计划" aria-label="Permalink to “下一步发布计划”">&#8203;</a></h2>
<p><code>oxc-minify</code> 正在被集成到 <a href="https://rolldown.rs" target="_blank" rel="noreferrer">Rolldown</a> 中作为其内置压缩器，
而 Rolldown 注定要 <a href="https://voidzero.dev/posts/announcing-voidzero-inc" target="_blank" rel="noreferrer">成为 Vite 的未来</a>。</p>
<p>因此，对我们来说至关重要的一点是：</p>
<ul>
<li>继续实现高级压缩技术，例如常量内联和死代码消除。</li>
<li>加强和扩展我们的测试基础设施，以确保其准备好投入生产使用。</li>
</ul>
<h2 id="致谢" tabindex="-1">致谢 <a class="header-anchor" href="#致谢" aria-label="Permalink to “致谢”">&#8203;</a></h2>
<p>感谢 <a href="https://github.com/sapphi-red" target="_blank" rel="noreferrer">@sapphi-red</a> 改进了压缩器，
尤其是 <code>esbuild</code> 所缺乏的高级符号压缩算法。</p>
]]></content>
        <author>
            <name>Boshen</name>
            <uri>https://github.com/Boshen</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Oxlint Beta 版]]></title>
        <id>https://oxc.rs/blog/2025-03-15-oxlint-beta</id>
        <link href="https://oxc.rs/blog/2025-03-15-oxlint-beta"/>
        <updated>2025-03-15T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[<AppBlogPostHeader /><Alert type="info">
<p><strong>本文宣布 Oxlint 的 Beta 版本发布。</strong> Oxlint 此后已达到 v1.0 稳定版！请参阅 <a href="/blog/2025-06-10-oxlint-stable.html">Oxlint v1.0 稳定版公告</a> 以了解最新功能和改进。</p>
</Alert>
<p>我们很高兴地宣布，经过社区一年多的开发，Oxlint 现已进入 Beta 发布阶段！</p>
<p>这个里程碑代表着在功能完整性、性能和稳定性方面迈出了重要的一步。</p>
<h2 id="如何使用" tabindex="-1">如何使用 <a class="header-anchor" href="#如何使用" aria-label="Permalink to “如何使用”">&#8203;</a></h2>
<p>在这个阶段，Oxlint 可用于在中小型项目中完全替代 ESLint。</p>
<p>对于大型项目，我们的建议是通过 <a href="https://npmx.dev/package/eslint-plugin-oxlint" target="_blank" rel="noreferrer">eslint-plugin-oxlint</a> 关闭 ESLint 规则，
并在本地或 CI 设置中在 ESLint 之前运行 Oxlint，以获得更快的反馈循环。</p>
<p>要在代码库中测试 Oxlint，您可以在代码库根目录使用您选择的包管理器：</p>
<table><tbody><tr><td>npm</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;user-select:none;-webkit-user-select:none">$ </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">npx</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint@latest</span></span></code></pre>
</div></td></tr><tr><td>pnpm</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;user-select:none;-webkit-user-select:none">$ </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">pnpm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> dlx</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint@latest</span></span></code></pre>
</div></td></tr><tr><td>yarn</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;user-select:none;-webkit-user-select:none">$ </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">yarn</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> dlx</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint@latest</span></span></code></pre>
</div></td></tr><tr><td>bun</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;user-select:none;-webkit-user-select:none">$ </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">bunx</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint@latest</span></span></code></pre>
</div></td></tr><tr><td>deno</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;user-select:none;-webkit-user-select:none">$ </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">deno</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> run</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> npm:oxlint@latest</span></span></code></pre>
</div></td></tr></tbody></table>
<p>有关如何使用 Oxlint 并将其与您的项目或编辑器集成的更详细说明，请查看 <a href="/docs/guide/usage/linter.html">安装指南</a>。</p>
<h2 id="自正式发布以来的新功能亮点" tabindex="-1">自正式发布以来的新功能亮点 <a class="header-anchor" href="#自正式发布以来的新功能亮点" aria-label="Permalink to “自正式发布以来的新功能亮点”">&#8203;</a></h2>
<ul>
<li>显著的性能改进，与上一个版本相比速度最快提升两倍</li>
<li>内置超过 500 条规则，无需额外安装</li>
<li>来自 <code>typescript</code>、<code>unicorn</code>、<code>react</code>、<code>react-perf</code>、<code>nextjs</code>、<code>import</code>、<code>jsdoc</code>、<code>jsx-a11y</code>、<code>node</code>、<code>promise</code>、<code>jest</code>、<code>vitest</code> 插件的许多规则现已完成。</li>
<li>支持通过 <a href="/docs/guide/usage/linter/nested-config.html#configuration-file-format"><code>.oxlintrc.json</code> 文件</a> 进行配置，包括 <a href="/docs/guide/usage/linter/nested-config.html">嵌套配置文件</a>，使用 <code>extends</code> 在文件间共享配置，对特定文件应用 <code>overrides</code> 等。</li>
<li>支持对 <code>.astro</code>、<code>.svelte</code> 和 <code>.vue</code> 文件中的 <code>&lt;script&gt;</code> 内容进行 lint 检查，无需额外配置。</li>
<li>允许对文件应用 <a href="/docs/guide/usage/linter/automatic-fixes.html">自动修复</a> 和建议。</li>
</ul>
<h2 id="更多规则-更高性能" tabindex="-1">更多规则，更高性能 <a class="header-anchor" href="#更多规则-更高性能" aria-label="Permalink to “更多规则，更高性能”">&#8203;</a></h2>
<p>我们专注于使 Oxlint 功能更完整，支持许多最常用的 ESLint 规则和插件，同时也使 Oxlint 速度更快。</p>
<p>第一个 <a href="./2023-12-12-announcing-oxlint.html">Oxlint 正式发布 (GA) 版本</a> 总共有 205 条规则，其中 70 条默认启用。此 Beta 版本现在总共包含 502 条规则，其中 99 条默认启用（默认启用的规则数量增加了 41%）。</p>
<p>| 规则类型     | 规则数量 (GA) | 规则数量 (beta) | 增加            |
|</p>
]]></summary>
        <content type="html"><![CDATA[<AppBlogPostHeader /><Alert type="info">
<p><strong>本文宣布 Oxlint 的 Beta 版本发布。</strong> Oxlint 此后已达到 v1.0 稳定版！请参阅 <a href="/blog/2025-06-10-oxlint-stable.html">Oxlint v1.0 稳定版公告</a> 以了解最新功能和改进。</p>
</Alert>
<p>我们很高兴地宣布，经过社区一年多的开发，Oxlint 现已进入 Beta 发布阶段！</p>
<p>这个里程碑代表着在功能完整性、性能和稳定性方面迈出了重要的一步。</p>
<h2 id="如何使用" tabindex="-1">如何使用 <a class="header-anchor" href="#如何使用" aria-label="Permalink to “如何使用”">&#8203;</a></h2>
<p>在这个阶段，Oxlint 可用于在中小型项目中完全替代 ESLint。</p>
<p>对于大型项目，我们的建议是通过 <a href="https://npmx.dev/package/eslint-plugin-oxlint" target="_blank" rel="noreferrer">eslint-plugin-oxlint</a> 关闭 ESLint 规则，
并在本地或 CI 设置中在 ESLint 之前运行 Oxlint，以获得更快的反馈循环。</p>
<p>要在代码库中测试 Oxlint，您可以在代码库根目录使用您选择的包管理器：</p>
<table><tbody><tr><td>npm</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;user-select:none;-webkit-user-select:none">$ </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">npx</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint@latest</span></span></code></pre>
</div></td></tr><tr><td>pnpm</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;user-select:none;-webkit-user-select:none">$ </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">pnpm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> dlx</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint@latest</span></span></code></pre>
</div></td></tr><tr><td>yarn</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;user-select:none;-webkit-user-select:none">$ </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">yarn</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> dlx</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint@latest</span></span></code></pre>
</div></td></tr><tr><td>bun</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;user-select:none;-webkit-user-select:none">$ </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">bunx</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint@latest</span></span></code></pre>
</div></td></tr><tr><td>deno</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;user-select:none;-webkit-user-select:none">$ </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">deno</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> run</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> npm:oxlint@latest</span></span></code></pre>
</div></td></tr></tbody></table>
<p>有关如何使用 Oxlint 并将其与您的项目或编辑器集成的更详细说明，请查看 <a href="/docs/guide/usage/linter.html">安装指南</a>。</p>
<h2 id="自正式发布以来的新功能亮点" tabindex="-1">自正式发布以来的新功能亮点 <a class="header-anchor" href="#自正式发布以来的新功能亮点" aria-label="Permalink to “自正式发布以来的新功能亮点”">&#8203;</a></h2>
<ul>
<li>显著的性能改进，与上一个版本相比速度最快提升两倍</li>
<li>内置超过 500 条规则，无需额外安装</li>
<li>来自 <code>typescript</code>、<code>unicorn</code>、<code>react</code>、<code>react-perf</code>、<code>nextjs</code>、<code>import</code>、<code>jsdoc</code>、<code>jsx-a11y</code>、<code>node</code>、<code>promise</code>、<code>jest</code>、<code>vitest</code> 插件的许多规则现已完成。</li>
<li>支持通过 <a href="/docs/guide/usage/linter/nested-config.html#configuration-file-format"><code>.oxlintrc.json</code> 文件</a> 进行配置，包括 <a href="/docs/guide/usage/linter/nested-config.html">嵌套配置文件</a>，使用 <code>extends</code> 在文件间共享配置，对特定文件应用 <code>overrides</code> 等。</li>
<li>支持对 <code>.astro</code>、<code>.svelte</code> 和 <code>.vue</code> 文件中的 <code>&lt;script&gt;</code> 内容进行 lint 检查，无需额外配置。</li>
<li>允许对文件应用 <a href="/docs/guide/usage/linter/automatic-fixes.html">自动修复</a> 和建议。</li>
</ul>
<h2 id="更多规则-更高性能" tabindex="-1">更多规则，更高性能 <a class="header-anchor" href="#更多规则-更高性能" aria-label="Permalink to “更多规则，更高性能”">&#8203;</a></h2>
<p>我们专注于使 Oxlint 功能更完整，支持许多最常用的 ESLint 规则和插件，同时也使 Oxlint 速度更快。</p>
<p>第一个 <a href="./2023-12-12-announcing-oxlint.html">Oxlint 正式发布 (GA) 版本</a> 总共有 205 条规则，其中 70 条默认启用。此 Beta 版本现在总共包含 502 条规则，其中 99 条默认启用（默认启用的规则数量增加了 41%）。</p>
<table tabindex="0">
<thead>
<tr>
<th>规则类型</th>
<th>规则数量 (GA)</th>
<th>规则数量 (beta)</th>
<th>增加</th>
</tr>
</thead>
<tbody>
<tr>
<td>默认规则</td>
<td>70</td>
<td>99</td>
<td>+29 条规则</td>
</tr>
<tr>
<td>正确性</td>
<td>88</td>
<td>173</td>
<td>+88 条规则</td>
</tr>
<tr>
<td>性能</td>
<td>0</td>
<td>9</td>
<td>+9 条规则</td>
</tr>
<tr>
<td>限制</td>
<td>15</td>
<td>64</td>
<td>+49 条规则</td>
</tr>
<tr>
<td>严格</td>
<td>43</td>
<td>79</td>
<td>+36 条规则</td>
</tr>
<tr>
<td>风格</td>
<td>38</td>
<td>137</td>
<td>+99 条规则</td>
</tr>
<tr>
<td>可疑</td>
<td>7</td>
<td>28</td>
<td>+21 条规则</td>
</tr>
<tr>
<td><strong>规则总数</strong></td>
<td>205</td>
<td><strong>502</strong></td>
<td><strong>+297 条规则</strong></td>
</tr>
</tbody>
</table>
<p>尽管添加了许多默认启用的新规则，Oxlint 现在的速度比以往任何时候都快。以下是一些流行仓库的 <a href="https://gist.github.com/camchenry/cb09f6fae14ec1e3df1f72938b7350c8" target="_blank" rel="noreferrer">基准测试</a>：</p>
<table tabindex="0">
<thead>
<tr>
<th>仓库</th>
<th>文件数量</th>
<th>Lint 时间 (GA)</th>
<th>Lint 时间 (beta)</th>
<th>加速</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>elastic/kibana</code></td>
<td>68,591</td>
<td>6.02s</td>
<td><strong>3.11s</strong></td>
<td><strong>1.94x</strong></td>
</tr>
<tr>
<td><code>microsoft/vscode</code></td>
<td>5,703</td>
<td>1.697s</td>
<td><strong>0.792s</strong></td>
<td><strong>2.14x</strong></td>
</tr>
<tr>
<td><code>vitest-dev/vitest</code></td>
<td>1,732</td>
<td>105ms</td>
<td><strong>50ms</strong></td>
<td><strong>2.1x</strong></td>
</tr>
<tr>
<td><code>vuejs/core</code></td>
<td>1,063</td>
<td>217ms</td>
<td><strong>89ms</strong></td>
<td><strong>2.44x</strong></td>
</tr>
</tbody>
</table>
<h2 id="路线图" tabindex="-1">路线图 <a class="header-anchor" href="#路线图" aria-label="Permalink to “路线图”">&#8203;</a></h2>
<p>Oxlint 最受请求的功能之一是对现有自定义 ESLint 插件的支持。我们一直忙于为此功能准备先决条件，并启用用 JavaScript 编写的快速 linter 插件。我们希望在下一次主要发布时提供此功能，并在不久的将来分享更多关于它的信息。</p>
<p>我们还计划继续改进 IDE/编辑器集成，更好地支持 VSCode、Zed、<code>coc.nvim</code> 和 IntelliJ 插件。</p>
<h2 id="致谢" tabindex="-1">致谢 <a class="header-anchor" href="#致谢" aria-label="Permalink to “致谢”">&#8203;</a></h2>
<p>如果没有超过 200 名项目贡献者，Oxlint Beta 版本是不可能实现的。</p>
<p>特别感谢：</p>
<ul>
<li><a href="https://github.com/camc314" target="_blank" rel="noreferrer">@cam314</a>、<a href="https://github.com/mysteryven" target="_blank" rel="noreferrer">@mysteryven</a> 和 <a href="https://github.com/shulaoda" target="_blank" rel="noreferrer">@shulaoda</a> 用于实现许多复杂的 lint 规则、测试，并不断改进一切。</li>
<li><a href="https://github.com/Sysix" target="_blank" rel="noreferrer">@Sysix</a> 用于维护 <code>eslint-plugin-oxlint</code>。</li>
<li><a href="https://github.com/DonIsaac" target="_blank" rel="noreferrer">@DonIsaac</a> 用于改进配置、文档和网站，并代表 Oxc 参加 <a href="https://2024.squiggleconf.com" target="_blank" rel="noreferrer">SquiggleConf 2024</a>。</li>
<li><a href="https://github.com/leaysgur" target="_blank" rel="noreferrer">@leaysgur</a> 用于 RegExp 解析器和 JSDoc 插件。</li>
<li><a href="https://github.com/u9g" target="_blank" rel="noreferrer">@u9g</a> 和 <a href="https://github.com/rzvxa" target="_blank" rel="noreferrer">@rzvxa</a> 用于实现控制流图分析。</li>
<li><a href="https://github.com/branchseer" target="_blank" rel="noreferrer">@branchseer</a> 用于实现多文件分析运行时。</li>
<li><a href="https://github.com/camchenry" target="_blank" rel="noreferrer">@camchenry</a> 用于实现嵌套配置支持。</li>
</ul>
]]></content>
        <author>
            <name>Boshen</name>
            <uri>https://github.com/Boshen</uri>
        </author>
        <author>
            <name>Cam</name>
            <uri>https://github.com/camchenry</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Oxlint v1.0 稳定版]]></title>
        <id>https://oxc.rs/blog/2025-06-10-oxlint-stable</id>
        <link href="https://oxc.rs/blog/2025-06-10-oxlint-stable"/>
        <updated>2025-06-10T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[<AppBlogPostHeader /><br>
<div  class="info custom-block"><p class="custom-block-title custom-block-title-default">INFO</p>
<p>这篇博客文章 <a href="https://voidzero.dev/posts/announcing-oxlint-1-stable" target="_blank" rel="noreferrer">最初发布在 VoidZero 网站上</a>。</p>
</div>
<br>
<p>TL;DR: Oxlint 的第一个稳定版本已发布！与 ESLint 相比，性能提升了 <a href="#benchmark">50~100 倍</a>，支持超过 500 条 ESLint 规则，并在 <a href="#real-world-impact">主要公司的使用情况</a> 中得到验证，如 Shopify、Airbnb 和 Mercedes-Benz，你应该试一试。<a href="#quick-start">立即开始</a>。</p>
]]></summary>
        <content type="html"><![CDATA[<AppBlogPostHeader /><br>
<div  class="info custom-block"><p class="custom-block-title custom-block-title-default">INFO</p>
<p>这篇博客文章 <a href="https://voidzero.dev/posts/announcing-oxlint-1-stable" target="_blank" rel="noreferrer">最初发布在 VoidZero 网站上</a>。</p>
</div>
<br>
<p>TL;DR: Oxlint 的第一个稳定版本已发布！与 ESLint 相比，性能提升了 <a href="#benchmark">50~100 倍</a>，支持超过 500 条 ESLint 规则，并在 <a href="#real-world-impact">主要公司的使用情况</a> 中得到验证，如 Shopify、Airbnb 和 Mercedes-Benz，你应该试一试。<a href="#quick-start">立即开始</a>。</p>
<hr>
<p>Oxlint 是一个基于 Rust 的 JavaScript 和 TypeScript 代码检查工具，旨在快速且易于采用。自 2023 年 12 月首次宣布以来，Oxlint 经历了显著的改进，现在发布了其第一个稳定版本 1.0。
除了稳定版本发布外，我们还想宣布 Oxlint 拥有一位专职维护者 <a href="https://github.com/camc314" target="_blank" rel="noreferrer">Cameron</a>，以及一个不断壮大的核心团队致力于维护和改进该代码检查工具。</p>
<h2 id="实际影响" tabindex="-1">实际影响 <a class="header-anchor" href="#实际影响" aria-label="Permalink to “实际影响”">&#8203;</a></h2>
<p>我们对 Oxlint 的性能及其对真实大规模代码库的影响感到非常自豪，这降低了 CI 成本。</p>
<p>我们感谢 <a href="https://github.com/oxc-project/oxc/network/dependents" target="_blank" rel="noreferrer">5,200 名早期采用者</a> 以及以下公司和项目：</p>
<ul>
<li><strong>Shopify</strong>，其前端平台团队在 Shopify 管理控制台中使用 Oxlint。</li>
<li><strong>Airbnb</strong>，他们在 126,000+ 个文件上使用多文件分析 <a href="https://oxc.rs/docs/guide/usage/linter/rules/oxc/no-barrel-file.html" target="_blank" rel="noreferrer">oxc/no-barrel-file</a> 和 <a href="https://oxc.rs/docs/guide/usage/linter/rules/import/no-cycle.html" target="_blank" rel="noreferrer">import/no-cycle</a>，在 CI 上仅需 7 秒即可完成。ESLint 对这些规则的实现会超时。</li>
<li><a href="https://www.mercedes-benz.io/blog/2025-05-16-how-can-modern-tooling-save-mercedes-benz-io-engineering-time" target="_blank" rel="noreferrer"><strong>Mercedes-Benz</strong></a>，他们观察到从 ESLint 切换到 Oxlint 后，lint 时间减少了 71%，某些项目甚至看到了高达 97% 的加速。</li>
<li>大型开源项目，从 <a href="https://github.com/oven-sh/bun/blob/main/oxlint.json" target="_blank" rel="noreferrer">Bun</a> 等运行时到 <a href="https://github.com/preactjs/preact/blob/main/oxlint.json" target="_blank" rel="noreferrer">Preact</a> 等框架。</li>
</ul>
<p>在我们发现的最大的仓库上，Oxlint 报告：</p>
<div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span>Finished in 22.5s on 264925 files with 101 rules using 10 threads.</span></span></code></pre>
</div><p>基于发布在 <a href="https://x.com/boshen_c/status/1928264877115597053" target="_blank" rel="noreferrer">X</a> 和 <a href="https://bsky.app/profile/boshen.github.io/post/3lqe47xi47c2e" target="_blank" rel="noreferrer">Bluesky</a> 上的真实案例，
Oxlint 的运行速度约为每秒 10,000 个文件，具体取决于使用的线程总数。</p>
<h2 id="快速开始" tabindex="-1">快速开始 <a class="header-anchor" href="#快速开始" aria-label="Permalink to “快速开始”">&#8203;</a></h2>
<p>Oxlint 非常适合那些希望开始检查代码而不想花费数小时配置工具的开发者。无需任何设置，你可以立即开始发现问题：</p>
<p><strong>运行它，无需配置。</strong></p>
<table><tbody><tr><td>npm</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;user-select:none;-webkit-user-select:none">$ </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">npx</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint@latest</span></span></code></pre>
</div></td></tr><tr><td>pnpm</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;user-select:none;-webkit-user-select:none">$ </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">pnpm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> dlx</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint@latest</span></span></code></pre>
</div></td></tr><tr><td>yarn</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;user-select:none;-webkit-user-select:none">$ </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">yarn</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> dlx</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint@latest</span></span></code></pre>
</div></td></tr><tr><td>bun</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;user-select:none;-webkit-user-select:none">$ </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">bunx</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint@latest</span></span></code></pre>
</div></td></tr><tr><td>deno</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;user-select:none;-webkit-user-select:none">$ </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">deno</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> run</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> npm:oxlint@latest</span></span></code></pre>
</div></td></tr></tbody></table>
<p>虽然不需要任何设置或配置，但 Oxlint 可以通过 <code>.oxlintrc.json</code> 文件进行配置，这对于大型项目或需要更多定制的项目非常有用。
此配置格式基于 ESLint v8 的平面配置（flat config），使得迁移变得简单且熟悉。
每个源文件都使用最近的适用配置进行 lint，你可以使用覆盖（overrides）来 targeting 特定的 glob 模式。
你还可以扩展共享配置以保持团队一致性。</p>
<p>对于已经使用 ESLint 的项目，可以使用 <a href="https://github.com/oxc-project/oxlint-migrate" target="_blank" rel="noreferrer">oxlint-migrate</a> 将现有的 ESLint flat-config 文件迁移到 Oxlint。
此外，<a href="https://npmx.dev/package/eslint-plugin-oxlint" target="_blank" rel="noreferrer">eslint-plugin-oxlint</a> 可以在同时使用两个代码检查工具时禁用重叠的 ESLint 规则。
建议运行 <code>oxlint &amp;&amp; eslint</code> 以受益于 Oxlint 更快的反馈周期。</p>
<p>有关如何使用 Oxlint 并将其与你的项目或编辑器集成的更详细说明，请查看 <a href="https://oxc.rs/docs/guide/usage/linter" target="_blank" rel="noreferrer">安装指南</a>。</p>
<h2 id="版本管理" tabindex="-1">版本管理 <a class="header-anchor" href="#版本管理" aria-label="Permalink to “版本管理”">&#8203;</a></h2>
<p>与发布运行时代码的库不同，代码检查工具只更改其返回的诊断信息。Oxlint 遵循语义化版本：</p>
<ul>
<li>补丁版本：仅修复错误。</li>
<li>次要版本：扩展规则覆盖范围和诊断信息，无需更改配置。</li>
<li>主要版本：CLI 或配置更改，可能需要迁移。
请注意，如果新添加的规则发现了以前隐藏的问题，次要版本仍然可能会破坏你的 CI。在我们的 <a href="https://oxc.rs/docs/guide/usage/linter/versioning" target="_blank" rel="noreferrer">版本管理指南</a> 中了解更多。</li>
</ul>
<h2 id="亮点" tabindex="-1">亮点 <a class="header-anchor" href="#亮点" aria-label="Permalink to “亮点”">&#8203;</a></h2>
<h3 id="全面的规则覆盖" tabindex="-1">全面的规则覆盖 <a class="header-anchor" href="#全面的规则覆盖" aria-label="Permalink to “全面的规则覆盖”">&#8203;</a></h3>
<p>Oxlint 包含来自各种来源的超过 500 条规则：</p>
<ul>
<li>完整的 ESLint 规则集，包括来自 <code>typescript-eslint</code> 的 TypeScript 特定规则（不包括类型检查规则）。</li>
<li>来自 <code>eslint-plugin-unicorn</code>、<code>eslint-plugin-jsdoc</code>、<code>eslint-plugin-react</code>、<code>eslint-plugin-react-hooks</code>、<code>eslint-plugin-jest</code> 和 <code>eslint-plugin-import</code> 的流行插件规则</li>
<li>独特的 Oxlint 规则，如 <a href="https://oxc.rs/docs/guide/usage/linter/rules/oxc/bad-comparison-sequence" target="_blank" rel="noreferrer">错误比较序列</a>、<a href="https://oxc.rs/docs/guide/usage/linter/rules/oxc/const-comparisons" target="_blank" rel="noreferrer">常量比较</a> 和 <a href="https://oxc.rs/docs/guide/usage/linter/rules/oxc/only-used-in-recursion" target="_blank" rel="noreferrer">仅在递归中使用</a></li>
</ul>
<h3 id="灵活的配置" tabindex="-1">灵活的配置 <a class="header-anchor" href="#灵活的配置" aria-label="Permalink to “灵活的配置”">&#8203;</a></h3>
<p>通过 <code>.oxlintrc.json</code> 文件配置 Oxlint，支持：</p>
<ul>
<li>适用于特定目录的嵌套配置</li>
<li>针对特定文件类型或位置的覆盖模式</li>
<li>共享配置扩展以保持团队一致性</li>
</ul>
<h3 id="编辑器集成" tabindex="-1">编辑器集成 <a class="header-anchor" href="#编辑器集成" aria-label="Permalink to “编辑器集成”">&#8203;</a></h3>
<p>一流的编辑器支持，扩展包括：</p>
<ul>
<li><a href="https://marketplace.visualstudio.com/items?itemName=oxc.oxc-vscode" target="_blank" rel="noreferrer">VS Code</a></li>
<li><a href="https://plugins.jetbrains.com/plugin/27061-oxc" target="_blank" rel="noreferrer">IntelliJ IDEA 和 WebStorm</a></li>
<li><a href="https://zed.dev/extensions?query=oxc" target="_blank" rel="noreferrer">Zed Editor</a></li>
<li>其他编辑器的语言服务器协议支持</li>
</ul>
<h3 id="有用的诊断信息" tabindex="-1">有用的诊断信息 <a class="header-anchor" href="#有用的诊断信息" aria-label="Permalink to “有用的诊断信息”">&#8203;</a></h3>
<p>Oxlint 旨在提供清晰、可操作的错误消息——不仅描述问题，还将其可视化并建议如何修复。</p>
<p><img src="https://github.com/oxc-project/oxc/assets/1430279/094a3b24-0433-42ae-aad2-48a7dec2b985" alt="CLI 演示">
<em>Oxlint 在终端中运行，带有详细的错误报告</em></p>
<h2 id="基准测试" tabindex="-1">基准测试 <a class="header-anchor" href="#基准测试" aria-label="Permalink to “基准测试”">&#8203;</a></h2>
<p>我们的 <a href="https://github.com/oxc-project/bench-javascript-linter" target="_blank" rel="noreferrer">基准测试</a> 显示，在相同设置下，Oxlint 比 ESLint 快约 50~100 倍。</p>
<table tabindex="0">
<thead>
<tr>
<th>工具</th>
<th>时间</th>
</tr>
</thead>
<tbody>
<tr>
<td>oxlint (多线)</td>
<td>615.3 ms</td>
</tr>
<tr>
<td>oxlint (单线)</td>
<td>1.840 s</td>
</tr>
<tr>
<td>eslint</td>
<td>33.481 s</td>
</tr>
</tbody>
</table>
<h2 id="路线图" tabindex="-1">路线图 <a class="header-anchor" href="#路线图" aria-label="Permalink to “路线图”">&#8203;</a></h2>
<p>Oxlint 1.0 只是一个开始！虽然它已稳定，但我们仍计划在未来版本中提供重要的功能和改进：</p>
<p><strong>自定义规则</strong> – JavaScript 插件支持即将推出，使团队能够编写与 Oxlint 架构无缝集成的自定义规则。</p>
<p><strong>性能优化</strong> – 持续改进解析和分析速度。</p>
<p><strong>细粒度（每个 glob）配置</strong> - ESLint v9 配置</p>
<h2 id="致谢" tabindex="-1">致谢 <a class="header-anchor" href="#致谢" aria-label="Permalink to “致谢”">&#8203;</a></h2>
<p>Oxlint 1.0 代表了 <a href="https://github.com/oxc-project/oxc/graphs/contributors" target="_blank" rel="noreferrer">超过 200 位贡献者</a> 的共同努力，他们塑造了这个项目。我们感谢每一个错误报告、功能请求和代码贡献。</p>
<p>特别感谢：</p>
<ul>
<li><a href="https://github.com/branchseer" target="_blank" rel="noreferrer">@branchseer</a> 实现了多文件分析运行时。</li>
<li><a href="https://github.com/camc314" target="_blank" rel="noreferrer">@camc314</a>、<a href="https://github.com/mysteryven" target="_blank" rel="noreferrer">@mysteryven</a> 和 <a href="https://github.com/shulaoda" target="_blank" rel="noreferrer">@shulaoda</a> 实现了许多复杂的 lint 规则、测试，并不断改进一切。</li>
<li><a href="https://github.com/camchenry" target="_blank" rel="noreferrer">@camchenry</a> 实现了嵌套配置支持。</li>
<li><a href="https://github.com/DonIsaac" target="_blank" rel="noreferrer">@DonIsaac</a> 改进了配置、文档和网站，并在 <a href="https://2024.squiggleconf.com" target="_blank" rel="noreferrer">SquiggleConf 2024</a> 上代表 Oxc。</li>
<li><a href="https://github.com/leaysgur" target="_blank" rel="noreferrer">@leaysgur</a> 开发了 RegExp 解析器和 JSDoc 插件。</li>
<li><a href="https://github.com/Sysix" target="_blank" rel="noreferrer">@Sysix</a> 维护 <code>eslint-plugin-oxlint</code> 并对语言服务器和 VSCode 扩展做出了重大贡献。</li>
<li><a href="https://github.com/u9g" target="_blank" rel="noreferrer">@u9g</a> 和 <a href="https://github.com/rzvxa" target="_blank" rel="noreferrer">@rzvxa</a> 实现了控制流图分析。</li>
</ul>
<h2 id="加入社区" tabindex="-1">加入社区 <a class="header-anchor" href="#加入社区" aria-label="Permalink to “加入社区”">&#8203;</a></h2>
<p>我们很乐意听取你对 Oxlint 的反馈，并很高兴看到它如何帮助改善你的开发工作流。与我们联系：</p>
<ul>
<li><strong>Discord</strong>：加入我们的 <a href="https://discord.gg/9uXCAwqQZW" target="_blank" rel="noreferrer">社区服务器</a> 进行实时讨论</li>
<li><strong>GitHub</strong>：在 <a href="https://github.com/oxc-project/oxc/discussions" target="_blank" rel="noreferrer">GitHub 讨论区</a> 分享反馈</li>
<li><strong>Issues</strong>：在我们的 <a href="https://github.com/oxc-project/oxc/issues" target="_blank" rel="noreferrer">问题追踪器</a> 上报告错误或请求功能</li>
</ul>
<p>你的反馈推动着 Oxlint 的演进。</p>
<h2 id="试一试" tabindex="-1">试一试 <a class="header-anchor" href="#试一试" aria-label="Permalink to “试一试”">&#8203;</a></h2>
<p>要开始使用，请遵循 <a href="https://oxc.rs/docs/guide/usage/linter" target="_blank" rel="noreferrer">安装指南</a>，或了解更多关于 <a href="https://oxc.rs/docs/guide/introduction" target="_blank" rel="noreferrer">Oxc 项目</a> 的信息。</p>
]]></content>
        <author>
            <name>Boshen</name>
            <uri>https://github.com/Boshen</uri>
        </author>
        <author>
            <name>Cameron</name>
            <uri>https://github.com/camc314</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Oxlint 类型感知预览]]></title>
        <id>https://oxc.rs/blog/2025-08-17-oxlint-type-aware</id>
        <link href="https://oxc.rs/blog/2025-08-17-oxlint-type-aware"/>
        <updated>2025-08-17T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[<AppBlogPostHeader /><Alert type="info">
<p><strong>本文宣布类型感知 linting 的技术预览版。</strong> 对于具有改进稳定性、可配置性和规则覆盖面的最新 alpha 版本，请参阅 <a href="/blog/2025-12-08-type-aware-alpha.html">类型感知 Linting Alpha 公告</a>。</p>
</Alert>
<br>
<p>我们很高兴宣布 <code>oxlint</code> 中的类型感知 linting！</p>
<p>期待已久的 <code>no-floating-promises</code> 及相关规则现已到来。</p>
<p>此预览版旨在通过记录我们的决策过程和技术细节，与社区进行协作和讨论。</p>
<h2 id="快速开始" tabindex="-1">快速开始 <a class="header-anchor" href="#快速开始" aria-label="Permalink to “快速开始”">&#8203;</a></h2>
<p>如果已配置 <code>oxlint</code>，请安装 <code>oxlint-tsgolint</code> 并使用 <code>--type-aware</code> 标志运行 <code>oxlint</code>：</p>
<div class="language-bash"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">pnpm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> add</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -D</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint-tsgolint@latest</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">pnpm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> dlx</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> --type-aware</span></span></code></pre>
</div><p>如果未配置 <code>oxlint</code> 但想查看 <code>no-floating-promises</code> 的实际效果：</p>
<div class="language-bash"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">pnpm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> add</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -D</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint-tsgolint@latest</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">pnpm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> dlx</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint@latest</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> --type-aware</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -A</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> all</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -D</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> typescript/no-floating-promises</span></span></code></pre>
</div><p>例如，我们将看到：</p>
<div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> × typescript</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">-</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">eslint</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(no</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">-</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">floating</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">-</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">promises): Promises must be awaited, end </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">with</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> a call to .catch, end </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">with</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> a call to .then </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">with</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> a rejection handler or be explicitly marked </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">as</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> ignored</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> with</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> the</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> `void`</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> operator</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">.</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">   ╭─[packages</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">rolldown</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">src</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">api</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">watch</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">watcher.ts:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">30</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">7</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">]</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">29</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> │       </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">await</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> this</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">close</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">();</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">30</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> │       </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">originClose</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">();</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">   ·       ──────────────</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">31</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> │     };</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">   ╰────</span></span></code></pre>
</div><p>请访问我们的 <a href="https://oxc.rs/docs/guide/usage/linter.html" target="_blank" rel="noreferrer">使用指南</a> 了解更多配置选项。</p>
<h2 id="性能" tabindex="-1">性能 <a class="header-anchor" href="#性能" aria-label="Permalink to “性能”">&#8203;</a></h2>
<p>我们的测试显示，以前使用 <code>typescript-eslint</code> 需要一分钟才能运行的仓库，现在不到 10 秒即可完成。</p>
<p>这是通过利用 <a href="https://github.com/microsoft/typescript-go" target="_blank" rel="noreferrer"><code>typescript-go</code></a> 实现的，
它是用 Go 编写的 <a href="https://devblogs.microsoft.com/typescript/typescript-native-port" target="_blank" rel="noreferrer">速度提升 10 倍的 TypeScript</a>。</p>
<p>使用来自 <a href="https://github.com/oxc-project/oxc-ecosystem-ci" target="_blank" rel="noreferrer">oxc-ecosystem-ci</a> 的项目：</p>
<p>| 项目     | 文件 | 时间 |
|</p>
]]></summary>
        <content type="html"><![CDATA[<AppBlogPostHeader /><Alert type="info">
<p><strong>本文宣布类型感知 linting 的技术预览版。</strong> 对于具有改进稳定性、可配置性和规则覆盖面的最新 alpha 版本，请参阅 <a href="/blog/2025-12-08-type-aware-alpha.html">类型感知 Linting Alpha 公告</a>。</p>
</Alert>
<br>
<p>我们很高兴宣布 <code>oxlint</code> 中的类型感知 linting！</p>
<p>期待已久的 <code>no-floating-promises</code> 及相关规则现已到来。</p>
<p>此预览版旨在通过记录我们的决策过程和技术细节，与社区进行协作和讨论。</p>
<h2 id="快速开始" tabindex="-1">快速开始 <a class="header-anchor" href="#快速开始" aria-label="Permalink to “快速开始”">&#8203;</a></h2>
<p>如果已配置 <code>oxlint</code>，请安装 <code>oxlint-tsgolint</code> 并使用 <code>--type-aware</code> 标志运行 <code>oxlint</code>：</p>
<div class="language-bash"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">pnpm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> add</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -D</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint-tsgolint@latest</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">pnpm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> dlx</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> --type-aware</span></span></code></pre>
</div><p>如果未配置 <code>oxlint</code> 但想查看 <code>no-floating-promises</code> 的实际效果：</p>
<div class="language-bash"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">pnpm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> add</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -D</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint-tsgolint@latest</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">pnpm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> dlx</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint@latest</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> --type-aware</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -A</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> all</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -D</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> typescript/no-floating-promises</span></span></code></pre>
</div><p>例如，我们将看到：</p>
<div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> × typescript</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">-</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">eslint</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(no</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">-</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">floating</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">-</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">promises): Promises must be awaited, end </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">with</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> a call to .catch, end </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">with</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> a call to .then </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">with</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> a rejection handler or be explicitly marked </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">as</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> ignored</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> with</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> the</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> `void`</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> operator</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">.</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">   ╭─[packages</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">rolldown</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">src</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">api</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">watch</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">watcher.ts:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">30</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">7</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">]</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">29</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> │       </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">await</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> this</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">close</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">();</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">30</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> │       </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">originClose</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">();</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">   ·       ──────────────</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">31</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> │     };</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">   ╰────</span></span></code></pre>
</div><p>请访问我们的 <a href="https://oxc.rs/docs/guide/usage/linter.html" target="_blank" rel="noreferrer">使用指南</a> 了解更多配置选项。</p>
<h2 id="性能" tabindex="-1">性能 <a class="header-anchor" href="#性能" aria-label="Permalink to “性能”">&#8203;</a></h2>
<p>我们的测试显示，以前使用 <code>typescript-eslint</code> 需要一分钟才能运行的仓库，现在不到 10 秒即可完成。</p>
<p>这是通过利用 <a href="https://github.com/microsoft/typescript-go" target="_blank" rel="noreferrer"><code>typescript-go</code></a> 实现的，
它是用 Go 编写的 <a href="https://devblogs.microsoft.com/typescript/typescript-native-port" target="_blank" rel="noreferrer">速度提升 10 倍的 TypeScript</a>。</p>
<p>使用来自 <a href="https://github.com/oxc-project/oxc-ecosystem-ci" target="_blank" rel="noreferrer">oxc-ecosystem-ci</a> 的项目：</p>
<table tabindex="0">
<thead>
<tr>
<th>项目</th>
<th>文件</th>
<th>时间</th>
</tr>
</thead>
<tbody>
<tr>
<td>napi-rs</td>
<td>144</td>
<td>1.0s</td>
</tr>
<tr>
<td>preact</td>
<td>245</td>
<td>2.7s</td>
</tr>
<tr>
<td>rolldown</td>
<td>314</td>
<td>1.5s</td>
</tr>
<tr>
<td>bluesky</td>
<td>1152</td>
<td>7.0s</td>
</tr>
</tbody>
</table>
<h2 id="类型感知-linting" tabindex="-1">类型感知 Linting <a class="header-anchor" href="#类型感知-linting" aria-label="Permalink to “类型感知 Linting”">&#8203;</a></h2>
<p>请参考
<a href="https://www.joshuakgoldberg.com/blog/rust-based-javascript-linters-fast-but-no-typed-linting-right-now" target="_blank" rel="noreferrer">基于 Rust 的 JavaScript Linter：速度快，但目前没有类型化 Linting</a>
以了解生态系统中类型感知 linting 的当前状态。</p>
<h2 id="技术细节" tabindex="-1">技术细节 <a class="header-anchor" href="#技术细节" aria-label="Permalink to “技术细节”">&#8203;</a></h2>
<p>此新功能的核心是 <a href="https://github.com/oxc-project/tsgolint" target="_blank" rel="noreferrer">oxc-project/tsgolint</a>。</p>
<p><code>tsgolint</code> 项目最初作为 <a href="https://github.com/typescript-eslint/tsgolint" target="_blank" rel="noreferrer">typescript-eslint/tsgolint</a> 进行原型设计。
然而，<code>typescript-eslint</code> 团队决定不为该原型分配开发资源，因为他们计划继续致力于使用 ESLint 进行类型化 linting 的 <code>typescript-eslint</code> 工作。</p>
<p><a href="https://github.com/Boshen" target="_blank" rel="noreferrer">@boshen</a> 联系了 <a href="https://github.com/auvred" target="_blank" rel="noreferrer">@auvred</a>，希望获得一个针对 oxlint 适配的、范围缩小的分支版本。
此版本将仅包含类型感知规则，而不需要完整 linter 所需的复杂配置解析。</p>
<p><a href="https://github.com/auvred" target="_blank" rel="noreferrer">@auvred</a> 慷慨地提出在 Oxc 组织下继续其开发工作。</p>
<h3 id="架构" tabindex="-1">架构 <a class="header-anchor" href="#架构" aria-label="Permalink to “架构”">&#8203;</a></h3>
<p><code>oxlint</code>（用 Rust 编写）和 <code>tsgolint</code>（用 Go 编写）被编译为各自的二进制文件。</p>
<p><code>oxlint</code> 作为 <code>tsgolint</code> 的“前端”，处理 CLI、路径遍历、忽略逻辑和诊断信息打印。</p>
<p><code>tsgolint</code> 作为 <code>oxlint</code> 的后端，接受路径和配置作为输入，并输出结构化的诊断信息。</p>
<p>这创建了一个简单的管道：</p>
<div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span>oxlint CLI (returns paths + rules + configuration)</span></span>
<span class="line"><span>  -> tsgolint (returns diagnostics)</span></span>
<span class="line"><span>  -> oxlint CLI (prints diagnostics)</span></span></code></pre>
</div><h3 id="tsgolint" tabindex="-1"><code>tsgolint</code> <a class="header-anchor" href="#tsgolint" aria-label="Permalink to “tsgolint”">&#8203;</a></h3>
<p><code>tsgolint</code> 不通过公共 API 与 typescript-go 通信。</p>
<p>相反，它通过 <a href="https://github.com/oxc-project/tsgolint/tree/main/shim" target="_blank" rel="noreferrer">shim</a> 其内部 API 使其公开，从而编译 <code>typescript-go</code>。</p>
<p>所有类型感知规则都是直接针对这些 shim 化的 API 编写的。</p>
<p>虽然这不是访问内部结构的推荐方法，但它有效！</p>
<h2 id="决策过程" tabindex="-1">决策过程 <a class="header-anchor" href="#决策过程" aria-label="Permalink to “决策过程”">&#8203;</a></h2>
<h3 id="编写我们自己的类型检查器" tabindex="-1">编写我们自己的类型检查器 <a class="header-anchor" href="#编写我们自己的类型检查器" aria-label="Permalink to “编写我们自己的类型检查器”">&#8203;</a></h3>
<p>之前放弃的实现类型检查器的尝试包括：</p>
<ul>
<li>我自己尝试 <a href="https://gist.github.com/Boshen/d189de0fe0720a30c5182cb666e3e9a5" target="_blank" rel="noreferrer">编写类型推断</a></li>
<li><a href="https://github.com/oxc-project/oxc/pull/413" target="_blank" rel="noreferrer">集成</a> <a href="https://github.com/kaleidawave/ezno" target="_blank" rel="noreferrer">ezno 类型检查器</a> by <a href="https://github.com/kaleidawave" target="_blank" rel="noreferrer">@kaleidawave</a></li>
<li><a href="https://github.com/dudykr/stc" target="_blank" rel="noreferrer">stc</a> by <a href="https://github.com/kdy1" target="_blank" rel="noreferrer">@kdy1</a></li>
<li>社区中还有许多没有走得太远的尝试。</li>
</ul>
<p>此外，还有正在进行的 <a href="https://biomejs.dev/blog/biome-v2/" target="_blank" rel="noreferrer">Biome 2.0</a> 及其自己的类型推断实现。</p>
<p>我们确定编写自己的类型推断器或类型检查器不可行，因为
难以跟上像 TypeScript 这样快速变化的目标。</p>
<h3 id="与-typescript-编译器通信" tabindex="-1">与 TypeScript 编译器通信 <a class="header-anchor" href="#与-typescript-编译器通信" aria-label="Permalink to “与 TypeScript 编译器通信”">&#8203;</a></h3>
<p>在 <code>typescript-go</code> 之前，项目通过将 AST 映射到 <code>estree</code> 或直接遍历 TypeScript AST，将插件接口添加到 TypeScript 的公共 API 中。例如：</p>
<ul>
<li><a href="https://typescript-eslint.io/getting-started/typed-linting" target="_blank" rel="noreferrer">typescript-eslint</a></li>
<li><a href="https://github.com/johnsoncodehk/tsslint" target="_blank" rel="noreferrer">tsslint</a></li>
<li><a href="https://github.com/ArnaudBarre/tsl" target="_blank" rel="noreferrer">tsl</a></li>
</ul>
<p>我们还探讨了 <a href="https://github.com/oxc-project/oxc/discussions/2855" target="_blank" rel="noreferrer">与 oxlint 的进程间通信</a>，但放弃了这个想法。</p>
<p>随着 <code>typescript-go</code> 的出现，TypeScript 团队 <a href="https://github.com/microsoft/typescript-go/discussions/455" target="_blank" rel="noreferrer">倾向于</a>
编码 TypeScript AST 并通过进程间通信在 JavaScript 端解码。</p>
<p>虽然这些方法可行，但它们仍然会产生：</p>
<ul>
<li>不同程度的性能问题，不适合 oxlint 的性能特征。</li>
<li>维护从 TypeScript AST 映射的 AST 的成本。</li>
</ul>
<h2 id="注意事项" tabindex="-1">注意事项 <a class="header-anchor" href="#注意事项" aria-label="Permalink to “注意事项”">&#8203;</a></h2>
<p>虽然 <code>tsgolint</code> 解决了性能问题，但还有其他技术挑战需要解决。</p>
<h3 id="需要不同版本的-typescript" tabindex="-1">需要不同版本的 TypeScript <a class="header-anchor" href="#需要不同版本的-typescript" aria-label="Permalink to “需要不同版本的 TypeScript”">&#8203;</a></h3>
<p>我们计划发布 <code>typescript-go</code> 版本的快照，并将其版本号与 TypeScript 对齐。
届时您将能够安装具有正确 TypeScript 版本的 <code>oxlint-typescript</code>。</p>
<p>这种方法的缺点是，如果 <code>oxlint-tsgolint</code> 需要更改，您可能需要升级 TypeScript。</p>
<h3 id="tsgolint-的维护成本" tabindex="-1"><code>tsgolint</code> 的维护成本 <a class="header-anchor" href="#tsgolint-的维护成本" aria-label="Permalink to “tsgolint 的维护成本”">&#8203;</a></h3>
<p>Shim TypeScript 的内部 API 带有一些风险。然而，TypeScript AST 及其访问者实际上相当稳定。
我们接受此风险，并将在升级 <code>typescript-go</code> 时修复破坏性变更。</p>
<p>我们的 <code>typescript-go</code> 版本每天同步。</p>
<h2 id="性能问题" tabindex="-1">性能问题 <a class="header-anchor" href="#性能问题" aria-label="Permalink to “性能问题”">&#8203;</a></h2>
<p><code>tsgolint</code> 目前在具有数百个项目或大量项目引用的大型单体仓库上表现不佳。</p>
<p>如果遇到 bug，它可能会因死锁而挂起或导致 OOM（内存不足）。</p>
<p>我们正在积极解决这些问题，对 <code>typescript-go</code> 进行性能分析并提交改进，使所有 <code>typescript-go</code> 用户受益。</p>
<p>我们的核心团队成员 <a href="https://github.com/camc314" target="_blank" rel="noreferrer">@camc314</a> 已经提交了 <a href="https://github.com/microsoft/typescript-go/pulls?q=is%3Apr+author%3Acamc314+" target="_blank" rel="noreferrer">许多 PR</a>，使 several code paths 显著更快。</p>
<h2 id="v1-0-发布" tabindex="-1">v1.0 发布 <a class="header-anchor" href="#v1-0-发布" aria-label="Permalink to “v1.0 发布”">&#8203;</a></h2>
<p>对于 <code>tsgolint</code> v1.0，我们将解决：</p>
<ul>
<li>大型单体仓库的性能问题</li>
<li>能够配置单个规则</li>
<li>每个单独规则的正确性</li>
<li>IDE 支持</li>
<li>整体稳定性</li>
</ul>
<h2 id="致谢" tabindex="-1">致谢 <a class="header-anchor" href="#致谢" aria-label="Permalink to “致谢”">&#8203;</a></h2>
<p>我们要向以下各方表示感谢：</p>
<ul>
<li>TypeScript 团队创建了 <code>typescript-go</code>。</li>
<li><code>typescript-eslint</code> 团队给予的暖心支持。</li>
<li><a href="https://github.com/auvred" target="_blank" rel="noreferrer">@auvred</a> 创建了 <code>tsgolint</code>。</li>
<li><a href="https://github.com/camchenry" target="_blank" rel="noreferrer">@camchenry</a> 完成了 <code>oxlint</code> + <code>tsgolint</code> 集成。</li>
<li><a href="https://github.com/camc314" target="_blank" rel="noreferrer">@camc314</a> 致力于性能问题的工作。</li>
</ul>
<h2 id="加入社区" tabindex="-1">加入社区 <a class="header-anchor" href="#加入社区" aria-label="Permalink to “加入社区”">&#8203;</a></h2>
<p>我们很希望听到您对 <code>oxlint</code> 和类型感知 linting 的反馈，并很高兴看到它如何帮助改善您的开发工作流程。</p>
<p>联系我们：</p>
<ul>
<li><strong>Discord</strong>: 加入我们的 <a href="https://discord.gg/9uXCAwqQZW" target="_blank" rel="noreferrer">社区服务器</a> 进行实时讨论</li>
<li><strong>GitHub</strong>: 在 <a href="https://github.com/oxc-project/oxc/discussions" target="_blank" rel="noreferrer">GitHub Discussions</a> 分享反馈</li>
<li><strong>Issues</strong>: 向 <a href="https://github.com/oxc-project/oxc/issues" target="_blank" rel="noreferrer">oxc</a> 报告 <code>oxlint</code> bug，向 <a href="https://github.com/oxc-project/tsgolint/issues" target="_blank" rel="noreferrer">tsgolint</a> 报告类型感知 linting bug。</li>
</ul>
<h2 id="下一步" tabindex="-1">下一步 <a class="header-anchor" href="#下一步" aria-label="Permalink to “下一步”">&#8203;</a></h2>
<p>安装 <code>oxlint</code>：</p>
<div class="language-bash"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">pnpm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> add</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -D</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint@latest</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint-tsgolint@latest</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">pnpm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> dlx</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> --init</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D"> # generate .oxlintrc.json</span></span></code></pre>
</div><p>或遵循 <a href="https://oxc.rs/docs/guide/usage/linter" target="_blank" rel="noreferrer">安装指南</a>。</p>
<p>使用 <code>--type-aware</code> CLI 标志。</p>
<div class="language-bash"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">pnpm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> dlx</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> --type-aware</span></span></code></pre>
</div><p>并在 <code>.oxlintrc.json</code> 中尝试任何类型感知规则：</p>
<div class="language-json"><button title="Copy Code" class="copy"></button><span class="lang">json</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">{</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">  "$schema"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"./node_modules/oxlint/configuration_schema.json"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">  "rules"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: {</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "typescript/await-thenable"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "typescript/no-array-delete"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "typescript/no-base-to-string"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "typescript/no-confusing-void-expression"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "typescript/no-duplicate-type-constituents"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "typescript/no-floating-promises"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "typescript/no-for-in-array"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "typescript/no-implied-eval"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "typescript/no-meaningless-void-operator"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "typescript/no-misused-promises"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "typescript/no-misused-spread"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "typescript/no-mixed-enums"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "typescript/no-redundant-type-constituents"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "typescript/no-unnecessary-boolean-literal-compare"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "typescript/no-unnecessary-template-expression"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "typescript/no-unnecessary-type-arguments"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "typescript/no-unnecessary-type-assertion"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "typescript/no-unsafe-argument"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "typescript/no-unsafe-assignment"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "typescript/no-unsafe-call"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "typescript/no-unsafe-enum-comparison"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "typescript/no-unsafe-member-access"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "typescript/no-unsafe-return"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "typescript/no-unsafe-type-assertion"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "typescript/no-unsafe-unary-minus"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "typescript/non-nullable-type-assertion-style"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "typescript/only-throw-error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "typescript/prefer-promise-reject-errors"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "typescript/prefer-reduce-type-parameter"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "typescript/prefer-return-this-type"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "typescript/promise-function-async"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "typescript/related-getter-setter-pairs"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "typescript/require-array-sort-compare"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "typescript/require-await"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "typescript/restrict-plus-operands"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "typescript/restrict-template-expressions"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "typescript/return-await"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "typescript/switch-exhaustiveness-check"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "typescript/unbound-method"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "typescript/use-unknown-in-catch-callback-variable"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span></code></pre>
</div>]]></content>
        <author>
            <name>Boshen</name>
            <uri>https://github.com/Boshen</uri>
        </author>
        <author>
            <name>auvred</name>
            <uri>https://github.com/auvred</uri>
        </author>
        <author>
            <name>Cam</name>
            <uri>https://github.com/camchenry</uri>
        </author>
        <author>
            <name>Cameron</name>
            <uri>https://github.com/camc314</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Oxlint JS 插件预览]]></title>
        <id>https://oxc.rs/blog/2025-10-09-oxlint-js-plugins</id>
        <link href="https://oxc.rs/blog/2025-10-09-oxlint-js-plugins"/>
        <updated>2025-10-09T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[<AppBlogPostHeader /><Alert type="info">
<p><strong>本文宣布 Oxlint JS 插件的预览版发布。</strong> JS 插件此后已达到 Alpha 阶段！请参阅 <a href="/blog/2026-03-11-oxlint-js-plugins-alpha.html">Oxlint JS Plugins Alpha 公告</a> 了解最新特性和改进。</p>
</Alert>
<br>
<p>今年早些时候，<a href="https://github.com/oxc-project/oxc/discussions/10342" target="_blank" rel="noreferrer">我们向社区征求了意见</a>，
以便为 Oxlint 支持自定义 JS 插件的设计提供参考。今天，我们很高兴地宣布经过数月
的研究、原型设计，以及最终的构建成果：</p>
<p><strong>Oxlint 支持用 JS 编写的插件！</strong></p>
<h4 id="主要特性" tabindex="-1">主要特性 <a class="header-anchor" href="#主要特性" aria-label="Permalink to “主要特性”">&#8203;</a></h4>
<ul>
<li>与 ESLint 兼容的插件 API。Oxlint 将能够运行许多现有的 ESLint 插件而无需修改。</li>
<li>另一种略有不同的 API，可实现更好的性能。</li>
</ul>
<h4 id="这是什么以及不是什么" tabindex="-1">这是什么以及不是什么 <a class="header-anchor" href="#这是什么以及不是什么" aria-label="Permalink to “这是什么以及不是什么”">&#8203;</a></h4>
<p>此预览版仅仅是个开始。重要的是要注意：</p>
<ul>
<li>此初始版本并未实现 ESLint 插件 API 的全部功能。</li>
<li>性能不错，但会变得<em>更加</em>出色——我们有许多优化正在计划中。</li>
</ul>
<p>用于代码检查规则的最常用 API <a href="#features">已实现</a>，因此许多现有的 ESLint 规则已经可以工作。
但与 token 相关的 API 尚未包含，因此风格（格式化）规则将无法工作。</p>
<p>我们邀请用户试用一下，提供反馈，并为下一阶段的开发优先事项提供参考。</p>
<h4 id="本文涵盖内容" tabindex="-1">本文涵盖内容 <a class="header-anchor" href="#本文涵盖内容" aria-label="Permalink to “本文涵盖内容”">&#8203;</a></h4>
<ol>
<li>如何使用它。</li>
<li>接下来会有什么。</li>
<li>一些技术细节，使我们能够采用“鱼与熊掌兼得”的方法，既提供 ESLint 兼容性
<strong>又</strong> 提供卓越的性能。</li>
</ol>
<h2 id="快速开始" tabindex="-1">快速开始 <a class="header-anchor" href="#快速开始" aria-label="Permalink to “快速开始”">&#8203;</a></h2>
<p>在项目中安装 Oxlint：</p>
<div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">pnpm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> add</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -D</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint</span></span></code></pre>
</div><p>编写自定义 JS 插件：</p>
<div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">// plugin.js</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">// 最简单的规则 - 禁止 debugger</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> rule</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">  create</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">context</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">) {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">    return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">      DebuggerStatement</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">node</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">) {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">        context.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">report</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">({</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">          message: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"No debugger!"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">          node,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">        });</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">      },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    };</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">};</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> plugin</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  meta: {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"best-plugin-ever"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  rules: {</span></span>
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">    "no-debugger"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: rule,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">};</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> default</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> plugin;</span></span></code></pre>
</div><p>创建启用插件的配置文件：</p>
<div class="language-json"><button title="Copy Code" class="copy"></button><span class="lang">json</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">// .oxlintrc.json</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">{</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">  "jsPlugins"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"./plugin.js"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">],</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">  "rules"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: {</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "best-plugin-ever/no-debugger"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span></code></pre>
</div><p>添加一个待检查的文件：</p>
<div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">// foo.js</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">debugger</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">;</span></span></code></pre>
</div><p>运行 Oxlint：</p>
<div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">pnpm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint</span></span></code></pre>
</div><p>预期看到：</p>
<div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span> x best-plugin-ever(no-debugger): No debugger!</span></span>
<span class="line"><span>  ,-[foo.js:1:1]</span></span>
<span class="line"><span>1 | debugger;</span></span>
<span class="line"><span>  : ^^^^^^^^^</span></span>
<span class="line"><span>  `</span></span></code></pre>
</div>]]></summary>
        <content type="html"><![CDATA[<AppBlogPostHeader /><Alert type="info">
<p><strong>本文宣布 Oxlint JS 插件的预览版发布。</strong> JS 插件此后已达到 Alpha 阶段！请参阅 <a href="/blog/2026-03-11-oxlint-js-plugins-alpha.html">Oxlint JS Plugins Alpha 公告</a> 了解最新特性和改进。</p>
</Alert>
<br>
<p>今年早些时候，<a href="https://github.com/oxc-project/oxc/discussions/10342" target="_blank" rel="noreferrer">我们向社区征求了意见</a>，
以便为 Oxlint 支持自定义 JS 插件的设计提供参考。今天，我们很高兴地宣布经过数月
的研究、原型设计，以及最终的构建成果：</p>
<p><strong>Oxlint 支持用 JS 编写的插件！</strong></p>
<h4 id="主要特性" tabindex="-1">主要特性 <a class="header-anchor" href="#主要特性" aria-label="Permalink to “主要特性”">&#8203;</a></h4>
<ul>
<li>与 ESLint 兼容的插件 API。Oxlint 将能够运行许多现有的 ESLint 插件而无需修改。</li>
<li>另一种略有不同的 API，可实现更好的性能。</li>
</ul>
<h4 id="这是什么以及不是什么" tabindex="-1">这是什么以及不是什么 <a class="header-anchor" href="#这是什么以及不是什么" aria-label="Permalink to “这是什么以及不是什么”">&#8203;</a></h4>
<p>此预览版仅仅是个开始。重要的是要注意：</p>
<ul>
<li>此初始版本并未实现 ESLint 插件 API 的全部功能。</li>
<li>性能不错，但会变得<em>更加</em>出色——我们有许多优化正在计划中。</li>
</ul>
<p>用于代码检查规则的最常用 API <a href="#features">已实现</a>，因此许多现有的 ESLint 规则已经可以工作。
但与 token 相关的 API 尚未包含，因此风格（格式化）规则将无法工作。</p>
<p>我们邀请用户试用一下，提供反馈，并为下一阶段的开发优先事项提供参考。</p>
<h4 id="本文涵盖内容" tabindex="-1">本文涵盖内容 <a class="header-anchor" href="#本文涵盖内容" aria-label="Permalink to “本文涵盖内容”">&#8203;</a></h4>
<ol>
<li>如何使用它。</li>
<li>接下来会有什么。</li>
<li>一些技术细节，使我们能够采用“鱼与熊掌兼得”的方法，既提供 ESLint 兼容性
<strong>又</strong> 提供卓越的性能。</li>
</ol>
<h2 id="快速开始" tabindex="-1">快速开始 <a class="header-anchor" href="#快速开始" aria-label="Permalink to “快速开始”">&#8203;</a></h2>
<p>在项目中安装 Oxlint：</p>
<div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">pnpm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> add</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -D</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint</span></span></code></pre>
</div><p>编写自定义 JS 插件：</p>
<div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">// plugin.js</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">// 最简单的规则 - 禁止 debugger</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> rule</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">  create</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">context</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">) {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">    return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">      DebuggerStatement</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">node</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">) {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">        context.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">report</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">({</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">          message: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"No debugger!"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">          node,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">        });</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">      },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    };</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">};</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> plugin</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  meta: {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"best-plugin-ever"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  rules: {</span></span>
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">    "no-debugger"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: rule,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">};</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> default</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> plugin;</span></span></code></pre>
</div><p>创建启用插件的配置文件：</p>
<div class="language-json"><button title="Copy Code" class="copy"></button><span class="lang">json</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">// .oxlintrc.json</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">{</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">  "jsPlugins"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"./plugin.js"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">],</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">  "rules"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: {</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "best-plugin-ever/no-debugger"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span></code></pre>
</div><p>添加一个待检查的文件：</p>
<div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">// foo.js</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">debugger</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">;</span></span></code></pre>
</div><p>运行 Oxlint：</p>
<div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">pnpm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint</span></span></code></pre>
</div><p>预期看到：</p>
<div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span> x best-plugin-ever(no-debugger): No debugger!</span></span>
<span class="line"><span>  ,-[foo.js:1:1]</span></span>
<span class="line"><span>1 | debugger;</span></span>
<span class="line"><span>  : ^^^^^^^^^</span></span>
<span class="line"><span>  `----</span></span></code></pre>
</div><p>有关编写插件的更多详情，请参阅 <a href="/docs/guide/usage/linter/writing-js-plugins.html">文档</a>。</p>
<h2 id="替代-api" tabindex="-1">替代 API <a class="header-anchor" href="#替代-api" aria-label="Permalink to “替代 API”">&#8203;</a></h2>
<p>Oxlint 还提供了一种略有不同的 API，可实现更好的性能。</p>
<p><strong>此替代 API 生成的插件既兼容 ESLint，也兼容 Oxlint。</strong></p>
<p>示例规则：标记包含超过 5 个类声明的文件：</p>
<h4 id="eslint-版本" tabindex="-1">ESLint 版本 <a class="header-anchor" href="#eslint-版本" aria-label="Permalink to “ESLint 版本”">&#8203;</a></h4>
<div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> rule</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">  create</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">context</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">) {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">    let</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> classCount </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> 0</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">    return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">      ClassDeclaration</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">node</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">) {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">        classCount</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">++</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">        if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> (classCount </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">===</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> 6</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">) {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">          context.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">report</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">({ message: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"Too many classes"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, node });</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">        }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">      },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    };</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">};</span></span></code></pre>
</div><h4 id="替代-api-版本" tabindex="-1">替代 API 版本 <a class="header-anchor" href="#替代-api-版本" aria-label="Permalink to “替代 API 版本”">&#8203;</a></h4>
<div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> { defineRule } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> "oxlint"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> rule</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> defineRule</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">({</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">  createOnce</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">context</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">) {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">    // 定义计数器变量</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">    let</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> classCount;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">    return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">      before</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">() {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">        // 在遍历每个文件的 AST 之前重置计数器</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">        classCount </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> 0</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">      },</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">      // 与之前相同</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">      ClassDeclaration</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">node</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">) {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">        classCount</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">++</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">        if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> (classCount </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">===</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> 6</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">) {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">          context.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">report</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">({ message: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"Too many classes"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, node });</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">        }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">      },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    };</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">});</span></span></code></pre>
</div><h4 id="差异" tabindex="-1">差异 <a class="header-anchor" href="#差异" aria-label="Permalink to “差异”">&#8203;</a></h4>
<ol>
<li>将规则对象包裹在 <code>defineRule(...)</code> 中。</li>
</ol>
<div class="language-diff"><button title="Copy Code" class="copy"></button><span class="lang">diff</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#B31D28;--shiki-dark:#FDAEB7">- const rule = {</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">+ const rule = defineRule({</span></span></code></pre>
</div><ol start="2">
<li>使用 <code>createOnce</code> 代替 <code>create</code>。</li>
</ol>
<div class="language-diff"><button title="Copy Code" class="copy"></button><span class="lang">diff</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#B31D28;--shiki-dark:#FDAEB7">-   create(context) {</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">+   createOnce(context) {</span></span></code></pre>
</div><ol start="3">
<li>将任何每文件设置从 <code>create</code> 主体移动到 <code>before</code> 钩子。</li>
</ol>
<div class="language-diff"><button title="Copy Code" class="copy"></button><span class="lang">diff</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#B31D28;--shiki-dark:#FDAEB7">-     let classCount = 0;</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">+     let classCount;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">      return {</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">+       before() {</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">+         classCount = 0; // 重置计数器</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">+       },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">        ClassDeclaration(node) {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">          classCount++;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">          if (classCount === 6) {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">            context.report({ message: "Too many classes", node });</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">          }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">        },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">      };</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  });</span></span></code></pre>
</div><p>这是唯一的显著差异——<code>create</code>（ESLint 的方法）<em>为每个文件</em> 重复调用，
而 <code>createOnce</code> 仅调用一次。</p>
<p>所有其他 API 的行为与 ESLint 完全相同。</p>
<p>为何此替代 API 有可能大幅提高性能的原因在
<a href="/docs/guide/usage/linter/writing-js-plugins.html#why-is-the-alternative-api-faster">文档</a> 中解释。</p>
<h2 id="性能" tabindex="-1">性能 <a class="header-anchor" href="#性能" aria-label="Permalink to “性能”">&#8203;</a></h2>
<p>如上所述，在 Oxlint JS 插件的此初始预览版中，性能并非我们的关注重点。
我们的主要目标是填充足够的 API，使 JS 插件在实际项目中有用，
并收集早期采用者的反馈。</p>
<p>目前的性能尚可，但绝不出色。</p>
<p>然而——我们认为这是重点——我们<em>下一个</em> 版本的原型表明，
一旦加入各种优化（参见 <a href="#under-the-hood">幕后技术</a>），
我们确定的架构设计能够实现<em>卓越</em> 的性能。</p>
<p>我们将在未来几个月内应用这些优化，用户将看到相比当前版本有多倍的速度提升。</p>
<p>话虽如此，即使没有这些优化，Oxlint 的性能仍然具有竞争力。</p>
<p>Oxlint 与 ESLint 检查中型 TypeScript 项目 <a href="https://github.com/vuejs/core" target="_blank" rel="noreferrer">vuejs/core</a> 的对比：</p>
<table tabindex="0">
<thead>
<tr>
<th>Linter</th>
<th>Time</th>
</tr>
</thead>
<tbody>
<tr>
<td>ESLint</td>
<td>4,116 ms</td>
</tr>
<tr>
<td>ESLint multi-threaded</td>
<td>3,710 ms</td>
</tr>
<tr>
<td>Oxlint</td>
<td>48 ms</td>
</tr>
<tr>
<td>Oxlint with custom JS plugin</td>
<td>236 ms</td>
</tr>
</tbody>
</table>
<div>
<details>
<summary>详情</summary>
<div  class="info custom-block"><p class="custom-block-title custom-block-title-default">INFO</p>
<ul>
<li>基准测试仓库：<a href="https://github.com/overlookmotel/vue-core-cam/tree/bench-js-plugins" target="_blank" rel="noreferrer">https://github.com/overlookmotel/vue-core-cam/tree/bench-js-plugins</a></li>
<li>基准测试环境：MacBook Air M3, 24GB RAM</li>
<li>基准测试命令：</li>
</ul>
<div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">hyperfine</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -i</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> --warmup</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> 3</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> \</span></span>
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">  './node_modules/.bin/oxlint --silent'</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> \</span></span>
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">  './node_modules/.bin/oxlint -c .oxlintrc-with-custom-plugin.json --silent'</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> \</span></span>
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">  'USE_CUSTOM_PLUGIN=true ./node_modules/.bin/eslint .'</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> \</span></span>
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">  'USE_CUSTOM_PLUGIN=true ./node_modules/.bin/eslint . --concurrency=auto'</span></span></code></pre>
</div><p>注意：撰写本文时 NPM 上的 Oxlint 版本 (1.23.0) 存在一个影响此基准测试的 bug，并且极大地
低估了 JS 插件的开销。上述结果是使用最新的 <code>main</code> 分支，在修复 bug 后，
在 <a href="https://github.com/oxc-project/oxc/commit/cd266b4c101c35c33e122457cdd0b514b44597a9" target="_blank" rel="noreferrer">此提交</a> 处获得的。
另见 <a href="#edit-18th-oct-2025">下方</a>。</p>
</div>
</details>
</div>
<p>在此示例中，向 Oxlint 添加一个简单的 JS 插件确实会产生显著开销，但 Oxlint 仍然比
ESLint 快 15 倍，即使使用 ESLint 新的多线程运行器。</p>
<p>显然，更复杂的 JS 插件，或许多插件，将具有更高的性能成本。</p>
<h2 id="特性" tabindex="-1">特性 <a class="header-anchor" href="#特性" aria-label="Permalink to “特性”">&#8203;</a></h2>
<p>Oxlint 支持大多数通常用于仅依赖 AST 检查的插件/规则中的 ESLint API。
这包括大多数“修复代码”类规则。</p>
<p>它尚未支持基于 token 的 API，因此风格（格式化）规则暂时无法工作。</p>
<h4 id="已支持" tabindex="-1">已支持 <a class="header-anchor" href="#已支持" aria-label="Permalink to “已支持”">&#8203;</a></h4>
<ul>
<li>AST 遍历</li>
<li>AST 探索（<code>node.parent</code>, <code>context.sourceCode.getAncestors</code>）</li>
<li>修复</li>
<li>选择器（<a href="https://eslint.org/docs/latest/extend/selectors" target="_blank" rel="noreferrer">ESLint 文档</a>）</li>
<li><code>SourceCode</code> API（例如 <code>context.sourceCode.getText(node)</code>）</li>
</ul>
<h4 id="尚未支持" tabindex="-1">尚未支持 <a class="header-anchor" href="#尚未支持" aria-label="Permalink to “尚未支持”">&#8203;</a></h4>
<ul>
<li>语言服务器 (IDE) 支持</li>
<li>规则选项</li>
<li>建议</li>
<li><s>作用域分析</s>（自 v1.25.0 起 <a href="https://github.com/oxc-project/oxc/pull/14890" target="_blank" rel="noreferrer">已实现</a>）</li>
<li>与 token 和注释相关的 <code>SourceCode</code> API（例如 <code>context.sourceCode.getTokens(node)</code>）</li>
<li>控制流分析</li>
</ul>
<h2 id="接下来会有什么" tabindex="-1">接下来会有什么 <a class="header-anchor" href="#接下来会有什么" aria-label="Permalink to “接下来会有什么”">&#8203;</a></h2>
<p>在未来几个月内，我们将：</p>
<h4 id="_1-完善插件-api-覆盖面" tabindex="-1">1. 完善插件 API 覆盖面 <a class="header-anchor" href="#_1-完善插件-api-覆盖面" aria-label="Permalink to “1. 完善插件 API 覆盖面”">&#8203;</a></h4>
<p>目标是支持 100% 的 ESLint 插件 API 覆盖面，以便 Oxlint 最终能够运行<em>任何</em> ESLint
插件而无需修改。</p>
<h4 id="_2-提升性能" tabindex="-1">2. 提升性能 <a class="header-anchor" href="#_2-提升性能" aria-label="Permalink to “2. 提升性能”">&#8203;</a></h4>
<p>性能已经不错，但我们在原型设计期间证明了进一步优化会带来许多显著的性能提升。我们将应用它们，
使 Oxlint 中的 JS 插件运行速度尽可能接近 Rust 速度。</p>
<h2 id="幕后技术" tabindex="-1">幕后技术 <a class="header-anchor" href="#幕后技术" aria-label="Permalink to “幕后技术”">&#8203;</a></h2>
<p>本文的其余部分对于使用 Oxlint 的 JS 插件并非必需。但如果你对我们实现方式的
技术细节感兴趣，请继续阅读...</p>
<h3 id="大问题-是否兼容-eslint" tabindex="-1">大问题：是否兼容 ESLint？ <a class="header-anchor" href="#大问题-是否兼容-eslint" aria-label="Permalink to “大问题：是否兼容 ESLint？”">&#8203;</a></h3>
<p>今年早些时候，<a href="https://github.com/oxc-project/oxc/discussions/10342" target="_blank" rel="noreferrer">我们向社区提出的问题</a>
是 Oxlint 是否应该旨在实现与 ESLint 兼容的插件 API。</p>
<p>显然，就熟悉度和从 ESLint 迁移的便利性而言，与 ESLint 兼容的接口是理想的。</p>
<p>然而，Oxlint 以其卓越的性能而闻名，过多妥协并不可取。</p>
<p>过去几个月我们原型设计工作的主要目标是量化性能
与 ESLint 兼容性之间的权衡，并调查是否存在一种“鱼与熊掌兼得”的解决方案，能够同时满足两者——
提供与 ESLint 兼容的 API <em>和</em> 可接受的性能（这里的“可接受”意味着非常快！）</p>
<p>我们相信通过结合不同的方法，我们找到了一种满足两者需求的方式。</p>
<h3 id="替代-api-1" tabindex="-1">替代 API <a class="header-anchor" href="#替代-api-1" aria-label="Permalink to “替代 API”">&#8203;</a></h3>
<p>请参阅 <a href="/docs/guide/usage/linter/writing-js-plugins.html#why-is-the-alternative-api-faster">文档</a> 中的解释，
了解为何此 API 能释放更高性能的潜力。</p>
<h3 id="原始传输" tabindex="-1">原始传输 <a class="header-anchor" href="#原始传输" aria-label="Permalink to “原始传输”">&#8203;</a></h3>
<p>像 Oxc 这样的工具将 JS/TS 文件的代码表示为&quot;AST&quot;
（<a href="https://en.wikipedia.org/wiki/Abstract_syntax_tree" target="_blank" rel="noreferrer">抽象语法树</a>）。
AST 非常大——比它们代表的源代码大得多。</p>
<p>通常，JS 与 Rust 等原生语言之间进行高性能互操作的最大障碍是
在“两个世界”之间传输如此大型数据结构所涉及的序列化
和反序列化。</p>
<p>在 JS 和 Rust 之间移动 AST 最简单和最常见的方法是：将 AST 序列化为 JSON，作为字符串发送到 JS，
然后使用 <code>JSON.parse</code> 再次“还原”它。但这非常慢。通常这些
转换的成本如此之高，以至于它们大大超过了首先使用原生代码所带来的性能增益。
其他序列化格式比 JSON 更高效，但它们仍然有相当大的开销。</p>
<p>我们开发了一种“原始传输”方案，通过使用 Rust 的原生内存布局作为序列化格式，完全消除了序列化（有关其工作原理的更多详情见 <a href="https://github.com/oxc-project/oxc/issues/2409" target="_blank" rel="noreferrer">此处</a>）。</p>
<p>“原始传输”是当前 JS 插件实现的基础。</p>
<h3 id="惰性反序列化" tabindex="-1">惰性反序列化 <a class="header-anchor" href="#惰性反序列化" aria-label="Permalink to “惰性反序列化”">&#8203;</a></h3>
<p>良好性能的第二大敌人，特别是在工作线程中跨多个 CPU 核心运行 JS 时，
是垃圾回收器。你创建的每个对象也需要被销毁以回收其内存。
在 JS 中，这是垃圾回收器的工作。像 V8 这样的 JS 引擎经过高度优化，但垃圾回收
仍然是一个昂贵的过程，并且 GC 会“窃取”实际工作负载的 CPU 资源。</p>
<p>我们原型化了一个 AST 访问器，它<em>惰性</em> 地反序列化 AST，并且只反序列化实际上<em>需要</em> 的 AST 部分。</p>
<p>例如，如果你的 lint 规则与类声明有关，此访问器将飞过大部分 AST 而不做太多事情，
并且只会为 <code>ClassDeclaration</code> AST 节点创建 JS 对象，然后将这些对象传递给规则的代码
进行处理。对于其余的 AST（变量声明、<code>if</code> 语句、函数等），根本不需要创建
节点对象。</p>
<p>这有 2 个效果：</p>
<ol>
<li>原始传输将序列化成本降为零。惰性也大大减少了另一面
（反序列化）。</li>
<li>大大降低了垃圾回收器压力。</li>
</ol>
<p>Deno 采用了类似的方法，这在
<a href="https://marvinh.dev/blog/speeding-up-javascript-ecosystem-part-11/" target="_blank" rel="noreferrer">Marvin Hagemeister 的博客文章</a> 中解释得非常精彩，并且 Deno lint
有一个非常高效的实现。</p>
<p>然而，我们发现正是惰性反序列化与“原始传输”的结合提供了<em>真正</em> 好的
性能。我们的测试发现，消除了这两项开销后，JS 插件可以以更快的速度运行。</p>
<p>此优化尚未包含在当前版本的 JS 插件中。我们将在未来版本中实现它。</p>
<h2 id="试一试" tabindex="-1">试一试！ <a class="header-anchor" href="#试一试" aria-label="Permalink to “试一试！”">&#8203;</a></h2>
<p>请尝试一下 JS 插件并报告您的体验。所有反馈——无论是正面的还是负面的——我们都感激不尽。</p>
<p>特别是，如果您发现 Oxlint 缺少您的插件工作所需的一些 API，请告诉我们。我们将在未来几个月内填补 API 的空白，并将优先考虑需求最大的那些。</p>
<p>祝您 lint 愉快！</p>
<hr>
<h4 id="编辑-2025-年-10-月-18-日" tabindex="-1">编辑：2025 年 10 月 18 日 <a class="header-anchor" href="#编辑-2025-年-10-月-18-日" aria-label="Permalink to “编辑：2025 年 10 月 18 日”">&#8203;</a></h4>
<p>这篇博客文章最初于 10 月 9 日发布的版本包含了一些基准测试结果，显示 Oxlint JS 插件的性能比实际情况要好得多。这是由于 Oxlint 中的一个 bug 造成的，该 bug 导致在某些情况下，当配置包含 overrides 时，许多文件会跳过 JS 插件。这个 bug 导致我们引用的基准测试中 JS 插件的性能被严重高估。</p>
<p>我们为这个错误真诚地道歉，并感谢 <a href="https://github.com/HerringtonDarkholme" target="_blank" rel="noreferrer">Herrington Darkholme</a> 指出了这个错误。</p>
]]></content>
        <author>
            <name>overlookmotel</name>
            <uri>https://github.com/overlookmotel</uri>
        </author>
        <author>
            <name>Cameron</name>
            <uri>https://github.com/camc314</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Oxfmt: Oxc 格式化器 Alpha 版]]></title>
        <id>https://oxc.rs/blog/2025-12-01-oxfmt-alpha</id>
        <link href="https://oxc.rs/blog/2025-12-01-oxfmt-alpha"/>
        <updated>2025-12-01T00:00:00.000Z</updated>
        <content type="html"><![CDATA[<AppBlogPostHeader /><Alert type="info">
<p><strong>本文宣布 Oxfmt 的 Alpha 版本发布。</strong> Oxfmt 此后已达到 Beta 版！请参阅 <a href="/blog/2026-02-24-oxfmt-beta.html">Oxfmt Beta 版本公告</a> 以了解最新功能和改进。</p>
</Alert>
<p>我们很高兴宣布 <strong>Oxfmt</strong> 的 Alpha 版本发布，这是一个基于 Rust 构建的、兼容 Prettier 的代码格式化器。首个版本专注于 JavaScript 和 TypeScript，对其他语言的支持即将推出。</p>
<p>Oxfmt 的设计旨在实现以下目标：</p>
<ul>
<li><strong>性能：</strong> 初次运行无缓存情况下，比 Prettier 快 30 倍以上，比 Biome 快 3 倍以上（<a href="https://github.com/oxc-project/bench-formatter" target="_blank" rel="noreferrer"><strong>基准测试</strong></a>）。</li>
<li><strong>兼容性：</strong> 兼容 Prettier，因此您可以轻松在现有项目中采用 Oxfmt。</li>
<li><strong>开发者体验：</strong> 即将推出的功能包括导入排序、扩展格式化选项以及对 Prettier 插件的支持。</li>
</ul>
<h2 id="快速开始" tabindex="-1"><strong>快速开始</strong> <a class="header-anchor" href="#快速开始" aria-label="Permalink to “快速开始”">&#8203;</a></h2>
<p>将 <code>oxfmt</code> 添加到您的项目：</p>
<table><tbody><tr><td>npm</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">npm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> add</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -D</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxfmt@latest</span></span></code></pre>
</div></td></tr><tr><td>pnpm</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">pnpm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> add</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -D</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxfmt@latest</span></span></code></pre>
</div></td></tr><tr><td>yarn</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">yarn</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> add</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -D</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxfmt@latest</span></span></code></pre>
</div></td></tr><tr><td>bun</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">bun</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> add</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -D</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxfmt@latest</span></span></code></pre>
</div></td></tr><tr><td>deno</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">deno</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> add</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -D</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> npm:oxfmt@latest</span></span></code></pre>
</div></td></tr></tbody></table>
<p>Oxfmt 遵循 Prettier 的配置格式。如果您使用 JSON 配置文件运行 Prettier，可以将其重命名为 <code>.oxfmtrc.jsonc</code>：</p>
<div class="language-bash"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">cp</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> .prettierrc.json</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> .oxfmtrc.jsonc</span></span></code></pre>
</div><p>您也可以从这个 <code>.oxfmtrc.jsonc</code> 配置示例开始：</p>
<div class="language-jsx"><button title="Copy Code" class="copy"></button><span class="lang">jsx</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">{</span></span>
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">  "$schema"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"./node_modules/oxfmt/configuration_schema.json"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">  // 如果从 Prettier 迁移请使用 80；100 是 Oxfmt 的默认值！</span></span>
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">  "printWidth"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">80</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">  "ignorePatterns"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: [] </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">// 与 `.prettierignore` 相同</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span></code></pre>
</div><p>接下来，将 <code>oxfmt</code> 添加到您的 package.json scripts 中：</p>
<div class="language-jsx"><button title="Copy Code" class="copy"></button><span class="lang">jsx</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"scripts"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: {</span></span>
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">  "format"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"oxfmt"</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span></code></pre>
</div><p>或者，参阅 <a href="/docs/guide/usage/formatter.html">安装指南</a> 获取详细说明。</p>
<h2 id="性能" tabindex="-1">性能 <a class="header-anchor" href="#性能" aria-label="Permalink to “性能”">&#8203;</a></h2>
<p>Oxfmt 速度极快。我们在 <a href="https://github.com/outline/outline" target="_blank" rel="noreferrer">Outline</a> 仓库上的基准测试结果显示：</p>
<ul>
<li>比无缓存的 Prettier 实验性 CLI 快 30 倍以上</li>
<li>比通过 <code>@prettier/plugin-oxc</code> 使用 Oxc 解析器的 Prettier 快 20 倍以上</li>
<li>比另一个基于 Rust 的格式化器 Biome 快 3 倍以上</li>
</ul>
<p>有关详细的基准测试设置，请参阅以下仓库：</p>
<blockquote>
<p>oxc-project/bench-formatter<br>
<a href="https://github.com/oxc-project/bench-formatter" target="_blank" rel="noreferrer">https://github.com/oxc-project/bench-formatter</a></p>
</blockquote>
<h2 id="设计" tabindex="-1">设计 <a class="header-anchor" href="#设计" aria-label="Permalink to “设计”">&#8203;</a></h2>
<p>Oxc 团队优先考虑与现有生态系统的兼容性，使得迁移变得简单直接，即使是大型代码库。</p>
<h3 id="代码格式化结果" tabindex="-1">代码格式化结果 <a class="header-anchor" href="#代码格式化结果" aria-label="Permalink to “代码格式化结果”">&#8203;</a></h3>
<p>Oxfmt 与 Prettier 的 JavaScript 格式化结果一致。如果您今天迁移到 Oxfmt，与 Prettier 相比应该不会看到任何格式化差异。</p>
<p>从较旧版本的 Prettier 迁移时，您可能会看到细微差异（<a href="https://github.com/SBoudrias/Inquirer.js/pull/1912" target="_blank" rel="noreferrer">参见迁移示例</a>），因为我们发现了 Prettier 格式化可以改进的地方。我们一直积极与 Prettier 团队合作，直接向 Prettier 提交错误报告和拉取请求。其中许多改进已纳入最近的 <a href="https://prettier.io/blog/2025/11/27/3.7.0" target="_blank" rel="noreferrer">Prettier 3.7</a> 版本中。</p>
<p>Oxfmt 目前通过了大约 <a href="https://github.com/oxc-project/oxc/tree/main/tasks/prettier_conformance/snapshots" target="_blank" rel="noreferrer">95%</a> 的 Prettier JavaScript 和 TypeScript 测试，我们希望随着时间的推移与 Prettier 团队共同努力，使格式化结果趋于一致。</p>
<h3 id="默认-printwidth-100" tabindex="-1">默认 <code>printWidth: 100</code> <a class="header-anchor" href="#默认-printwidth-100" aria-label="Permalink to “默认 printWidth: 100”">&#8203;</a></h3>
<p>我们选择 <code>printWidth: 100</code> 作为默认行长度，而不是 Prettier 的 <code>80</code>。我们的原因包括：</p>
<ul>
<li>TypeScript 代码由于类型注释往往比 JavaScript 更长。</li>
<li>导入语句通常包含许多项。</li>
<li>更大的屏幕提供更多的水平空间。</li>
<li>产生的 LLM tokens 略少。</li>
</ul>
<p>虽然 Oxfmt 保持与 Prettier 兼容，但它使用不同的默认打印宽度 100 个字符。如果您想在从 Prettier 迁移时避免大的差异，请显式将打印宽度设置为 80。</p>
<h3 id="ignorepatterns" tabindex="-1"><code>ignorePatterns</code> <a class="header-anchor" href="#ignorepatterns" aria-label="Permalink to “ignorePatterns”">&#8203;</a></h3>
<p>虽然 Oxfmt 支持 <code>.prettierignore</code>，但它也支持 <code>ignorePatterns</code> 配置选项，以便将所有配置合并到一个文件中。</p>
<h3 id="配置" tabindex="-1">配置 <a class="header-anchor" href="#配置" aria-label="Permalink to “配置”">&#8203;</a></h3>
<p>Prettier JSON 配置文件与 Oxfmt 兼容。在最简单的情况下，迁移配置如下所示：</p>
<div class="language-bash"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">cp</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> .prettierrc.json</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> .oxfmtrc.jsonc</span></span></code></pre>
</div><p>如果您的编辑器支持 JSON 语言服务器，您可以在将 <code>oxfmt</code> 添加到 <code>devDependencies</code> 后使用此最小模板：</p>
<div class="language-json"><button title="Copy Code" class="copy"></button><span class="lang">json</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">{</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">  "$schema"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"./node_modules/oxfmt/configuration_schema.json"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">  "ignorePatterns"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: []</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span></code></pre>
</div><p>虽然在此 Alpha 版本中我们尚未支持 Prettier 的所有配置选项，但我们支持以下主要选项：<code>printWidth</code>、<code>tabWidth</code>、<code>useTabs</code>、<code>semi</code>、<code>singleQuote</code>、<code>quoteProps</code>、<code>jsxSingleQuote</code>、<code>trailingComma</code>、<code>bracketSpacing</code>、<code>objectWrap</code>、<code>bracketSameLine</code>、<code>arrowParens</code>、<code>endOfLine</code> 和 <code>singleAttributePerLine</code>。</p>
<p>在我们的 <a href="https://oxc.rs/docs/guide/usage/formatter.html#configuration-file" target="_blank" rel="noreferrer">文档</a> 中查看所有选项。</p>
<h3 id="终端输出" tabindex="-1">终端输出 <a class="header-anchor" href="#终端输出" aria-label="Permalink to “终端输出”">&#8203;</a></h3>
<p>Oxfmt 的默认行为等同于 <code>prettier . --write</code>，提供与 <code>cargo fmt</code> 相同的用户体验且不产生输出。您可以使用 <code>--check</code> 来显示格式化差异并在 CI 流程中强制使用 oxfmt。</p>
<h2 id="beta-版本发布计划" tabindex="-1">Beta 版本发布计划 <a class="header-anchor" href="#beta-版本发布计划" aria-label="Permalink to “Beta 版本发布计划”">&#8203;</a></h2>
<p>以下是我们对 Beta 版本的计划：</p>
<ul>
<li><a href="https://github.com/oxc-project/oxc/issues/15899" target="_blank" rel="noreferrer">支持更多文件格式</a> - 如 <code>.json</code> 文件</li>
<li><a href="https://github.com/oxc-project/oxc/issues/15180" target="_blank" rel="noreferrer">添加对嵌入式语言格式化的支持</a> - js 中的 css 或 js 中的 graphql</li>
<li><a href="https://github.com/oxc-project/oxc/issues/13610" target="_blank" rel="noreferrer">内置排序和美学功能</a>，例如 <a href="https://github.com/oxc-project/oxc/issues/14253" target="_blank" rel="noreferrer">导入排序</a></li>
<li><a href="https://github.com/oxc-project/oxc/issues/15665" target="_blank" rel="noreferrer">Prettier 插件</a></li>
<li><a href="https://github.com/oxc-project/oxc/issues/15913" target="_blank" rel="noreferrer">Oxfmt 的 Node.js API</a></li>
<li><a href="https://github.com/oxc-project/oxc/issues/15066" target="_blank" rel="noreferrer">禁用文件末尾的换行符</a></li>
<li><a href="https://github.com/oxc-project/oxc/issues/15849" target="_blank" rel="noreferrer"><code>--migrate prettier</code></a></li>
<li><em>… 以及您的功能请求</em></li>
</ul>
<p>您可以在此处跟踪我们迈向 Beta 版本的进度：</p>
<blockquote>
<p>Formatter Beta · Milestone #15 · oxc-project/oxc<br>
<a href="https://github.com/oxc-project/oxc/milestone/15" target="_blank" rel="noreferrer">https://github.com/oxc-project/oxc/milestone/15</a></p>
</blockquote>
<p>我们还计划在未来版本中放宽一些格式化意见。</p>
<h2 id="下一步" tabindex="-1">下一步 <a class="header-anchor" href="#下一步" aria-label="Permalink to “下一步”">&#8203;</a></h2>
<p>请在 <a href="https://oxc.rs/docs/guide/usage/formatter.html" target="_blank" rel="noreferrer">Oxfmt 文档</a> 中查看完整的安装指南。</p>
<h3 id="报告问题" tabindex="-1">报告问题 <a class="header-anchor" href="#报告问题" aria-label="Permalink to “报告问题”">&#8203;</a></h3>
<p>对于格式化差异，请参阅 <a href="https://github.com/oxc-project/oxc/discussions/14669" target="_blank" rel="noreferrer">https://github.com/oxc-project/oxc/discussions/14669</a>。
此外，已知问题通过 <a href="https://github.com/oxc-project/oxc/issues?q=sort%3Aupdated-desc%20is%3Aissue%20label%3AA-formatter-prettier-diff" target="_blank" rel="noreferrer">标签</a> 区分。</p>
<p>如果您发现任何其他问题，请在 GitHub 上使用 <a href="https://github.com/oxc-project/oxc/issues/new?template=formatter_diff_report.yaml" target="_blank" rel="noreferrer">专用模板</a> 创建问题。</p>
<h3 id="加入社区" tabindex="-1">加入社区 <a class="header-anchor" href="#加入社区" aria-label="Permalink to “加入社区”">&#8203;</a></h3>
<blockquote>
<p>RFC: Formatter · oxc-project/oxc · Discussion #13608<br>
<a href="https://github.com/oxc-project/oxc/discussions/13608" target="_blank" rel="noreferrer">https://github.com/oxc-project/oxc/discussions/13608</a></p>
</blockquote>
<p>我们欢迎您的反馈，帮助使 Oxfmt 变得更好！</p>
<h2 id="致谢" tabindex="-1">致谢 <a class="header-anchor" href="#致谢" aria-label="Permalink to “致谢”">&#8203;</a></h2>
<p>Oxfmt 基于 <a href="https://github.com/biomejs/biome/tree/main/crates/biome_formatter" target="_blank" rel="noreferrer"><code>biome_formatter</code></a> 基础设施的 fork 构建，我们要感谢 Biome 团队，尤其是 <a href="https://github.com/ematipico" target="_blank" rel="noreferrer">@ematipico</a> 和 <a href="https://github.com/MichaReiser" target="_blank" rel="noreferrer">@MichaReiser</a>。我们还要感谢 Prettier 团队和 <a href="https://github.com/fisker" target="_blank" rel="noreferrer">@fisker</a> 在格式化兼容性方面与我们合作。</p>
]]></content>
        <author>
            <name>Boshen</name>
            <uri>https://github.com/Boshen</uri>
        </author>
        <author>
            <name>Dunqing</name>
            <uri>https://github.com/dunqing</uri>
        </author>
        <author>
            <name>Yuji Sugiura</name>
            <uri>https://github.com/leaysgur</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[类型感知 Linting Alpha]]></title>
        <id>https://oxc.rs/blog/2025-12-08-type-aware-alpha</id>
        <link href="https://oxc.rs/blog/2025-12-08-type-aware-alpha"/>
        <updated>2025-12-08T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[<AppBlogPostHeader /><br>
<p>我们很高兴地宣布 Oxlint 中类型感知 linting 的 Alpha 版本发布！</p>
<h2 id="概述" tabindex="-1">概述 <a class="header-anchor" href="#概述" aria-label="Permalink to “概述”">&#8203;</a></h2>
<p>继我们 <a href="/blog/2025-08-17-oxlint-type-aware.html">8 月的技术预览</a> 之后，我们很高兴地宣布类型感知 linting 已达到 Alpha 状态。这一里程碑带来了稳定性、可配置性和规则覆盖范围的显著改进。</p>
<p>类型感知 linting 支持强大的规则，如 <code>no-floating-promises</code>、<code>no-misused-promises</code> 和 <code>await-thenable</code>，它们利用 TypeScript 的类型系统来捕捉 bug。现在已有 43 条类型感知规则可用，您可以在运行时错误发生之前捕捉到整个类别的错误。</p>
<p><strong>本文内容：</strong></p>
<ul>
<li><a href="#quick-start">快速开始</a> - 几分钟内开始使用类型感知 linting</li>
<li><a href="#performance">性能</a> - 查看类型感知 linting 比 ESLint 快多少</li>
<li><a href="#what-s-new-since-the-technical-preview">技术预览以来有哪些新功能</a> - 新功能和改进</li>
<li><a href="#technical-details">技术细节</a> - 类型感知 linting 如何在底层工作</li>
<li><a href="#what-s-next">下一步计划</a> - Beta 版本的即将改进</li>
</ul>
<h2 id="快速开始" tabindex="-1">快速开始 <a class="header-anchor" href="#快速开始" aria-label="Permalink to “快速开始”">&#8203;</a></h2>
<p>安装 <code>oxlint</code> 和 <code>oxlint-tsgolint</code>，然后使用 <code>--type-aware</code> 标志运行：</p>
<table><tbody><tr><td>npm</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">npm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> add</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -D</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint-tsgolint@latest</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">npx</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> --type-aware</span></span></code></pre>
</div></td></tr><tr><td>pnpm</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">pnpm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> add</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -D</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint-tsgolint@latest</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">pnpm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> --type-aware</span></span></code></pre>
</div></td></tr><tr><td>yarn</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">yarn</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> add</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -D</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint-tsgolint@latest</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">yarn</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> --type-aware</span></span></code></pre>
</div></td></tr><tr><td>bun</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">bun</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> add</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -D</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint-tsgolint@latest</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">bunx</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> --type-aware</span></span></code></pre>
</div></td></tr></tbody></table>
<p>要尝试特定的类型感知规则而不使用其他配置（<code>oxlint-tsgolint</code> 必须已经全局或本地安装）：</p>
<table><tbody><tr><td>npm</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">npx</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> --type-aware</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -A</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> all</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -D</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> typescript/no-floating-promises</span></span></code></pre>
</div></td></tr><tr><td>pnpm</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">pnpx</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> --type-aware</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -A</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> all</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -D</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> typescript/no-floating-promises</span></span></code></pre>
</div></td></tr><tr><td>yarn</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">yarn</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> --type-aware</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -A</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> all</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -D</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> typescript/no-floating-promises</span></span></code></pre>
</div></td></tr><tr><td>bun</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">bunx</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> --type-aware</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -A</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> all</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -D</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> typescript/no-floating-promises</span></span></code></pre>
</div></td></tr></tbody></table>
<p>有关更多配置选项，请参阅我们的 <a href="/docs/guide/usage/linter/type-aware.html">使用指南</a>。</p>
<h2 id="性能" tabindex="-1">性能 <a class="header-anchor" href="#性能" aria-label="Permalink to “性能”">&#8203;</a></h2>
<p>| 项目            | Oxlint + 类型感知 | ESLint + typescript-eslint | 提升   |
|</p>
]]></summary>
        <content type="html"><![CDATA[<AppBlogPostHeader /><br>
<p>我们很高兴地宣布 Oxlint 中类型感知 linting 的 Alpha 版本发布！</p>
<h2 id="概述" tabindex="-1">概述 <a class="header-anchor" href="#概述" aria-label="Permalink to “概述”">&#8203;</a></h2>
<p>继我们 <a href="/blog/2025-08-17-oxlint-type-aware.html">8 月的技术预览</a> 之后，我们很高兴地宣布类型感知 linting 已达到 Alpha 状态。这一里程碑带来了稳定性、可配置性和规则覆盖范围的显著改进。</p>
<p>类型感知 linting 支持强大的规则，如 <code>no-floating-promises</code>、<code>no-misused-promises</code> 和 <code>await-thenable</code>，它们利用 TypeScript 的类型系统来捕捉 bug。现在已有 43 条类型感知规则可用，您可以在运行时错误发生之前捕捉到整个类别的错误。</p>
<p><strong>本文内容：</strong></p>
<ul>
<li><a href="#quick-start">快速开始</a> - 几分钟内开始使用类型感知 linting</li>
<li><a href="#performance">性能</a> - 查看类型感知 linting 比 ESLint 快多少</li>
<li><a href="#what-s-new-since-the-technical-preview">技术预览以来有哪些新功能</a> - 新功能和改进</li>
<li><a href="#technical-details">技术细节</a> - 类型感知 linting 如何在底层工作</li>
<li><a href="#what-s-next">下一步计划</a> - Beta 版本的即将改进</li>
</ul>
<h2 id="快速开始" tabindex="-1">快速开始 <a class="header-anchor" href="#快速开始" aria-label="Permalink to “快速开始”">&#8203;</a></h2>
<p>安装 <code>oxlint</code> 和 <code>oxlint-tsgolint</code>，然后使用 <code>--type-aware</code> 标志运行：</p>
<table><tbody><tr><td>npm</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">npm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> add</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -D</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint-tsgolint@latest</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">npx</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> --type-aware</span></span></code></pre>
</div></td></tr><tr><td>pnpm</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">pnpm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> add</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -D</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint-tsgolint@latest</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">pnpm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> --type-aware</span></span></code></pre>
</div></td></tr><tr><td>yarn</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">yarn</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> add</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -D</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint-tsgolint@latest</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">yarn</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> --type-aware</span></span></code></pre>
</div></td></tr><tr><td>bun</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">bun</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> add</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -D</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint-tsgolint@latest</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">bunx</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> --type-aware</span></span></code></pre>
</div></td></tr></tbody></table>
<p>要尝试特定的类型感知规则而不使用其他配置（<code>oxlint-tsgolint</code> 必须已经全局或本地安装）：</p>
<table><tbody><tr><td>npm</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">npx</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> --type-aware</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -A</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> all</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -D</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> typescript/no-floating-promises</span></span></code></pre>
</div></td></tr><tr><td>pnpm</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">pnpx</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> --type-aware</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -A</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> all</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -D</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> typescript/no-floating-promises</span></span></code></pre>
</div></td></tr><tr><td>yarn</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">yarn</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> --type-aware</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -A</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> all</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -D</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> typescript/no-floating-promises</span></span></code></pre>
</div></td></tr><tr><td>bun</td><td><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">bunx</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> --type-aware</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -A</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> all</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -D</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> typescript/no-floating-promises</span></span></code></pre>
</div></td></tr></tbody></table>
<p>有关更多配置选项，请参阅我们的 <a href="/docs/guide/usage/linter/type-aware.html">使用指南</a>。</p>
<h2 id="性能" tabindex="-1">性能 <a class="header-anchor" href="#性能" aria-label="Permalink to “性能”">&#8203;</a></h2>
<table tabindex="0">
<thead>
<tr>
<th>项目</th>
<th>Oxlint + 类型感知</th>
<th>ESLint + typescript-eslint</th>
<th>提升</th>
</tr>
</thead>
<tbody>
<tr>
<td>vuejs/core</td>
<td>2.531 s</td>
<td>20.800 s</td>
<td>8.22x</td>
</tr>
<tr>
<td>outline/outline</td>
<td>4.448 s</td>
<td>55.070 s</td>
<td>12.38x</td>
</tr>
</tbody>
</table>
<p>基准测试是在 MacBook Pro M2 Max 12 核心（8 个性能核心和 4 个能效核心）上进行的。</p>
<p>我们的性能测试显示，带有类型感知 linting 的 <code>oxlint</code> 比带有 <code>typescript-eslint</code> 的 <code>eslint</code> 快大约 10 倍。查看我们的 <a href="https://github.com/oxc-project/bench-linter" target="_blank" rel="noreferrer">性能基准测试</a> 了解更多详情。</p>
<p>Oxlint 还可以在 lint 的同时用于类型检查您的代码库。这避免了重复工作，因为许多类型信息已经在类型感知 linting 期间计算好了。</p>
<div  class="warning custom-block"><p class="custom-block-title">已知问题</p>
<p>虽然 <code>tsgolint</code> 已准备好在生产代码库中进行测试，但在处理非常大的代码库时，您可能会遇到内存不足的问题。我们正在努力优化下一个里程碑的内存使用。如果您尝试 <code>tsgolint</code> 并在 <a href="https://github.com/oxc-project/tsgolint" target="_blank" rel="noreferrer"><code>tsgolint</code> 仓库</a> 中向我们报告任何内存不足问题，并提供一些关于您项目的详细信息以帮助我们改进内存使用，我们将不胜感激。</p>
</div>
<h2 id="技术预览以来有哪些新功能" tabindex="-1">技术预览以来有哪些新功能？ <a class="header-anchor" href="#技术预览以来有哪些新功能" aria-label="Permalink to “技术预览以来有哪些新功能？”">&#8203;</a></h2>
<h3 id="支持在-lint-过程中进行类型检查" tabindex="-1">支持在 lint 过程中进行类型检查 <a class="header-anchor" href="#支持在-lint-过程中进行类型检查" aria-label="Permalink to “支持在 lint 过程中进行类型检查”">&#8203;</a></h3>
<p><code>tsgolint</code> 现在支持在 lint 时发出 TypeScript 的类型检查错误。由于类型感知规则已经需要检查文件中的所有类型，我们能够使用这些现有的类型信息而不是丢弃它们。这意味着在某些情况下，可以完全跳过单独的类型检查命令（例如 <code>tsc --noEmit</code>），减少在 CI 中花费在 linting 和类型检查上的总时间。</p>
<p>这是一个实验性功能，但您可以通过向 <code>oxlint</code> 命令添加 <code>--type-check</code> 和 <code>--type-aware</code> 标志来启用它：</p>
<div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span>$ oxlint --type-aware --type-check</span></span>
<span class="line"><span></span></span>
<span class="line"><span>  × typescript(TS2322): Type 'number' is not assignable to type 'string'.</span></span>
<span class="line"><span>   ╭─[index.ts:1:7]</span></span>
<span class="line"><span> 1 │ const message: string = 1</span></span>
<span class="line"><span>   ·       ───────</span></span>
<span class="line"><span>   ╰────</span></span></code></pre>
</div><h3 id="支持在-oxlint-中配置规则" tabindex="-1">支持在 <code>oxlint</code> 中配置规则 <a class="header-anchor" href="#支持在-oxlint-中配置规则" aria-label="Permalink to “支持在 oxlint 中配置规则”">&#8203;</a></h3>
<p>在 <code>tsgolint</code> 中运行的类型感知规则可以像任何其他 lint 规则一样在 <code>oxlint</code> 中配置。例如，您可以配置 <code>no-floating-promises</code> 规则以允许某些安全调用或忽略 <code>void</code>：</p>
<div class="language-json"><button title="Copy Code" class="copy"></button><span class="lang">json</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">{</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">  "rules"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: {</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "typescript/no-floating-promises"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: [</span></span>
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">      "error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">      {</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">        "ignoreVoid"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">        "allowForKnownSafePromises"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: [</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">          { </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">"from"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"file"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">"name"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"SafePromise"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">          { </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">"from"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"lib"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">"name"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"PromiseLike"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">        ]</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">      }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    ]</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span></code></pre>
</div><p>配置选项与 <code>typescript-eslint</code> 支持的选项保持一致，文档可以在每个规则的配置部分找到（例如 <a href="https://oxc.rs/docs/guide/usage/linter/rules/typescript/no-floating-promises.html#configuration" target="_blank" rel="noreferrer"><code>no-floating-promises</code></a>）。</p>
<h3 id="支持行内禁用注释" tabindex="-1">支持行内禁用注释 <a class="header-anchor" href="#支持行内禁用注释" aria-label="Permalink to “支持行内禁用注释”">&#8203;</a></h3>
<p>在 <code>tsgolint</code> 中运行的规则现在可以通过在文件中或行上放置注释来禁用，类似于任何其他 <code>oxlint</code> 规则：</p>
<div class="language-ts"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">/* oxlint-disable typescript/no-floating-promises */</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">// oxlint-disable-next-line typescript/no-floating-promises</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">[</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">2</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">3</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">].</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">map</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">async</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> (</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">x</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> x </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">+</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> 1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">);</span></span></code></pre>
</div><h3 id="支持更多规则" tabindex="-1">支持更多规则 <a class="header-anchor" href="#支持更多规则" aria-label="Permalink to “支持更多规则”">&#8203;</a></h3>
<p>我们继续致力于从 <code>typescript-eslint</code> 移植流行规则，您现在可以通过 <code>oxlint</code> 使用它们。<code>tsgolint</code> 与 <code>oxlint</code> 结合，目前支持 43 条类型感知规则。</p>
<p>自初始预览以来，还添加了对以下规则的支持：</p>
<ul>
<li><a href="/docs/guide/usage/linter/rules/typescript/no-deprecated.html"><code>no-deprecated</code></a>（最常请求的规则之一）</li>
<li><a href="/docs/guide/usage/linter/rules/typescript/prefer-includes.html"><code>prefer-includes</code></a></li>
<li><a href="/docs/guide/usage/linter/rules/typescript/strict-boolean-expressions.html"><code>strict-boolean-expressions</code></a></li>
</ul>
<h3 id="现在会报告-typescript-程序诊断信息" tabindex="-1">现在会报告 TypeScript 程序诊断信息 <a class="header-anchor" href="#现在会报告-typescript-程序诊断信息" aria-label="Permalink to “现在会报告 TypeScript 程序诊断信息”">&#8203;</a></h3>
<p>以前，如果 TypeScript 无法创建和解析程序，这些错误不会被报告，导致人们对为什么 linting 不起作用感到困惑。现在，我们将报告创建程序时的任何问题作为诊断信息，包括 <code>tsconfig.json</code> 文件中的配置问题。</p>
<p>例如，如果 <code>tsconfig.json</code> 文件包含 <code>baseUrl</code>，这将报告为错误，因为 <code>baseUrl</code> 已在 TypeScript v7.0 中移除：</p>
<div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span>$ oxlint --type-aware</span></span>
<span class="line"><span></span></span>
<span class="line"><span>  × typescript(tsconfig-error): Invalid tsconfig</span></span>
<span class="line"><span>   ╭─[tsconfig.json:4:3]</span></span>
<span class="line"><span> 3 │     "compilerOptions": {</span></span>
<span class="line"><span> 4 │         "baseUrl": ".",</span></span>
<span class="line"><span>   ·         ─────────</span></span>
<span class="line"><span> 5 │         "experimentalDecorators": true,</span></span>
<span class="line"><span>   ╰────</span></span>
<span class="line"><span>  help: Option 'baseUrl' has been removed. Please remove it from your configuration.</span></span>
<span class="line"><span>        See https://github.com/oxc-project/tsgolint/issues/351 for more information.</span></span></code></pre>
</div><h3 id="类型感知规则的自动修复" tabindex="-1">类型感知规则的自动修复 <a class="header-anchor" href="#类型感知规则的自动修复" aria-label="Permalink to “类型感知规则的自动修复”">&#8203;</a></h3>
<p>类型感知规则现在支持通过 <code>--fix</code> 标志进行自动修复。当您运行 <code>oxlint --type-aware --fix</code> 时，来自 <code>tsgolint</code> 的可修复诊断信息将像常规 <code>oxlint</code> 修复一样应用。这使修复工作流程与非类型感知规则完全一致。</p>
<h2 id="技术细节" tabindex="-1">技术细节 <a class="header-anchor" href="#技术细节" aria-label="Permalink to “技术细节”">&#8203;</a></h2>
<h3 id="架构" tabindex="-1">架构 <a class="header-anchor" href="#架构" aria-label="Permalink to “架构”">&#8203;</a></h3>
<p>Oxlint 中的类型感知 linting 使用独特的双二进制架构：</p>
<div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span>oxlint CLI (Rust)</span></span>
<span class="line"><span>  ├─ Handles file traversal, ignore logic, and diagnostics</span></span>
<span class="line"><span>  ├─ Runs non-type-aware rules and custom JS plugins</span></span>
<span class="line"><span>  ├─ Passes paths and configuration to tsgolint</span></span>
<span class="line"><span>  └─ Formats and displays results</span></span>
<span class="line"><span></span></span>
<span class="line"><span>tsgolint (Go)</span></span>
<span class="line"><span>  ├─ Uses typescript-go directly for type checking</span></span>
<span class="line"><span>  ├─ Executes type-aware rules</span></span>
<span class="line"><span>  └─ Returns structured diagnostics</span></span></code></pre>
</div><p>这种设计在通过 typescript-go 利用 TypeScript 类型系统的同时，保持了 Oxlint 核心的快速。前端 - 后端分离意味着 <code>oxlint</code> 控制用户体验，而 <code>tsgolint</code> 处理类型分析的繁重工作。</p>
<h3 id="typescript-兼容性" tabindex="-1">TypeScript 兼容性 <a class="header-anchor" href="#typescript-兼容性" aria-label="Permalink to “TypeScript 兼容性”">&#8203;</a></h3>
<p><code>tsgolint</code> 基于 <a href="https://github.com/microsoft/typescript-go" target="_blank" rel="noreferrer">typescript-go</a>，这是微软基于 Go 的重写版本，将成为 TypeScript v7.0。有关 TypeScript 7 进度的更多详情，请参阅 <a href="https://devblogs.microsoft.com/typescript/progress-on-typescript-7-december-2025/" target="_blank" rel="noreferrer">官方 TypeScript 博客文章</a>。这意味着您可能会遇到一些不再支持的功能。</p>
<p><strong>重要的兼容性说明：</strong></p>
<ul>
<li>仅支持 TypeScript 7.0+ 功能</li>
<li>不支持 7.0 之前的语法和已弃用的功能</li>
<li>遗留的 <code>tsconfig.json</code> 选项（如 <code>baseUrl</code>）已在 TypeScript 7.0 中移除</li>
</ul>
<p>如果您正在使用 TypeScript 6.0 或更早版本的已弃用功能，您需要先迁移代码库。请参阅 <a href="https://github.com/microsoft/TypeScript/issues/62508#issuecomment-3348649259" target="_blank" rel="noreferrer">TypeScript 迁移指南</a> 以帮助更新已弃用的 tsconfig 选项。</p>
<h3 id="实现细节" tabindex="-1">实现细节 <a class="header-anchor" href="#实现细节" aria-label="Permalink to “实现细节”">&#8203;</a></h3>
<p><code>tsgolint</code> 不使用 typescript-go 的公共 API。相反，它通过 <a href="https://github.com/oxc-project/tsgolint/tree/main/shim" target="_blank" rel="noreferrer">shimming</a> 内部 API 来编译 typescript-go，使它们可访问。我们积极跟踪 typescript-go 更新并根据需要修复破坏性变更。</p>
<p>我们的 typescript-go 分支使用 renovatebot 定期同步，确保我们保持最新的改进和修复。一旦 TypeScript 7.0 正式发布，我们将跟踪稳定版本而不是主分支的顶端。</p>
<h2 id="下一步计划" tabindex="-1">下一步计划 <a class="header-anchor" href="#下一步计划" aria-label="Permalink to “下一步计划”">&#8203;</a></h2>
<p>我们正在积极致力于以下改进以发布 Beta 版本：</p>
<ul>
<li><strong>支持更多规则</strong> - 目前我们支持 <code>typescript-eslint</code> 中 59 条类型感知规则中的 43 条。随着我们走向 Beta 发布，我们计划继续扩大规则覆盖范围。</li>
<li><strong>性能和内存使用改进</strong> - 我们将继续优化性能，特别是对于非常大的 monorepos。</li>
</ul>
<h2 id="致谢" tabindex="-1">致谢 <a class="header-anchor" href="#致谢" aria-label="Permalink to “致谢”">&#8203;</a></h2>
<p>我们想向以下各方表示感谢：</p>
<ul>
<li>TypeScript 团队创建了 <code>typescript-go</code>。</li>
<li><code>typescript-eslint</code> 团队给予的暖心支持。</li>
<li><a href="https://github.com/auvred" target="_blank" rel="noreferrer">@auvred</a> 创建了 <code>tsgolint</code>。</li>
<li><a href="https://github.com/camchenry" target="_blank" rel="noreferrer">@camchenry</a> 持续进行的性能优化工作，以及实现了规则选项支持。</li>
</ul>
<h2 id="试一试" tabindex="-1">试一试 <a class="header-anchor" href="#试一试" aria-label="Permalink to “试一试”">&#8203;</a></h2>
<p>准备好开始了吗？前往上方的 <a href="#quick-start">快速开始</a> 部分安装并运行类型感知 linting。</p>
<p>我们很希望听到您对类型感知 linting 的反馈，也很兴奋看到它如何帮助改善您的开发工作流。</p>
<p>联系我们：</p>
<ul>
<li><strong>Discord</strong>：加入我们的 <a href="https://discord.gg/9uXCAwqQZW" target="_blank" rel="noreferrer">社区服务器</a> 进行实时讨论</li>
<li><strong>GitHub</strong>：在 <a href="https://github.com/oxc-project/oxc/discussions" target="_blank" rel="noreferrer">GitHub 讨论区</a> 分享反馈</li>
<li><strong>问题</strong>：将 <code>oxlint</code> 的 bug 报告给 <a href="https://github.com/oxc-project/oxc/issues" target="_blank" rel="noreferrer">oxc</a>，将类型感知 linting 的 bug 报告给 <a href="https://github.com/oxc-project/tsgolint/issues" target="_blank" rel="noreferrer">tsgolint</a>。</li>
</ul>
]]></content>
        <author>
            <name>Cameron</name>
            <uri>https://github.com/camc314</uri>
        </author>
        <author>
            <name>Cam</name>
            <uri>https://github.com/camchenry</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Oxfmt Beta 版]]></title>
        <id>https://oxc.rs/blog/2026-02-24-oxfmt-beta</id>
        <link href="https://oxc.rs/blog/2026-02-24-oxfmt-beta"/>
        <updated>2026-02-24T00:00:00.000Z</updated>
        <content type="html"><![CDATA[<AppBlogPostHeader /><p>我们很高兴地宣布 Oxfmt 已进入 Beta 阶段。</p>
<p>Oxfmt 是一个基于 Rust 驱动、与 Prettier 兼容的代码格式化程序，专为 JavaScript 生态系统构建。它旨在与现代工具链完全兼容，同时显著提升性能。</p>
<p>在基准测试中，在无缓存的首次运行中，Oxfmt 的速度比 Prettier 快 30 倍以上，比 Biome 快 3 倍。查看完整的 <a href="https://github.com/oxc-project/bench-formatter" target="_blank" rel="noreferrer">基准测试</a> 结果。</p>
<p>自 12 月的 Alpha 版本发布以来，我们扩展了对更多文件格式的支持，添加了嵌入式语言格式化，引入了导入排序，集成了 Tailwind CSS 支持，并带来了许多稳定性和兼容性改进。</p>
<p>Oxfmt 已经在生态系统中得到了广泛采用。使用 Oxfmt 的项目包括：<a href="https://github.com/openclaw/openclaw" target="_blank" rel="noreferrer">openclaw/openclaw</a>、<a href="https://github.com/vuejs/core" target="_blank" rel="noreferrer">vuejs/core</a>、<a href="https://github.com/vercel/turborepo" target="_blank" rel="noreferrer">vercel/turborepo</a>、<a href="https://github.com/huggingface/huggingface.js" target="_blank" rel="noreferrer">huggingface/huggingface.js</a>、<a href="https://github.com/getsentry/sentry-javascript" target="_blank" rel="noreferrer">getsentry/sentry-javascript</a>、<a href="https://github.com/npmx-dev/npmx.dev" target="_blank" rel="noreferrer">npmx-dev/npmx.dev</a> 以及更多。</p>
<h2 id="快速开始" tabindex="-1">快速开始 <a class="header-anchor" href="#快速开始" aria-label="Permalink to “快速开始”">&#8203;</a></h2>
<p>将 <code>oxfmt</code> 安装为开发依赖：</p>
<div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">pnpm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> add</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -D</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxfmt</span></span></code></pre>
</div><p>将脚本添加到 <code>package.json</code>：</p>
<tr><td>package.json</td><td><div class="vp-code-block-title">
      <div class="vp-code-block-title-bar">
          <span class="vp-code-block-title-text" data-title="package.json">package.json</span>
      </div>
        <div class="language-json"><button title="Copy Code" class="copy"></button><span class="lang">json</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">{</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">  "scripts"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: {</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "fmt"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"oxfmt"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "fmt:check"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"oxfmt --check"</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span></code></pre>
</div>
      </div>
      </td></tr><p>格式化文件：</p>
<div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">pnpm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> run</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> fmt</span></span></code></pre>
</div><p>检查格式化而不写入文件：</p>
<div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">pnpm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> run</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> fmt:check</span></span></code></pre>
</div><h3 id="从-prettier-迁移" tabindex="-1">从 Prettier 迁移 <a class="header-anchor" href="#从-prettier-迁移" aria-label="Permalink to “从 Prettier 迁移”">&#8203;</a></h3>
<p>安装、迁移配置并重新格式化，只需一条命令：</p>
<div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">pnpm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> add</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -D</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxfmt</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> &#x26;&#x26; </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">pnpm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxfmt</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> --migrate</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> prettier</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> &#x26;&#x26; </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">pnpm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxfmt</span></span></code></pre>
</div><p>完整迁移指南，请参阅 <a href="/docs/guide/usage/formatter/migrate-from-prettier.html">从 Prettier 迁移</a>。</p>
<h3 id="ai-迁移提示词" tabindex="-1">AI 迁移提示词 <a class="header-anchor" href="#ai-迁移提示词" aria-label="Permalink to “AI 迁移提示词”">&#8203;</a></h3>
<p>或者，你可以将此提示词复制到你的 AI 编程助手以迁移你的项目：</p>
<div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span>按照 https://oxc.rs/docs/guide/usage/formatter.html 将此项目从 Prettier 迁移到 Oxfmt：</span></span>
<span class="line"><span>1. 安装 oxfmt 并运行 `oxfmt --migrate prettier`</span></span>
<span class="line"><span>2. 更新 package.json 脚本以使用 oxfmt</span></span>
<span class="line"><span>3. 更新 CI 工作流以使用 `oxfmt --check`</span></span>
<span class="line"><span>4. 更新 lint-staged 以使用 `oxfmt --no-error-on-unmatched-pattern`</span></span>
<span class="line"><span>5. 运行 oxfmt 重新格式化所有文件</span></span>
<span class="line"><span>6. 卸载 prettier 及相关包</span></span>
<span class="line"><span>7. 更新编辑器设置以支持 oxfmt</span></span>
<span class="line"><span>8. 如果 CONTRIBUTING.md、AGENTS.md 或 CLAUDE.md 中提到了 prettier，请更新它们</span></span></code></pre>
</div><p>更多详细说明，请查看 <a href="https://oxc.rs/docs/guide/usage/formatter.html" target="_blank" rel="noreferrer">Oxfmt 文档</a>。</p>
<h2 id="自-alpha-版本以来的新功能亮点" tabindex="-1">自 Alpha 版本以来的新功能亮点 <a class="header-anchor" href="#自-alpha-版本以来的新功能亮点" aria-label="Permalink to “自 Alpha 版本以来的新功能亮点”">&#8203;</a></h2>
<h3 id="_100-prettier-兼容性" tabindex="-1">100% Prettier 兼容性 <a class="header-anchor" href="#_100-prettier-兼容性" aria-label="Permalink to “100% Prettier 兼容性”">&#8203;</a></h3>
<p>Oxfmt 现在通过了 Prettier 100% 的 JavaScript 和 TypeScript 一致性测试。对于少数剩余的格式化不一致之处，我们已 <a href="https://github.com/oxc-project/oxc/issues/18717" target="_blank" rel="noreferrer">向 Prettier 团队报告</a> 并正在协作以达成预期行为的一致。</p>
<p>这意味着你可以放心地从 Prettier 迁移到 Oxfmt，确信你的代码将被相同地格式化。如果你遇到任何未覆盖的情况，请 <a href="https://github.com/oxc-project/oxc/issues/new?template=formatter_diff_report.yaml" target="_blank" rel="noreferrer">报告它们</a>。</p>
<h3 id="更多文件格式支持" tabindex="-1">更多文件格式支持 <a class="header-anchor" href="#更多文件格式支持" aria-label="Permalink to “更多文件格式支持”">&#8203;</a></h3>
<p>Oxfmt 现在支持格式化 JavaScript、JSX、TypeScript、TSX、JSON、JSONC、JSON5、YAML、TOML、HTML、Angular、Vue、CSS、SCSS、Less、Markdown、MDX、GraphQL、Ember 和 Handlebars。这意味着你可以为整个项目使用单一格式化程序。</p>
<h3 id="tailwind-css-集成" tabindex="-1">Tailwind CSS 集成 <a class="header-anchor" href="#tailwind-css-集成" aria-label="Permalink to “Tailwind CSS 集成”">&#8203;</a></h3>
<p>支持对 JS/TS 和非 JS/TS 文件进行自动 <a href="/docs/guide/usage/formatter/sorting.html#sort-tailwind-css-classes">Tailwind CSS 类排序</a>。<code>prettier-plugin-tailwindcss</code> 的功能已内置，因此不再需要该插件。</p>
<h3 id="导入排序" tabindex="-1">导入排序 <a class="header-anchor" href="#导入排序" aria-label="Permalink to “导入排序”">&#8203;</a></h3>
<p>内置的 <a href="/docs/guide/usage/formatter/sorting.html#sort-imports">导入排序</a> 现已可用，带有可配置选项：</p>
<ul>
<li><code>ignoreCase</code> - 不区分大小写排序</li>
<li><code>sortSideEffects</code> - 排序副作用导入</li>
<li><code>newlinesBetween</code> - 控制导入组之间的空行</li>
<li><code>groups</code> - 自定义排序顺序组</li>
<li><code>customGroups</code> - 定义自定义分组规则</li>
</ul>
<p>更多选项，请参阅 <a href="/docs/guide/usage/formatter/config-file-reference.html#sortimports">完整参考</a>。</p>
<h3 id="package-json-排序" tabindex="-1"><code>package.json</code> 排序 <a class="header-anchor" href="#package-json-排序" aria-label="Permalink to “package.json 排序”">&#8203;</a></h3>
<p>默认启用自动 <a href="/docs/guide/usage/formatter/sorting.html#sort-package-json-fields">package.json 字段排序</a>，保持你的 package.json 文件一致的组织结构。</p>
<h3 id="嵌入式语言格式化" tabindex="-1">嵌入式语言格式化 <a class="header-anchor" href="#嵌入式语言格式化" aria-label="Permalink to “嵌入式语言格式化”">&#8203;</a></h3>
<p>格式化 <a href="/docs/guide/usage/formatter/embedded-formatting.html">嵌入在模板字面量中的代码</a>：</p>
<ul>
<li>具有 styled-components 类似语法的 CSS-in-JS，<code>styled-jsx</code> 和 CSS prop 支持</li>
<li>Angular <code>@Component</code> 模板和样式</li>
</ul>
<h3 id="node-js-api" tabindex="-1">Node.js API <a class="header-anchor" href="#node-js-api" aria-label="Permalink to “Node.js API”">&#8203;</a></h3>
<p>现在可以使用编程式 API：</p>
<div class="language-ts"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> { format, </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">type</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> FormatOptions } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> "oxfmt"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> input</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> `let a=42;`</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> options</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">:</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> FormatOptions</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  semi: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">false</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">};</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> { </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">code</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> await</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> format</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"a.js"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, input, options);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">log</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(code); </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">// "let a = 42"</span></span></code></pre>
</div><h3 id="cli-变更" tabindex="-1"><a href="/docs/guide/usage/formatter/cli.html">CLI 变更</a> <a class="header-anchor" href="#cli-变更" aria-label="Permalink to “CLI 变更”">&#8203;</a></h3>
<ul>
<li><code>--init</code> - 引导生成新的配置文件</li>
<li><code>--migrate prettier</code> - 从 Prettier 配置迁移</li>
<li><code>--migrate biome</code> - 从 Biome 配置迁移</li>
<li><code>--stdin-filepath</code> - 指定 stdin 输入的文件路径</li>
<li>支持 Glob 模式展开 - <code>oxfmt './packages/**/*.{js,jsx}'</code></li>
</ul>
<h3 id="配置变更" tabindex="-1"><a href="/docs/guide/usage/formatter/config.html">配置变更</a> <a class="header-anchor" href="#配置变更" aria-label="Permalink to “配置变更”">&#8203;</a></h3>
<ul>
<li><a href="/docs/guide/usage/formatter/config.html#overrides"><code>overrides</code></a> - 将不同选项应用于特定文件模式</li>
<li><a href="/docs/guide/usage/formatter/config.html#insertfinalnewline"><code>insertFinalNewline</code></a> - 控制尾部换行</li>
<li>支持 <a href="/docs/guide/usage/formatter/config.html#editorconfig"><code>.editorconfig</code></a> 中的 <code>insert_final_newline</code></li>
</ul>
<h3 id="编辑器支持" tabindex="-1"><a href="/docs/guide/usage/formatter/editors.html">编辑器支持</a> <a class="header-anchor" href="#编辑器支持" aria-label="Permalink to “编辑器支持”">&#8203;</a></h3>
<p>Oxfmt 适用于所有支持的编辑器：VS Code、Cursor、Zed、IntelliJ IDEA、WebStorm、Neovim 以及任何支持 LSP 的编辑器。</p>
<h2 id="路线图" tabindex="-1">路线图 <a class="header-anchor" href="#路线图" aria-label="Permalink to “路线图”">&#8203;</a></h2>
<p>我们正在持续改进 Oxfmt 以迈向稳定版发布：</p>
<ul>
<li>支持 Prettier 插件</li>
<li>改进 xxx-in-js 格式化</li>
<li>稳定性</li>
<li>性能优化</li>
</ul>
<h2 id="下一步" tabindex="-1">下一步 <a class="header-anchor" href="#下一步" aria-label="Permalink to “下一步”">&#8203;</a></h2>
<p>请参阅 <a href="/docs/guide/usage/formatter.html">Oxfmt 文档</a> 中的完整安装指南。</p>
<h3 id="报告问题" tabindex="-1">报告问题 <a class="header-anchor" href="#报告问题" aria-label="Permalink to “报告问题”">&#8203;</a></h3>
<p>对于格式化差异，请参阅 <a href="https://github.com/oxc-project/oxc/discussions/14669" target="_blank" rel="noreferrer">格式化差异讨论</a>。</p>
<h3 id="加入社区" tabindex="-1">加入社区 <a class="header-anchor" href="#加入社区" aria-label="Permalink to “加入社区”">&#8203;</a></h3>
<p>我们很乐意听取你对 Oxfmt 的反馈。联系我们：</p>
<ul>
<li>Discord：加入我们的 <a href="https://discord.gg/9uXCAwqQZW" target="_blank" rel="noreferrer">社区服务器</a> 进行实时讨论</li>
<li>GitHub：在 <a href="https://github.com/oxc-project/oxc/discussions/13608" target="_blank" rel="noreferrer">Formatter RFC</a> 上分享反馈</li>
<li>Issues：在 <a href="https://github.com/oxc-project/oxc/issues" target="_blank" rel="noreferrer">问题追踪器</a> 上报告错误或请求功能</li>
</ul>
]]></content>
        <author>
            <name>Boshen</name>
            <uri>https://github.com/Boshen</uri>
        </author>
        <author>
            <name>Dunqing</name>
            <uri>https://github.com/dunqing</uri>
        </author>
        <author>
            <name>Yuji Sugiura</name>
            <uri>https://github.com/leaysgur</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Oxlint JS 插件 Alpha]]></title>
        <id>https://oxc.rs/blog/2026-03-11-oxlint-js-plugins-alpha</id>
        <link href="https://oxc.rs/blog/2026-03-11-oxlint-js-plugins-alpha"/>
        <updated>2026-03-11T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[<AppBlogPostHeader /><br>
<p><strong>Oxlint 的 JavaScript 插件已达到 Alpha 阶段 - 我们预计 80% 的 ESLint 用户现在可以切换到 Oxlint，并且能够“开箱即用”。</strong></p>
<p>Oxlint 已经用 Rust 实现了超过 650 条流行的 lint 规则，以原生速度运行。JS 插件填补了空白 - 一个兼容 ESLint 的插件 API，让你可以在 Oxlint 中运行现有的 ESLint 插件并编写你自己的自定义规则。大多数规则享有原生性能，其余规则拥有完全的灵活性。</p>
<p>自从去年 <a href="./2025-10-09-oxlint-js-plugins.html">首次技术预览</a> 以来，我们完善了几乎整个 ESLint 插件 API，添加了 TypeScript 插件支持、自动修复、IDE 集成以及 <a href="#performance">重大的性能提升</a>。</p>
<p>这意味着许多团队可以用 Oxlint 替换 ESLint，而无需重写他们的 lint 规则。</p>
<p>这个 Alpha 版本标志着我们认为 JS 插件已准备好在真实世界项目中采用的节点。</p>
<p>大多数项目应该会发现 Oxlint 现在可以作为 ESLint 的直接替代品，迁移简单，并且 lint 时间大幅减少。</p>
<h3 id="功能" tabindex="-1">功能 <a class="header-anchor" href="#功能" aria-label="Permalink to “功能”">&#8203;</a></h3>
<ul>
<li>无需修改即可运行大多数现有的 ESLint 插件。</li>
<li>使用 JavaScript 或 TypeScript 编写你自己的自定义 lint 规则。</li>
<li>从 JS 插件规则获得自动修复和建议。</li>
<li>通过语言服务器在 IDE 中实时查看 JS 插件诊断。</li>
</ul>
<h3 id="它有多可靠" tabindex="-1">它有多可靠？ <a class="header-anchor" href="#它有多可靠" aria-label="Permalink to “它有多可靠？”">&#8203;</a></h3>
<p>Oxlint JS 插件支持针对 ESLint 本身的完整测试套件进行了测试，也针对广泛的 ESLint 插件进行了测试，包括：</p>
<p>| 插件                                                                                               | 测试数 |  通过率 |
|</p>
]]></summary>
        <content type="html"><![CDATA[<AppBlogPostHeader /><br>
<p><strong>Oxlint 的 JavaScript 插件已达到 Alpha 阶段 - 我们预计 80% 的 ESLint 用户现在可以切换到 Oxlint，并且能够“开箱即用”。</strong></p>
<p>Oxlint 已经用 Rust 实现了超过 650 条流行的 lint 规则，以原生速度运行。JS 插件填补了空白 - 一个兼容 ESLint 的插件 API，让你可以在 Oxlint 中运行现有的 ESLint 插件并编写你自己的自定义规则。大多数规则享有原生性能，其余规则拥有完全的灵活性。</p>
<p>自从去年 <a href="./2025-10-09-oxlint-js-plugins.html">首次技术预览</a> 以来，我们完善了几乎整个 ESLint 插件 API，添加了 TypeScript 插件支持、自动修复、IDE 集成以及 <a href="#performance">重大的性能提升</a>。</p>
<p>这意味着许多团队可以用 Oxlint 替换 ESLint，而无需重写他们的 lint 规则。</p>
<p>这个 Alpha 版本标志着我们认为 JS 插件已准备好在真实世界项目中采用的节点。</p>
<p>大多数项目应该会发现 Oxlint 现在可以作为 ESLint 的直接替代品，迁移简单，并且 lint 时间大幅减少。</p>
<h3 id="功能" tabindex="-1">功能 <a class="header-anchor" href="#功能" aria-label="Permalink to “功能”">&#8203;</a></h3>
<ul>
<li>无需修改即可运行大多数现有的 ESLint 插件。</li>
<li>使用 JavaScript 或 TypeScript 编写你自己的自定义 lint 规则。</li>
<li>从 JS 插件规则获得自动修复和建议。</li>
<li>通过语言服务器在 IDE 中实时查看 JS 插件诊断。</li>
</ul>
<h3 id="它有多可靠" tabindex="-1">它有多可靠？ <a class="header-anchor" href="#它有多可靠" aria-label="Permalink to “它有多可靠？”">&#8203;</a></h3>
<p>Oxlint JS 插件支持针对 ESLint 本身的完整测试套件进行了测试，也针对广泛的 ESLint 插件进行了测试，包括：</p>
<table tabindex="0">
<thead>
<tr>
<th>插件</th>
<th style="text-align:right">测试数</th>
<th style="text-align:right">通过率</th>
</tr>
</thead>
<tbody>
<tr>
<td>ESLint 内置规则</td>
<td style="text-align:right">33,006</td>
<td style="text-align:right">100%</td>
</tr>
<tr>
<td><a href="https://www.npmjs.com/package/eslint-plugin-react-hooks" target="_blank" rel="noreferrer">React hooks</a>（包括 React Compiler 规则）</td>
<td style="text-align:right">5,007</td>
<td style="text-align:right">100%</td>
</tr>
<tr>
<td><a href="https://eslint.style/" target="_blank" rel="noreferrer">ESLint Stylistic</a></td>
<td style="text-align:right">18,310</td>
<td style="text-align:right">99.99%</td>
</tr>
<tr>
<td><a href="https://www.npmjs.com/package/eslint-plugin-testing-library" target="_blank" rel="noreferrer">Testing Library</a></td>
<td style="text-align:right">17,016</td>
<td style="text-align:right">100%</td>
</tr>
<tr>
<td><a href="https://www.npmjs.com/package/eslint-plugin-sonarjs" target="_blank" rel="noreferrer">SonarJS</a></td>
<td style="text-align:right">3,951</td>
<td style="text-align:right">99.6%*</td>
</tr>
<tr>
<td><a href="https://www.npmjs.com/package/@e18e/eslint-plugin" target="_blank" rel="noreferrer">e18e</a></td>
<td style="text-align:right">474</td>
<td style="text-align:right">100%*</td>
</tr>
</tbody>
</table>
<p><small>* 不包括类型感知规则</small></p>
<p>如果插件不在上面的列表中，它很可能仍然可以工作 - 只是尚未包含在 <a href="https://github.com/oxc-project/oxc/tree/13606c3ab16cc273a6fad7e2de964ffa0ad0a241/apps/oxlint/conformance" target="_blank" rel="noreferrer">我们的合规性测试套件</a> 中。</p>
<p>ESLint 自己的测试覆盖了整个 API 表面，所以 100% 的通过率让我们有信心覆盖了边界情况以及正常路径。请尝试一下并告诉我们反馈！</p>
<p>Oxlint 已经被许多公司和项目在生产环境中使用，包括 <a href="https://x.com/_chenglou/status/2026408795857981610" target="_blank" rel="noreferrer">Midjourney</a>、<a href="https://github.com/preactjs/preact" target="_blank" rel="noreferrer">Preact</a>、<a href="https://github.com/PostHog/posthog" target="_blank" rel="noreferrer">Posthog</a>、<a href="https://github.com/outline/outline" target="_blank" rel="noreferrer">Outline</a> 和 <a href="https://github.com/actualbudget/actual" target="_blank" rel="noreferrer">Actual</a>。</p>
<h3 id="它目前还不能做什么" tabindex="-1">它目前还不能做什么 <a class="header-anchor" href="#它目前还不能做什么" aria-label="Permalink to “它目前还不能做什么”">&#8203;</a></h3>
<ul>
<li>对前端框架自定义文件格式的支持有限（例如 Svelte、Vue、Angular）- 今年晚些时候推出。</li>
<li>没有自定义类型感知规则（TypeScript-ESLint 的规则已经通过 <a href="./../docs/guide/usage/linter/type-aware.html">类型感知 lint</a> 内置到 Oxlint 中）。</li>
<li>一些用户发现 Windows 上的体验欠佳。内存不足错误是 <a href="https://github.com/oxc-project/oxc/issues/19395" target="_blank" rel="noreferrer">一个已知问题</a>，特别是在 Windows 上。我们正在解决。与此同时，如果你遇到这个问题，我们建议在可行的情况下在 WSL 中运行 Oxlint。</li>
</ul>
<p>你可以在 <a href="https://github.com/oxc-project/oxc/issues/19918" target="_blank" rel="noreferrer">跟踪问题</a> 上关注我们填补这些空白的进展。</p>
<h2 id="开始使用" tabindex="-1">开始使用 <a class="header-anchor" href="#开始使用" aria-label="Permalink to “开始使用”">&#8203;</a></h2>
<p>将 <code>oxlint</code> 安装为开发依赖：</p>
<div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">pnpm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> add</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -D</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> oxlint</span></span></code></pre>
</div><p>在 <code>package.json</code> 中添加脚本：</p>
<tr><td>package.json</td><td><div class="vp-code-block-title">
      <div class="vp-code-block-title-bar">
          <span class="vp-code-block-title-text" data-title="package.json">package.json</span>
      </div>
        <div class="language-json"><button title="Copy Code" class="copy"></button><span class="lang">json</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">{</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">  "scripts"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: {</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "lint"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"oxlint"</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span></code></pre>
</div>
      </div>
      </td></tr><p>创建配置文件（或使用 <a href="#migrating-from-eslint">我们的迁移工具</a>）：</p>
<tr><td>.oxlintrc.json</td><td><div class="vp-code-block-title">
      <div class="vp-code-block-title-bar">
          <span class="vp-code-block-title-text" data-title=".oxlintrc.json">.oxlintrc.json</span>
      </div>
        <div class="language-json"><button title="Copy Code" class="copy"></button><span class="lang">json</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">{</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">  "jsPlugins"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"eslint-plugin-testing-library"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">],</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">  "rules"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: {</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "testing-library/no-render-in-lifecycle"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span></code></pre>
</div>
      </div>
      </td></tr><p>Lint 你的项目：</p>
<div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">pnpm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> run</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> lint</span></span></code></pre>
</div><h3 id="从-eslint-迁移" tabindex="-1">从 ESLint 迁移 <a class="header-anchor" href="#从-eslint-迁移" aria-label="Permalink to “从 ESLint 迁移”">&#8203;</a></h3>
<p>大多数项目应该会发现从 ESLint 迁移很简单。</p>
<p>最简单的途径是通过 <code>@oxlint/migrate</code> 工具。</p>
<div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">npx</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> @oxlint/migrate</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> eslint.config.js</span></span></code></pre>
</div><p>或者让你的编码代理使用 <a href="https://skills.sh/oxc-project/oxc/migrate-oxlint" target="_blank" rel="noreferrer"><code>migrate-oxlint</code> 技能</a> 为你完成。</p>
<p>查看更多详情请参阅 <a href="./../docs/guide/usage/linter/migrate-from-eslint.html">迁移指南</a>。</p>
<h2 id="eslint-规则" tabindex="-1">ESLint 规则 <a class="header-anchor" href="#eslint-规则" aria-label="Permalink to “ESLint 规则”">&#8203;</a></h2>
<p>Oxlint 已经原生实现了大多数 ESLint 的内置规则，用 Rust 重写，但并非所有规则都已实现。</p>
<p>为了弥补这一差距，我们提供了 <a href="https://www.npmjs.com/package/oxlint-plugin-eslint" target="_blank" rel="noreferrer">oxlint-plugin-eslint</a>，其中包含所有 ESLint 内置规则，打包为 Oxlint JS 插件。</p>
<p>这解锁了诸如 <code>no-restricted-syntax</code> 之类的规则，这些规则尚未在 Oxlint 中原生实现。</p>
<tr><td>.oxlintrc.json</td><td><div class="vp-code-block-title">
      <div class="vp-code-block-title-bar">
          <span class="vp-code-block-title-text" data-title=".oxlintrc.json">.oxlintrc.json</span>
      </div>
        <div class="language-jsonc"><button title="Copy Code" class="copy"></button><span class="lang">jsonc</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">{</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">  "jsPlugins"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"oxlint-plugin-eslint"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">],</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">  "rules"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">    // 注意："eslint-js" 而不是 "eslint"</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "eslint-js/no-restricted-syntax"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: [</span></span>
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">      "error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">      {</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">        "selector"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"ThrowStatement > CallExpression[callee.name=/Error$/]"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">        "message"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"Use `new` keyword when throwing an `Error`."</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">      },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    ],</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span></code></pre>
</div>
      </div>
      </td></tr><p>Oxlint 还原生实现了来自 <a href="https://www.npmjs.com/package/eslint-plugin-jsdoc" target="_blank" rel="noreferrer">eslint-plugin-jsdoc</a> 等插件的子集规则。对于 Oxlint 本身未实现的规则，你可以直接使用 <code>eslint-plugin-jsdoc</code> 包。这是推荐的模式：</p>
<tr><td>.oxlintrc.json</td><td><div class="vp-code-block-title">
      <div class="vp-code-block-title-bar">
          <span class="vp-code-block-title-text" data-title=".oxlintrc.json">.oxlintrc.json</span>
      </div>
        <div class="language-jsonc"><button title="Copy Code" class="copy"></button><span class="lang">jsonc</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">{</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">  "jsPlugins"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: [</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">    // 为插件 "jsdoc-js" 设置别名</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    { </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">"name"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"jsdoc-js"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">"specifier"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"eslint-plugin-jsdoc"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  ],</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">  "rules"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">    // 使用别名来引用插件中的规则</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "jsdoc-js/check-examples"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "jsdoc-js/require-description"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">    // 对 Oxlint 原生实现的规则使用普通的 "jsdoc"</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "jsdoc/require-property-name"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    "jsdoc/require-property-description"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span></code></pre>
</div>
      </div>
      </td></tr><h2 id="性能" tabindex="-1">性能 <a class="header-anchor" href="#性能" aria-label="Permalink to “性能”">&#8203;</a></h2>
<p>自从首次技术预览以来，我们已经将驱动 JS 插件的大量代码&quot;Rust 化&quot;，这带来了显著的性能提升。特别是依赖 tokens API 的插件（例如 ESLint Stylistic）比以前快了 5 倍。</p>
<p>作为一个基准测试，我们将 Node.js 的仓库从 ESLint 迁移到了 Oxlint。Node.js 是一个大型项目，利用了许多自定义 lint 规则，以及几个重量级的 ESLint 插件（总共 98 条 JS lint 规则）。</p>
<table tabindex="0">
<thead>
<tr>
<th>Linter</th>
<th>时间</th>
<th>加速比</th>
</tr>
</thead>
<tbody>
<tr>
<td>ESLint</td>
<td>1 分 43 秒</td>
<td></td>
</tr>
<tr>
<td>Oxlint</td>
<td>21 秒</td>
<td>4.8 倍</td>
</tr>
</tbody>
</table>
<div>
<details>
<summary>详情</summary>
<div  class="info custom-block"><p class="custom-block-title custom-block-title-default">INFO</p>
<ul>
<li>
<p><a href="https://github.com/overlookmotel/node" target="_blank" rel="noreferrer">基准测试仓库</a></p>
</li>
<li>
<p>6298 个文件已 lint</p>
</li>
<li>
<p>104 个内置 Oxlint 规则 (Rust)</p>
</li>
<li>
<p>75 个来自 JS 插件的规则 (JS)</p>
</li>
<li>
<p>23 个自定义规则 (JS)</p>
</li>
<li>
<p>基准测试环境：Mac Mini M4, 48GB RAM, Node.js 24.14.0</p>
</li>
<li>
<p>ESLint 基准测试：</p>
</li>
</ul>
<div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">git</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> checkout</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> bench-eslint</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">npm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> ci</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">hyperfine</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -i</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> --warmup</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> 1</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> --runs</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> 5</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> "node --run eslint"</span></span></code></pre>
</div><ul>
<li>Oxlint 基准测试：</li>
</ul>
<div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" dir="ltr" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">git</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> checkout</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> bench-oxlint</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">npm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> ci</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">hyperfine</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -i</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> --warmup</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> 1</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> --runs</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> 5</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> "node --run oxlint"</span></span></code></pre>
</div></div>
</details>
</div>
<p>当前使用 TypeScript-ESLint 或 <code>eslint-plugin-import</code> 的项目可能会看到 <strong>更大</strong> 的性能提升。<a href="https://discord.com/channels/1079625926024900739/1080712072012238858/threads/1478161352097796206" target="_blank" rel="noreferrer">我们 Discord 中的一位用户</a> 报告说，当他们从 ESLint 切换到 Oxlint 并大量使用 JS 插件时，他们公司 200 万行代码库的 lint 速度提升了 16 倍。较少使用 JS 插件的项目报告的速度提升高达 100 倍。</p>
<h3 id="未来的性能改进" tabindex="-1">未来的性能改进 <a class="header-anchor" href="#未来的性能改进" aria-label="Permalink to “未来的性能改进”">&#8203;</a></h3>
<p>这只是开始！</p>
<p>虽然带有 JS 插件的 Oxlint 已经比 ESLint 快得多，但我们管道中还有更多的优化。</p>
<p>Oxlint JS 插件性能的关键是一种新的、高度优化的、用于 Rust 和 JS 之间通信的底层机制，我们称之为 &quot;raw transfer&quot;。</p>
<p>Rust/JS 边界一直是支持 JS 插件的原生工具的根本问题。原生代码很快，但在 Rust 和 JS 之间来回发送数据的成本可能非常高，以至于抵消了这种增益，导致整体性能平庸。</p>
<p>Raw transfer 将数据在 Rust 和 JS 之间移动的成本降低到几乎为零，终于使原生代码和 JS 插件能够有效地协同工作。</p>
<p>Raw transfer 的第一次迭代已经在 Oxlint 的底层工作，但我们才刚刚开始利用它能做什么。随着我们继续这项工作，我们预计性能将进一步发生阶梯式变化，使 JS 插件接近原生 Rust 性能。</p>
<p>如果你对细节感兴趣，Oxc 核心团队成员 <a href="https://github.com/overlookmotel" target="_blank" rel="noreferrer">@overlookmotel</a> 就这个主题 <a href="https://www.youtube.com/watch?v=ofQV3xiBgT8" target="_blank" rel="noreferrer">在 ViteConf 2025 做了一次演讲</a>。</p>
<p>简而言之：Oxlint 已经是现存最快的 JS/TS linter。它将变得更快。</p>
<h3 id="性能提示-1-使用格式化工具" tabindex="-1">性能提示 1：使用格式化工具 <a class="header-anchor" href="#性能提示-1-使用格式化工具" aria-label="Permalink to “性能提示 1：使用格式化工具”">&#8203;</a></h3>
<p>我们强烈建议从使用 linter 进行代码格式化转向使用 <a href="./../docs/guide/usage/formatter.html">Oxfmt</a>（或你首选的格式化工具），如果可以的话。</p>
<p>Oxfmt 比 Prettier 快 30 倍，并且与 ESLint Stylistic 等 linter 插件相比，也将大幅减少 lint 时间。</p>
<p>Oxlint 和 Oxfmt 是非常强大的组合！</p>
<h3 id="性能提示-2-明智地选择插件" tabindex="-1">性能提示 2：明智地选择插件 <a class="header-anchor" href="#性能提示-2-明智地选择插件" aria-label="Permalink to “性能提示 2：明智地选择插件”">&#8203;</a></h3>
<p>与许多人的看法相反，编写高性能的 JavaScript 代码是完全可能的。Oxlint 速度快不仅仅是因为它是用 Rust 编写的——它也是经过精心设计，考虑了性能。</p>
<p>JS 插件本身的代码不在 Oxlint 的控制之下。要从整体上获得 Oxlint 的良好性能，需要你选择的 JS 插件也表现良好。</p>
<p>如果插件使用低效的算法或执行大量的文件系统操作，它在 ESLint 中会很慢，在 Oxlint 中也会很慢。Oxlint <em>可以</em> 做的是提供一个闪电般的解析器和供插件接口的高性能 API，但它不能神奇地让缓慢的 JS 代码变快。</p>
<p>如果你发现 lint 速度不如你想要的快，我们将来会提供一个实用工具来诊断哪些插件/规则是你项目中的性能瓶颈。</p>
<h2 id="创建自定义插件" tabindex="-1">创建自定义插件 <a class="header-anchor" href="#创建自定义插件" aria-label="Permalink to “创建自定义插件”">&#8203;</a></h2>
<p>如果您的项目有特定需求，为 Oxlint 创建自定义 JS 插件很简单。</p>
<p>请参阅 <a href="./../docs/guide/usage/linter/js-plugins.html">JS 插件指南</a>。</p>
<h1 id="常见问题" tabindex="-1">常见问题 <a class="header-anchor" href="#常见问题" aria-label="Permalink to “常见问题”">&#8203;</a></h1>
<p><strong>Oxlint 可以运行 ESLint 插件吗？</strong>
可以。大多数插件无需修改即可工作。</p>
<p><strong>Oxlint 比 ESLint 更快吗？</strong>
是的。基准测试通常显示 4 倍到 100 倍的速度提升。</p>
<p><strong>我可以逐步迁移吗？</strong>
可以。您可以同时运行 Oxlint 和 ESLint。</p>
<h2 id="致谢" tabindex="-1">致谢 <a class="header-anchor" href="#致谢" aria-label="Permalink to “致谢”">&#8203;</a></h2>
<p>将 JS 插件推进到这个里程碑是许多人共同努力的结果。特别是，我们要感谢：</p>
<ul>
<li><a href="https://github.com/Sysix" target="_blank" rel="noreferrer">@Sysix</a> 为语言服务器集成所做的不懈努力。</li>
<li><a href="https://github.com/lilnasy" target="_blank" rel="noreferrer">@lilnasy</a> 构建了许多 API。</li>
</ul>
<h2 id="加入社区" tabindex="-1">加入社区 <a class="header-anchor" href="#加入社区" aria-label="Permalink to “加入社区”">&#8203;</a></h2>
<p>我们很乐意听取您对 Oxlint JS 插件的反馈，并很高兴看到它如何帮助改善您的开发工作流程。</p>
<p>联系我们：</p>
<ul>
<li><strong>Discord</strong>：加入我们的 <a href="https://discord.gg/9uXCAwqQZW" target="_blank" rel="noreferrer">社区服务器</a> 进行实时讨论</li>
<li><strong>GitHub</strong>：在 <a href="https://github.com/oxc-project/oxc/discussions" target="_blank" rel="noreferrer">GitHub Discussions</a> 上分享反馈</li>
<li><strong>Issues</strong>：向 <a href="https://github.com/oxc-project/oxc/issues" target="_blank" rel="noreferrer">oxc</a> 报告 <code>oxlint</code> 错误。</li>
</ul>
]]></content>
        <author>
            <name>overlookmotel</name>
            <uri>https://github.com/overlookmotel</uri>
        </author>
        <author>
            <name>Cameron</name>
            <uri>https://github.com/camc314</uri>
        </author>
    </entry>
</feed>