<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Rspack 博客</title>
        <link>https://rspack.rs</link>
        <description>Fast Rust-based bundler for the web with a modernized webpack API</description>
        <lastBuildDate>Wed, 22 Apr 2026 10:55:13 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>zh-CN</language>
        <item>
            <title><![CDATA[Rspack 2.0 正式发布]]></title>
            <link>https://rspack.rs/zh/blog/announcing-2-0</link>
            <guid isPermaLink="false">/zh/blog/announcing-2-0</guid>
            <pubDate>Wed, 22 Apr 2026 16:00:01 GMT</pubDate>
            <description><![CDATA[Rspack 2.0 正式发布，在保持与 webpack 生态兼容的同时，引入了更现代的默认行为、API 设计和构建产物。]]></description>
            <content:encoded><![CDATA[<!--$--><p><em>2026 年 4 月 22 日</em></p>
<h1 class="rp-toc-include" id="rspack-20-正式发布"><a href="#rspack-20-正式发布" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rspack 2.0 正式发布<!-- --> </h1><div class="rp-not-doc rp-llms-container"><button class="rp-not-doc rp-llms-button rp-llms-copy-button"><div class="rp-llms-copy-button__icon-wrapper"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-llms-copy-button__icon-success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-llms-copy-button__icon-copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg></div><span>复制 Markdown</span></button><button class="rp-llms-button rp-llms-view-options__trigger "><svg width="1em" height="1em" viewBox="0 0 32 32" class="rp-llms-view-options__arrow "><path fill="currentColor" d="M16 22 6 12l1.4-1.4 8.6 8.6 8.6-8.6L26 12z"></path></svg></button></div>
<p><img src="https://assets.rspack.rs/rspack/rspack-banner-v2.0.png" alt="Rspack 2.0 Banner"/></p>
<p>我们很高兴地宣布 Rspack 2.0 已正式发布！</p>
<h2 class="rp-toc-include" id="回顾-1x"><a href="#回顾-1x" class="rp-header-anchor rp-link" aria-hidden="true">#</a>回顾 1.x</h2>
<p>在 2024 年 8 月发布 Rspack 1.0 时，我们设定了一个明确的阶段目标：在保持与 webpack API 和生态兼容的前提下，实现 10 倍的构建性能提升。</p>
<p>回顾 1.x 阶段，这一目标已经基本达成。Rspack 不仅实现了 webpack 的核心能力和插件 API，也在开发体验、产物优化以及现代语言特性支持等方面不断演进，陆续引入并完善了增量构建、按需编译、持久化缓存、常量内联、虚拟模块、Barrel 文件优化等新特性。</p>
<p>同时，Rspack 也正被越来越多的用户采用。与 1.0 发布时相比，<strong>Rspack 的周下载量已由 10 万增长至 500 万</strong>：</p>
<p><img src="https://assets.rspack.rs/rspack/assets/rspack-v2-0-npm-downloads.png" alt="Rspack 2.0 npm downloads"/></p>
<p>我们还围绕 Rspack 打造了 Rstack，一套统一的 JavaScript 工具链，包括 <a href="https://github.com/web-infra-dev/rsbuild" target="_blank" rel="noopener noreferrer" class="rp-link">Rsbuild</a>、<a href="https://github.com/web-infra-dev/rslib" target="_blank" rel="noopener noreferrer" class="rp-link">Rslib</a>、<a href="https://github.com/web-infra-dev/rstest" target="_blank" rel="noopener noreferrer" class="rp-link">Rstest</a>、<a href="https://github.com/web-infra-dev/rspress" target="_blank" rel="noopener noreferrer" class="rp-link">Rspress</a>、<a href="https://github.com/web-infra-dev/rsdoctor" target="_blank" rel="noopener noreferrer" class="rp-link">Rsdoctor</a> 和 <a href="https://github.com/web-infra-dev/rslint" target="_blank" rel="noopener noreferrer" class="rp-link">Rslint</a>。这些工具面向不同场景，但都共享了同一个使命：让 Web 开发变得更加简洁、一致和高效。</p>
<p>Rspack 也在逐步融入更广泛的 JavaScript 生态，社区中许多优秀的工具、框架和平台已经提供对 Rspack 的支持，包括但不限于：<a href="https://nx.dev/docs/technologies/angular/angular-rspack" target="_blank" rel="noopener noreferrer" class="rp-link">Angular Rspack</a>、<a href="https://github.com/addfox/addfox" target="_blank" rel="noopener noreferrer" class="rp-link">Addfox</a>、<a href="https://github.com/facebook/docusaurus" target="_blank" rel="noopener noreferrer" class="rp-link">Docusaurus</a>、<a href="https://github.com/extension-js/extension.js" target="_blank" rel="noopener noreferrer" class="rp-link">Extension.js</a>、<a href="https://github.com/alibaba/ice" target="_blank" rel="noopener noreferrer" class="rp-link">ice.js</a>、<a href="https://github.com/lynx-family/lynx" target="_blank" rel="noopener noreferrer" class="rp-link">Lynx</a>、<a href="https://github.com/meteor/meteor" target="_blank" rel="noopener noreferrer" class="rp-link">Meteor</a>、<a href="https://github.com/web-infra-dev/modern.js" target="_blank" rel="noopener noreferrer" class="rp-link">Modern.js</a>、<a href="https://github.com/vercel/next.js" target="_blank" rel="noopener noreferrer" class="rp-link">Next.js</a>、<a href="https://github.com/nuxt/nuxt" target="_blank" rel="noopener noreferrer" class="rp-link">Nuxt</a>、<a href="https://github.com/nrwl/nx" target="_blank" rel="noopener noreferrer" class="rp-link">Nx</a>、<a href="https://github.com/kmijs/kmi" target="_blank" rel="noopener noreferrer" class="rp-link">Kmi</a>、<a href="https://github.com/callstack/repack" target="_blank" rel="noopener noreferrer" class="rp-link">Re.Pack</a>、<a href="https://github.com/remotion-dev/remotion" target="_blank" rel="noopener noreferrer" class="rp-link">Remotion</a>、<a href="https://github.com/shakacode/shakapacker" target="_blank" rel="noopener noreferrer" class="rp-link">Shakapacker</a>、<a href="https://github.com/storybookjs/storybook" target="_blank" rel="noopener noreferrer" class="rp-link">Storybook</a>、<a href="https://tanstack.com/router" target="_blank" rel="noopener noreferrer" class="rp-link">TanStack Router</a>、<a href="https://github.com/unjs/unplugin" target="_blank" rel="noopener noreferrer" class="rp-link">Unplugin</a>、<a href="https://github.com/ubugeeei/vize" target="_blank" rel="noopener noreferrer" class="rp-link">Vize</a>、<a href="https://github.com/basementstudio/xmcp" target="_blank" rel="noopener noreferrer" class="rp-link">xmcp</a>、<a href="https://zephyr-cloud.io/" target="_blank" rel="noopener noreferrer" class="rp-link">Zephyr</a>。在此，我们衷心感谢所有支持 Rspack 的社区项目和团队。</p>
<h2 class="rp-toc-include" id="迈向-20"><a href="#迈向-20" class="rp-header-anchor rp-link" aria-hidden="true">#</a>迈向 2.0</h2>
<p>JavaScript 生态在不断发展，Coding Agent 也正在改变软件研发范式。这促使我们重新思考：一个面向未来的打包工具应当如何演进。</p>
<p><strong>Rspack 的目标不只是成为一个「更快的 webpack」</strong>。在 1.x 阶段，我们有意让 Rspack 的 API 和默认值与 webpack 5 保持一致，这一策略是为了帮助现有项目低成本迁移到 Rspack。但随着 JavaScript 模块规范和生态的发展，一些历史设计已不再适合作为当下的默认选择。</p>
<p>从 2.0 开始，在保持对 webpack 生态兼容的前提下，Rspack 将逐步引入更符合现代 JavaScript 开发的默认行为、API 设计和构建产物。这将是一个渐进的过程，我们会尽量避免在单个主版本中引入过多不兼容变更，同时也会提供迁移指南与 Agent Skills，将迁移成本控制在可接受范围内。</p>
<h2 class="rp-toc-include" id="20-亮点"><a href="#20-亮点" class="rp-header-anchor rp-link" aria-hidden="true">#</a>2.0 亮点</h2>
<p>Rspack 2.0 主要带来以下更新：</p>
<ul>
<li>性能提升<!-- -->
<ul>
<li><a href="#build-performance" class="rp-link">构建提速</a></li>
<li><a href="#fewer-deps" class="rp-link">精简默认依赖</a></li>
</ul>
</li>
<li>产物优化<!-- -->
<ul>
<li><a href="#better-tree-shaking" class="rp-link">静态分析增强</a></li>
<li><a href="#pure-functions" class="rp-link">编译器注解支持</a></li>
<li><a href="#mf-share-treeshaking" class="rp-link">模块联邦 tree shaking</a></li>
</ul>
</li>
<li>改进 ESM 支持<!-- -->
<ul>
<li><a href="#pure-esm" class="rp-link">纯 ESM 包</a></li>
<li><a href="#import-meta" class="rp-link">import.meta 支持</a></li>
<li><a href="#import-defer" class="rp-link">import defer 支持</a></li>
<li><a href="#modern-module" class="rp-link">改进 ESM 库构建</a></li>
</ul>
</li>
<li>新特性<!-- -->
<ul>
<li><a href="#rsc-support" class="rp-link">React Server Components 支持</a></li>
<li><a href="#subpath-alias-import" class="rp-link">支持 <code>#/</code> 子路径别名导入</a></li>
<li><a href="#automatic-targets" class="rp-link">简化目标环境配置</a></li>
<li><a href="#detect-syntax" class="rp-link">简化 swc-loader 配置</a></li>
<li><a href="#resolve-import" class="rp-link">支持控制 CSS 导入</a></li>
<li><a href="#hashed-module-ids-plugin" class="rp-link">使用哈希作为模块 ID</a></li>
<li><a href="#enforce-size-threshold" class="rp-link">代码分割改进</a></li>
</ul>
</li>
</ul>
<h2 class="rp-toc-include" id="性能提升"><a href="#性能提升" class="rp-header-anchor rp-link" aria-hidden="true">#</a>性能提升</h2>
<h3 class="rp-toc-include" id="build-performance"><a href="#build-performance" class="rp-header-anchor rp-link" aria-hidden="true">#</a>构建提速</h3>
<p>构建性能始终是 Rspack 的核心关注点之一。与 Rspack 1.7 相比，<strong>Rspack 2.0 的整体性能提升约 10%</strong>，相较 1.0 最多可提升 100%。</p>
<div class="rp-table-scroll-container rp-scrollbar"><table><thead><tr><th>版本</th><th>生产构建（无缓存）</th><th>生产构建（有缓存）</th><th>热更新</th></tr></thead><tbody><tr><td>Rspack 1.0</td><td><strong>5.6 s</strong></td><td><strong>5.6 s</strong></td><td><strong>128 ms</strong></td></tr><tr><td>Rspack 1.7</td><td><strong>3.6 s</strong></td><td><strong>2.2 s</strong></td><td><strong>134 ms</strong></td></tr><tr><td>Rspack 2.0</td><td><strong>3.1 s</strong></td><td><strong>1.4 s</strong></td><td><strong>118 ms</strong></td></tr></tbody></table></div>
<blockquote>
<p>数据来源：<a href="https://github.com/LingyuCoder/rspack-react-10k-benchmark/actions/runs/24710780593" target="_blank" rel="noopener noreferrer" class="rp-link">rspack-react-10k-benchmark</a></p>
</blockquote>
<p>这些改进主要来自对核心架构的持续优化。我们针对关键性能路径重构了部分算法与数据结构，升级了部分过时依赖，并清理了不再使用的代码路径。</p>
<p>在开启 <a href="/zh/config/cache" class="rp-link">持久化缓存</a> 的场景下，构建性能和内存占用得到了进一步改善：</p>
<ul>
<li>现在 Rspack 支持对 <a href="/zh/plugins/rspack/swc-js-minimizer-rspack-plugin" class="rp-link">SWC 压缩插件</a> 的结果进行缓存复用，在命中缓存时，<strong>构建性能提升约 50%</strong></li>
<li>通过优化底层存储实现，在启用缓存时，<strong>内存占用下降了 20%+</strong></li>
</ul>
<h3 class="rp-toc-include" id="fewer-deps"><a href="#fewer-deps" class="rp-header-anchor rp-link" aria-hidden="true">#</a>精简默认依赖</h3>
<p>Rspack 2.0 减少了默认安装的 npm 依赖数量：</p>
<ul>
<li><code>@rspack/dev-server</code>：<strong>依赖数量从 192 降至 1</strong>。</li>
<li><code>@rspack/core</code>：<strong>依赖数量从 8 降至 1</strong>。</li>
<li><code>@rspack/cli</code>：<strong>现在为零依赖</strong>。</li>
</ul>
<p>在 Rspack 1.x 中，<code>@rspack/dev-server</code> 通过 <code>webpack-dev-server</code> 间接引入了较多依赖，这增加了安装体积，也加大了依赖管理的复杂度。为此，我们对它进行了重构，梳理并精简了功能和依赖，<strong>使安装体积减少超过 90%</strong>（从 15 MB 降至 1.4 MB）。</p>
<p>同时，<code>@rspack/cli</code> 也不再默认依赖 <code>@rspack/dev-server</code>，这意味着如果只使用 <code>rspack build</code>，将不再需要引入开发服务器相关依赖。</p>
<p>此外，我们还采用了以下方式来减少依赖：</p>
<ul>
<li>将非核心依赖调整为可选依赖。例如 <a href="https://www.npmjs.com/package/@module-federation/runtime-tools" target="_blank" rel="noopener noreferrer" class="rp-link">@module-federation/runtime-tools</a> 现在仅在使用 <a href="/zh/plugins/webpack/module-federation-plugin" class="rp-link">模块联邦插件</a> 时才需要手动安装。</li>
<li>使用更轻量的替代实现，例如以 <a href="https://github.com/rstackjs/connect-next" target="_blank" rel="noopener noreferrer" class="rp-link">connect-next</a> 替代 Express。对于开发服务器而言，Connect 的中间件模型已经能够覆盖大多数场景，这也与 Rsbuild 的开发服务器实现保持一致。</li>
<li>将部分依赖 <a href="https://e18e.dev/blog/bundling-dependencies" target="_blank" rel="noopener noreferrer" class="rp-link">打包进 npm 发布产物</a>，由 Rspack 统一控制这些依赖及其子依赖的版本，避免依赖自动升级带来的潜在供应链风险。</li>
<li>优先使用 Node.js 20+ 内置的原生 API，例如用 <a href="https://nodejs.org/api/util.html#utilstyletextformat-text-options" target="_blank" rel="noopener noreferrer" class="rp-link">styleText</a> 替代 <code>picocolors</code>。</li>
</ul>
<h2 class="rp-toc-include" id="产物优化"><a href="#产物优化" class="rp-header-anchor rp-link" aria-hidden="true">#</a>产物优化</h2>
<h3 class="rp-toc-include" id="better-tree-shaking"><a href="#better-tree-shaking" class="rp-header-anchor rp-link" aria-hidden="true">#</a>静态分析增强</h3>
<p>Rspack 2.0 在静态分析能力上进行了增强，使更多复杂代码模式纳入 <a href="/zh/guide/optimization/tree-shaking" class="rp-link">tree shaking</a> 的优化范围。一些过去难以分析的场景，现在也能参与导出级别的裁剪。</p>
<ul>
<li><strong>CommonJS <code>require</code> 解构赋值</strong>：Rspack 现在可以识别解构中实际使用到的导出成员，仅保留必要代码</li>
</ul>
<div class="rp-codeblock language-js"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js"><code><span class="line"><span style="color:var(--shiki-token-keyword)">const</span><span style="color:var(--shiki-foreground)"> { </span><span style="color:var(--shiki-token-constant)">bar</span><span style="color:var(--shiki-foreground)"> } </span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-token-function)"> require</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">&#x27;./foo&#x27;</span><span style="color:var(--shiki-foreground)">);</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<ul>
<li><strong>CommonJS <code>require</code> 成员访问与调用</strong>：Rspack 现在能继续向下分析对象的成员访问和调用，判断哪些导出被使用</li>
</ul>
<div class="rp-codeblock language-js"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js"><code><span class="line"><span style="color:var(--shiki-token-keyword)">const</span><span style="color:var(--shiki-token-constant)"> foo</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-function)"> require</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">&#x27;./foo&#x27;</span><span style="color:var(--shiki-foreground)">);</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-constant)">foo</span><span style="color:var(--shiki-foreground)">.bar;</span></span>
<span class="line"><span style="color:var(--shiki-token-constant)">foo</span><span style="color:var(--shiki-token-function)">.baz</span><span style="color:var(--shiki-foreground)">();</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<ul>
<li><strong>动态 <code>import()</code> 结果的内联成员访问与调用</strong>：对于这种直接在表达式中访问模块成员的写法，Rspack 同样可以识别使用到的导出，并进行裁剪</li>
</ul>
<div class="rp-codeblock language-js"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js"><code><span class="line"><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-keyword)">await</span><span style="color:var(--shiki-token-keyword)"> import</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">&#x27;./foo&#x27;</span><span style="color:var(--shiki-foreground)">)).bar;</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h3 class="rp-toc-include" id="pure-functions"><a href="#pure-functions" class="rp-header-anchor rp-link" aria-hidden="true">#</a>编译器注解支持</h3>
<p>Rspack 2.0 现在支持 <a href="https://github.com/javascript-compiler-hints/compiler-notations-spec" target="_blank" rel="noopener noreferrer" class="rp-link">编译器注解</a>，允许你使用 <code>#__NO_SIDE_EFFECTS__</code> 将函数标记为无副作用。当该函数调用的返回值未被使用时，tree shaking 会自动移除未使用的代码。</p>
<p>例如，在下面的代码中，<code>join</code> 被标记为无副作用函数。当它的返回值没有被使用时，该调用会被安全移除。</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">utils.js</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="utils.js"><code><span class="line"><span style="color:var(--shiki-token-comment)">/*#__NO_SIDE_EFFECTS__*/</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> function</span><span style="color:var(--shiki-token-function)"> join</span><span style="color:var(--shiki-foreground)">(a</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> b) {</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">  return</span><span style="color:var(--shiki-token-string-expression)"> `</span><span style="color:var(--shiki-token-keyword)">${</span><span style="color:var(--shiki-foreground)">a</span><span style="color:var(--shiki-token-keyword)">}</span><span style="color:var(--shiki-token-string-expression)">-</span><span style="color:var(--shiki-token-keyword)">${</span><span style="color:var(--shiki-foreground)">b</span><span style="color:var(--shiki-token-keyword)">}</span><span style="color:var(--shiki-token-string-expression)">`</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">}</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">index.js</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="index.js"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { join } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;./utils&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-function)">join</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">&#x27;btn&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-string-expression)"> &#x27;primary&#x27;</span><span style="color:var(--shiki-foreground)">);</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<blockquote>
<p>该功能仍处于实验阶段，目前需要通过 <a href="/zh/config/experiments#experimentspurefunctions" class="rp-link"><code>experiments.pureFunctions</code></a> 启用，并将在后续版本中默认开启，查看 <a href="/zh/guide/optimization/tree-shaking#no_side_effects-注解" class="rp-link">指南</a> 了解更多。</p>
</blockquote>
<p>对于无法直接修改源码的第三方模块，Rspack 还允许你通过 <a href="/zh/config/module#moduleparserjavascriptpurefunctions" class="rp-link"><code>module.parser.javascript.pureFunctions</code></a> 选项手动声明纯函数列表，以达到同样的效果。</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  module</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    parser</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      javascript</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        pureFunctions</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span><span style="color:var(--shiki-token-string-expression)">&#x27;myFunctionName&#x27;</span><span style="color:var(--shiki-foreground)">]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h3 class="rp-toc-include" id="mf-share-treeshaking"><a href="#mf-share-treeshaking" class="rp-header-anchor rp-link" aria-hidden="true">#</a>模块联邦 tree shaking</h3>
<p>Rspack 现在支持对 <a href="/zh/guide/features/module-federation" class="rp-link">模块联邦</a> 的共享依赖进行 tree shaking。它可以在导出级别裁剪共享依赖，移除未使用的部分，从而减小共享包的体积。</p>
<p>在 Rspack 1.x 中，只要依赖被声明为 <code>shared</code>，运行时通常需要加载完整包。即使只用到少量导出，也会引入全部内容。对于体积较大的共享库，这会带来显著的开销。</p>
<p>而 Rspack 2.0 支持在 <code>shared</code> 选项中开启 <code>treeShaking</code>。此时，<code>ModuleFederationPlugin</code> 会为共享依赖生成裁剪后的产物，运行时优先加载该结果；若无法命中，再回退到完整依赖，以保证行为一致。</p>
<p>例如：</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { rspack } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;@rspack/core&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  plugins</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">    new</span><span style="color:var(--shiki-token-constant)"> rspack</span><span style="color:var(--shiki-token-function)">.</span><span style="color:var(--shiki-token-constant)">container</span><span style="color:var(--shiki-token-function)">.ModuleFederationPlugin</span><span style="color:var(--shiki-foreground)">({</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      shared</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-token-string-expression)">        &#x27;lodash-es&#x27;</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          singleton</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> true</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          treeShaking</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">            mode</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;runtime-infer&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">            usedExports</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span><span style="color:var(--shiki-token-string-expression)">&#x27;debounce&#x27;</span><span style="color:var(--shiki-foreground)">]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    })</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  ]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<blockquote>
<p>查看 <a href="https://module-federation.io/zh/guide/performance/shared-tree-shaking" target="_blank" rel="noopener noreferrer" class="rp-link">共享依赖 tree shaking 指南</a> 了解更多。</p>
</blockquote>
<h2 class="rp-toc-include" id="改进-esm-支持"><a href="#改进-esm-支持" class="rp-header-anchor rp-link" aria-hidden="true">#</a>改进 ESM 支持</h2>
<h3 class="rp-toc-include" id="pure-esm"><a href="#pure-esm" class="rp-header-anchor rp-link" aria-hidden="true">#</a>纯 ESM 包</h3>
<p>Rspack 的核心包现在以 pure ESM 包的形式发布，并移除了自身的 CommonJS 构建产物，这使模块加载方式更加统一，也更符合当前 Node.js 的主流实践。</p>
<p>本次变更涉及以下 npm 包：</p>
<ul>
<li><a href="https://www.npmjs.com/package/@rspack/core" target="_blank" rel="noopener noreferrer" class="rp-link">@rspack/core</a></li>
<li><a href="https://www.npmjs.com/package/@rspack/cli" target="_blank" rel="noopener noreferrer" class="rp-link">@rspack/cli</a></li>
<li><a href="https://www.npmjs.com/package/@rspack/dev-server" target="_blank" rel="noopener noreferrer" class="rp-link">@rspack/dev-server</a></li>
<li><a href="https://www.npmjs.com/package/@rspack/plugin-react-refresh" target="_blank" rel="noopener noreferrer" class="rp-link">@rspack/plugin-react-refresh</a></li>
</ul>
<p>在 Node.js 20 及以上版本中，运行时已原生支持通过 <a href="https://nodejs.org/api/modules.html#loading-ecmascript-modules-using-require" target="_blank" rel="noopener noreferrer" class="rp-link">require(esm)</a> 加载 ESM 模块。因此，对于大多数仍通过 JavaScript API 使用 Rspack 的项目而言，这一变更通常不会带来实际影响，也无需额外修改现有代码。</p>
<h3 class="rp-toc-include" id="import-meta"><a href="#import-meta" class="rp-header-anchor rp-link" aria-hidden="true">#</a>import.meta 支持</h3>
<p>Rspack 2.0 改进了对 <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import.meta" target="_blank" rel="noopener noreferrer" class="rp-link">import.meta</a> 的支持。</p>
<p>在 Rspack 1.x 中，为了兼容非 ESM 产物，Rspack 会在编译阶段解析 <code>import.meta</code> 并替换为对应的值。对于无法识别的 <code>import.meta</code> 属性，通常会直接替换为 <code>undefined</code>。</p>
<p>从 Rspack 2.0 开始，在生成 ESM 产物时，Rspack 默认会保留无法识别的 <code>import.meta</code> 属性，而不是在编译阶段将其替换。这使你可以使用一些自定义 <code>import.meta</code> 属性，也使其行为更符合 ESM 规范。</p>
<p>这一行为也可以通过 <a href="/zh/config/module#moduleparserjavascriptimportmeta" class="rp-link"><code>module.parser.javascript.importMeta</code></a> 进行控制，例如：</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  output</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    module</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> true</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  module</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    parser</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      javascript</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        importMeta</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;preserve-unknown&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>此外，Rspack 2.0 还补充了对 <a href="/zh/api/runtime-api/module-variables#importmetamain" class="rp-link"><code>import.meta.main</code></a>、<a href="/zh/api/runtime-api/module-variables#importmetafilename" class="rp-link"><code>import.meta.filename</code></a> 和 <a href="/zh/api/runtime-api/module-variables#importmetadirname" class="rp-link"><code>import.meta.dirname</code></a> 的支持。</p>
<h3 class="rp-toc-include" id="import-defer"><a href="#import-defer" class="rp-header-anchor rp-link" aria-hidden="true">#</a>import defer 支持</h3>
<p><a href="https://github.com/tc39/proposal-defer-import-eval" target="_blank" rel="noopener noreferrer" class="rp-link">import defer</a> 是 JavaScript 中一项用于延后模块求值的能力，也已在 <a href="https://devblogs.microsoft.com/typescript/announcing-typescript-5-9-beta/#support-for-import-defer" target="_blank" rel="noopener noreferrer" class="rp-link">TypeScript 5.9</a> 中得到支持。它允许你在导入模块时先完成加载，而不立即执行模块及其依赖，从而更好地控制代码加载和副作用发生的时机。</p>
<p>Rspack 从 1.6 开始支持 <code>import defer * as foo from &#x27;./foo&#x27;</code> 语法。在 2.0 中，我们进一步补齐了对 <code>import.defer()</code> 的支持，使这项能力能够覆盖更多实际场景。</p>
<ul>
<li>启用实验性开关：</li>
</ul>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  experiments</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    deferImport</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> true</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<ul>
<li>使用 <code>import.defer()</code> 来动态导入模块：</li>
</ul>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">app.js</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="app.js"><code><span class="line"><span style="color:var(--shiki-token-keyword)">const</span><span style="color:var(--shiki-token-constant)"> file</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-constant)"> Math</span><span style="color:var(--shiki-token-function)">.random</span><span style="color:var(--shiki-foreground)">() </span><span style="color:var(--shiki-token-keyword)">&gt;</span><span style="color:var(--shiki-token-constant)"> 0.5</span><span style="color:var(--shiki-token-keyword)"> ?</span><span style="color:var(--shiki-token-string-expression)"> &#x27;a.js&#x27;</span><span style="color:var(--shiki-token-keyword)"> :</span><span style="color:var(--shiki-token-string-expression)"> &#x27;b.js&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-constant)">import</span><span style="color:var(--shiki-token-function)">.defer</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">&#x27;./dir&#x27;</span><span style="color:var(--shiki-token-keyword)"> +</span><span style="color:var(--shiki-foreground)"> file);</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h3 class="rp-toc-include" id="modern-module"><a href="#modern-module" class="rp-header-anchor rp-link" aria-hidden="true">#</a>改进 ESM 库构建</h3>
<p>在构建 JavaScript 库时，ESM 输出的质量会直接影响下游工具的分析和优化效果。更纯净的 ESM 产物，通常也更有利于静态分析、代码分割和 tree shaking。</p>
<p>在 Rspack 2.0 中，你可以将 <a href="/zh/config/output#outputlibrarytype" class="rp-link"><code>output.library.type</code></a> 配置为 <code>&#x27;modern-module&#x27;</code>，以生成更适合库发布的 ESM 产物。</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  output</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    library</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      type</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;modern-module&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>相比面向普通 ESM 输出的 <a href="/zh/config/output#outputmodule" class="rp-link"><code>output.module</code></a> 选项，<code>modern-module</code> 针对库构建场景做了专门优化。它基于 Rspack 1.x 中引入的实验性 <a href="https://v1.rspack.rs/plugins/rspack/esm-library-plugin" target="_blank" rel="noopener noreferrer" class="rp-link"><code>rspack.experiments.EsmLibraryPlugin</code></a> 演进而来，生成的产物更便于下游工具继续分析和处理。在代码分割场景下，它也能保持更清晰的 ESM 结构，并减少多入口构建中的重复代码。</p>
<p>此外，<code>modern-module</code> 还支持保留源码目录结构，详见 <a href="/zh/guide/features/esm" class="rp-link">ESM 指南</a>。</p>
<h2 class="rp-toc-include" id="新特性"><a href="#新特性" class="rp-header-anchor rp-link" aria-hidden="true">#</a>新特性</h2>
<h3 class="rp-toc-include" id="rsc-support"><a href="#rsc-support" class="rp-header-anchor rp-link" aria-hidden="true">#</a>React Server Components 支持</h3>
<p><a href="https://react.dev/reference/rsc/server-components" target="_blank" rel="noopener noreferrer" class="rp-link">React Server Components</a>（RSC）正在成为 React 全栈框架中的一项重要基础能力。Rspack 2.0 也为此提供了实验性的底层构建支持，包括：</p>
<ul>
<li><strong>指令支持</strong>：支持 <code>&quot;use client&quot;</code> 声明，以及模块和函数级别的 <code>&quot;use server&quot;</code> 声明</li>
<li><strong>编译期检查</strong>：在编译阶段识别违反 RSC 规范的 React API 调用，帮助在进入运行时前尽早发现问题</li>
<li><strong>CSS 支持</strong>：在构建阶段收集服务端与客户端组件的样式，并在渲染时注入</li>
<li><strong>HMR 支持</strong>：同时支持服务端组件和客户端组件的热更新</li>
</ul>
<p>你可以通过以下两种方式使用这项能力：</p>
<ul>
<li><strong>使用 Rsbuild</strong>：我们通过 <a href="https://github.com/rstackjs/rsbuild-plugin-rsc" target="_blank" rel="noopener noreferrer" class="rp-link">rsbuild-plugin-rsc</a> 提供了开箱即用的 RSC 支持。</li>
<li><strong>手动配置 Rspack</strong>：参考 <a href="/zh/guide/tech/rsc" class="rp-link">React Server Components 文档</a> 以手动添加相关配置。</li>
</ul>
<p>在生态支持方面，Modern.js 已基于 Rspack 提供 RSC 支持，详见 <a href="https://modernjs.dev/guides/basic-features/render/rsc.html" target="_blank" rel="noopener noreferrer" class="rp-link">Modern.js RSC 文档</a>。同时，Rspack 已支持 React Router 的 Data Mode，相关示例见 <a href="https://github.com/rstackjs/rsbuild-plugin-rsc/tree/main/examples/react-router" target="_blank" rel="noopener noreferrer" class="rp-link">React Router 示例</a>。</p>
<p>另外，我们也在与 <a href="https://tanstack.com/" target="_blank" rel="noopener noreferrer" class="rp-link">TanStack</a> 团队展开合作，计划在后续版本中提供对 <a href="https://tanstack.com/start" target="_blank" rel="noopener noreferrer" class="rp-link">TanStack Start</a> 和 <a href="https://tanstack.com/blog/react-server-components" target="_blank" rel="noopener noreferrer" class="rp-link">TanStack 的 RSC</a> 的支持。TanStack Start 是一个基于 TanStack Router 构建的全栈框架，我们非常期待结合双方的能力，共同探索 RSC 在不同场景下的更多可能性。</p>
<h3 class="rp-toc-include" id="subpath-alias-import"><a href="#subpath-alias-import" class="rp-header-anchor rp-link" aria-hidden="true">#</a><code>#/</code> 子路径别名导入</h3>
<p>在模块解析方面，Rspack 2.0 支持 <code>#/</code> 形式的子路径别名导入。这样一来，你可以直接使用 <code>package.json</code> 中的 <code>imports</code> 字段来组织包内路径映射，而不必额外维护一套独立的别名配置。</p>
<div class="rp-codeblock language-json"><div class="rp-codeblock__title">package.json</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="json" data-title="package.json"><code><span class="line"><span style="color:var(--shiki-foreground)">{</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">  &quot;imports&quot;</span><span style="color:var(--shiki-token-punctuation)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">    &quot;#/*&quot;</span><span style="color:var(--shiki-token-punctuation)">:</span><span style="color:var(--shiki-token-string-expression)"> &quot;./src/*&quot;</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">}</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">src/index.js</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="src/index.js"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> main </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;#/main.ts&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h3 class="rp-toc-include" id="automatic-targets"><a href="#automatic-targets" class="rp-header-anchor rp-link" aria-hidden="true">#</a>简化目标环境配置</h3>
<p>在 Rspack 1.x 中，顶层的 <a href="/zh/config/target" class="rp-link">target</a> 选项不会影响 loader 或压缩工具的转换目标，因此你通常还需要在 loader 或压缩插件中分别配置目标环境。这带来了额外的配置成本，同一份目标环境信息需要在多个位置重复声明。</p>
<p>Rspack 2.0 对此进行了改进，内置的 loaders 和压缩插件会默认解析顶层的 <code>target</code> 配置，并据此推断各自需要的目标环境设置。多数情况下，你只需要在顶层声明一次目标环境，就能让 JavaScript 代码转换、CSS 转换和代码压缩保持一致。</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables has-diff" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  target</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;browserslist: Chrome &gt;= 100&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  module</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    rules</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        test</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> /\.js</span><span style="color:var(--shiki-token-keyword)">$</span><span style="color:var(--shiki-token-string-expression)">/</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        use</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">            loader</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;builtin:swc-loader&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">            options</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line diff remove"><span style="color:var(--shiki-foreground)">              env</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> { targets</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;Chrome &gt;= 100&#x27;</span><span style="color:var(--shiki-foreground)"> }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">            }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        ]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    ]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  optimization</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    minimizer</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">      new</span><span style="color:var(--shiki-token-constant)"> rspack</span><span style="color:var(--shiki-token-function)">.SwcJsMinimizerRspackPlugin</span><span style="color:var(--shiki-foreground)">()</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">      new</span><span style="color:var(--shiki-token-constant)"> rspack</span><span style="color:var(--shiki-token-function)">.LightningCssMinimizerRspackPlugin</span><span style="color:var(--shiki-foreground)">({</span></span>
<span class="line diff remove"><span style="color:var(--shiki-foreground)">        minimizerOptions</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> { targets</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;Chrome &gt;= 100&#x27;</span><span style="color:var(--shiki-foreground)"> }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      })</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    ]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<blockquote>
<p>查看 <a href="/zh/config/target#目标环境继承" class="rp-link">target - 目标环境继承</a> 了解更多。</p>
</blockquote>
<h3 class="rp-toc-include" id="detect-syntax"><a href="#detect-syntax" class="rp-header-anchor rp-link" aria-hidden="true">#</a>简化 swc-loader 配置</h3>
<p>在以往的配置中，如果希望 <a href="/zh/guide/features/builtin-swc-loader" class="rp-link">builtin:swc-loader</a> 同时处理 <code>.js</code>、<code>.jsx</code>、<code>.ts</code>、<code>.tsx</code> 等文件，需要根据文件类型显式指定 <code>jsc.parser</code> 中的 <code>syntax</code>、<code>jsx</code>、<code>tsx</code> 等选项，以确保 SWC 能以正确的语义解析代码，例如判断 <code>&lt;</code> 应被解析为 JSX 语法还是 TypeScript 泛型。</p>
<p>这带来了一定的配置复杂度。为了让 SWC 正确解析不同后缀的文件，通常需要定义多条 <code>rules</code>，导致配置变得冗长，不利于维护。</p>
<p>为了解决这一问题，Rspack 2.0 在内置的 <code>swc-loader</code> 中引入了 <a href="/zh/guide/features/builtin-swc-loader#detectsyntax" class="rp-link">detectSyntax</a> 选项。启用 <code>detectSyntax: &#x27;auto&#x27;</code> 后，loader 会根据文件扩展名自动推断 <code>syntax</code>、<code>jsx</code>、<code>tsx</code> 等 <code>parser</code> 选项。通过一条规则即可覆盖不同的文件类型，使配置更清晰。</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  module</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    rules</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        test</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> /\.(?:js</span><span style="color:var(--shiki-token-keyword)">|</span><span style="color:var(--shiki-token-string-expression)">mjs</span><span style="color:var(--shiki-token-keyword)">|</span><span style="color:var(--shiki-token-string-expression)">jsx</span><span style="color:var(--shiki-token-keyword)">|</span><span style="color:var(--shiki-token-string-expression)">ts</span><span style="color:var(--shiki-token-keyword)">|</span><span style="color:var(--shiki-token-string-expression)">tsx)</span><span style="color:var(--shiki-token-keyword)">$</span><span style="color:var(--shiki-token-string-expression)">/</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        use</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          loader</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;builtin:swc-loader&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          options</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">            detectSyntax</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;auto&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    ]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h3 class="rp-toc-include" id="resolve-import"><a href="#resolve-import" class="rp-header-anchor rp-link" aria-hidden="true">#</a>支持控制 CSS 导入</h3>
<p>Rspack 2.0 的 CSS 解析器提供了 <a href="/zh/config/module#moduleparsercssautoresolveimport" class="rp-link"><code>resolveImport</code></a> 选项，它用于控制构建时是否解析并内联 <code>@import</code>。</p>
<p>默认情况下，Rspack 会解析 <code>@import</code>，并将导入的内容直接合并到当前文件中。你也可以将 <code>resolveImport</code> 设为 <code>false</code>，保留原始的 <code>@import</code>，交由浏览器或下游工具处理。</p>
<p><code>resolveImport</code> 还支持传入函数，用来按需决定每一条 <code>@import</code> 是否需要内联。例如，你可以只内联文件名包含 <code>style.css</code> 的导入，其他导入则保留原样：</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  module</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    parser</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-token-string-expression)">      &#x27;css/auto&#x27;</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-token-function)">        resolveImport</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> ({ url }) </span><span style="color:var(--shiki-token-keyword)">=&gt;</span><span style="color:var(--shiki-token-constant)"> url</span><span style="color:var(--shiki-token-function)">.includes</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">&#x27;style.css&#x27;</span><span style="color:var(--shiki-foreground)">)</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h3 class="rp-toc-include" id="hashed-module-ids-plugin"><a href="#hashed-module-ids-plugin" class="rp-header-anchor rp-link" aria-hidden="true">#</a>使用哈希作为模块 ID</h3>
<p>Rspack 2.0 为 <a href="/zh/config/optimization#optimizationmoduleids" class="rp-link">optimization.moduleIds</a> 新增了 <code>hashed</code> 选项。启用后，Rspack 会基于模块路径生成较短且稳定的哈希值，并将其用作模块 ID。</p>
<p>这适用于希望在保持模块 ID 稳定性的同时，进一步缩短模块 ID 长度的场景。对于模块数量较多的大型应用，这在某些情况下也有助于减少产物中模块 ID 占用的体积。</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  optimization</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    moduleIds</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;hashed&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h3 class="rp-toc-include" id="enforce-size-threshold"><a href="#enforce-size-threshold" class="rp-header-anchor rp-link" aria-hidden="true">#</a>代码分割改进</h3>
<p>Rspack 2.0 现在支持 <a href="/zh/plugins/webpack/split-chunks-plugin#splitchunksenforcesizethreshold" class="rp-link"><code>splitChunks.enforceSizeThreshold</code></a> 选项，用于为代码分割设置一个强制生效的体积阈值。</p>
<p>默认情况下，<code>splitChunks</code> 中的请求数限制选项，例如 <a href="/zh/plugins/webpack/split-chunks-plugin#splitchunksmaxasyncrequests" class="rp-link">maxAsyncRequests</a> 和 <a href="/zh/plugins/webpack/split-chunks-plugin#splitchunksmaxinitialrequests" class="rp-link">maxInitialRequests</a>，可能会阻止较大的 chunk 继续拆分。在启用 <code>enforceSizeThreshold</code> 后，只要模块组的体积超过设定阈值，Rspack 就会忽略这些限制并进行强制拆分。</p>
<p>在生产模式下，Rspack 默认会为所有模块类型设置 <code>50000</code> 字节的 <code>enforceSizeThreshold</code>，其他模式下默认值为 <code>30000</code> 字节。你也可以根据需要自行调整这个选项：</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  optimization</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    splitChunks</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-token-comment)">      // 对所有模块类型生效</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      enforceSizeThreshold</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> 50000</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-token-comment)">      // 也可以按模块类型分别配置</span></span>
<span class="line"><span style="color:var(--shiki-token-comment)">      // enforceSizeThreshold: { javascript: 50000, css: 30000 },</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>该选项也支持在 cache group 中单独配置，以便为特定的 cache group 指定不同的值。</p>
<h2 class="rp-toc-include" id="尝试-20"><a href="#尝试-20" class="rp-header-anchor rp-link" aria-hidden="true">#</a>尝试 2.0</h2>
<h3 class="rp-toc-include" id="创建新项目"><a href="#创建新项目" class="rp-header-anchor rp-link" aria-hidden="true">#</a>创建新项目</h3>
<p>如果你是首次使用 Rspack，推荐直接创建 <a href="https://rsbuild.rs/" target="_blank" rel="noopener noreferrer" class="rp-link">Rsbuild</a> 项目，它是一个由 Rspack 驱动、开箱即用的构建工具：</p>
<div class="rp-codeblock language-bash"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="bash"><code><span class="line"><span style="color:var(--shiki-token-function)">npm</span><span style="color:var(--shiki-token-string)"> create</span><span style="color:var(--shiki-token-string)"> rsbuild@latest</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<blockquote>
<p>查看 <a href="/zh/guide/start/quick-start" class="rp-link">快速上手</a> 了解更多。</p>
</blockquote>
<h3 class="rp-toc-include" id="从-v1-升级"><a href="#从-v1-升级" class="rp-header-anchor rp-link" aria-hidden="true">#</a>从 v1 升级</h3>
<p>Rspack 2.0 包含一些不兼容变更。对于现有项目，我们提供了 <a href="/zh/guide/migration/rspack_1.x" class="rp-link">升级指南</a>，其中包含从 v1 升级到 v2 的所有不兼容变更，以及对应的迁移方式。</p>
<p>如果你正在使用支持 Skills 的 Coding Agent，可以安装下面的 Skill，让 Agent 协助完成迁移；这种方式通常比手动升级更高效。</p>
<div class="rp-codeblock language-bash"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="bash"><code><span class="line"><span style="color:var(--shiki-token-function)">npx</span><span style="color:var(--shiki-token-string)"> skills</span><span style="color:var(--shiki-token-string)"> add</span><span style="color:var(--shiki-token-string)"> rstackjs/agent-skills</span><span style="color:var(--shiki-token-string)"> --skill</span><span style="color:var(--shiki-token-string)"> rspack-v2-upgrade</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h2 class="rp-toc-include" id="展望未来"><a href="#展望未来" class="rp-header-anchor rp-link" aria-hidden="true">#</a>展望未来</h2>
<p>Rspack 2.0 标志着一个新的演进阶段。相比 1.0，我们已经在性能、API 设计和产物形态上做出了一系列改进。接下来，我们会继续从多个方向推进 Rspack 的演进，包括产物优化、Agent 支持和工具链协同等：</p>
<ul>
<li><strong>产物优化</strong>：Rspack 的目标不仅是更快地完成构建，也是在保证行为稳定的前提下生成质量更高的产物。我们会继续改进 tree shaking、代码分割和静态分析等基础能力，探索结合静态类型信息进行优化分析，并提供更细粒度的代码拆分与优化选项。</li>
<li><strong>Agent 友好</strong>：随着 Coding Agent 逐渐成为开发工具的重要使用者，我们也会在设计中更多考虑这类场景，让 Agent 更容易理解和处理构建问题。例如，通过 CLI 向 Agent 提供更丰富的调试信息、性能数据和其他上下文，帮助它更准确地分析问题并参与问题排查和性能优化。</li>
<li><strong>工具链协同</strong>：在实际项目中，耗时往往不只来自打包本身，测试、类型检查和代码检查等环节同样会带来明显开销。我们会继续推进 Rstack 工具链的协同演进，并与 typescript-go 结合。例如，Rslint 已支持 <a href="https://rslint.rs/guide/type-checking" target="_blank" rel="noopener noreferrer" class="rp-link"><code>rslint --type-check</code></a>，可同时执行代码检查和类型检查。后续我们也会在 <a href="https://github.com/rstackjs/ts-checker-rspack-plugin" target="_blank" rel="noopener noreferrer" class="rp-link"><code>ts-checker-rspack-plugin</code></a> 中支持 typescript-go。</li>
</ul>
<blockquote>
<p>查看 <a href="/zh/misc/planning/roadmap" class="rp-link">Rspack 路线图</a> 了解更多。</p>
</blockquote>
<h2 class="rp-toc-include" id="faq"><a href="#faq" class="rp-header-anchor rp-link" aria-hidden="true">#</a>常见问题</h2>
<h3 class="rp-toc-include" id="rspack-20-还兼容-webpack-吗"><a href="#rspack-20-还兼容-webpack-吗" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rspack 2.0 还兼容 webpack 吗？</h3>
<p>会。进入 2.0 阶段后，Rspack 仍然会把与 webpack 生态的兼容性作为重要目标。</p>
<p>随着 JavaScript 标准的发展，Rspack 也会更积极地引入更合理的默认行为和 API 设计，这会是一个渐进的过程。</p>
<h3 class="rp-toc-include" id="1x-版本还会继续维护吗"><a href="#1x-版本还会继续维护吗" class="rp-header-anchor rp-link" aria-hidden="true">#</a>1.x 版本还会继续维护吗？</h3>
<p>会。2.0 发布后，对于 1.x 版本，我们仍会在一段时间内继续提供维护支持，例如关键问题修复和迁移支持。但后续的新特性和优化会优先在 2.x 上实现，因此我们建议尽快升级至 2.x。</p>
<h3 class="rp-toc-include" id="rspack-生态什么时候升级到-20"><a href="#rspack-生态什么时候升级到-20" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rspack 生态什么时候升级到 2.0？</h3>
<p>Rsbuild 2.0 已经与 Rspack 2.0 同步发布，查看 <a href="https://rsbuild.rs/zh/blog/v2-0" target="_blank" rel="noopener noreferrer" class="rp-link">Rsbuild 2.0 博客</a> 了解更多。</p>
<p>Rslib、Rstest 和 Rspress 也会在随后升级到 Rspack 2.0 正式版。与此同时，我们也会持续协助社区中的框架和工具完成对 Rspack 2.0 的升级与适配。</p>
<h2 class="rp-toc-include" id="致谢"><a href="#致谢" class="rp-header-anchor rp-link" aria-hidden="true">#</a>致谢</h2>
<p>感谢所有 Rspack 的用户、贡献者和合作伙伴。每一条反馈和参与，都在推动 Rspack 生态的发展。我们也希望 Rspack 能为 JavaScript 生态的发展持续贡献力量。</p>
<p>感谢社区中各个打包工具的开发团队，包括 esbuild、Parcel、Rollup、Rolldown、Turbopack 和 webpack。正是因为这些项目在不同方向上的持续探索，许多想法才得以相互启发，并最终得以实现。</p><!--/$-->]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Rspack 1.7 发布公告]]></title>
            <link>https://rspack.rs/zh/blog/announcing-1-7</link>
            <guid isPermaLink="false">/zh/blog/announcing-1-7</guid>
            <pubDate>Wed, 31 Dec 2025 16:00:00 GMT</pubDate>
            <description><![CDATA[Rspack 1.7 版本发布，提升了 SWC Wasm 插件兼容性，支持 Import Bytes 资源导入，并将多项实验特性稳定化。]]></description>
            <content:encoded><![CDATA[<!--$--><p><em>2025 年 12 月 31 日</em></p>
<h1 class="rp-toc-include" id="rspack-17-发布公告"><a href="#rspack-17-发布公告" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rspack 1.7 发布公告<!-- --> </h1><div class="rp-not-doc rp-llms-container"><button class="rp-not-doc rp-llms-button rp-llms-copy-button"><div class="rp-llms-copy-button__icon-wrapper"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-llms-copy-button__icon-success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-llms-copy-button__icon-copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg></div><span>复制 Markdown</span></button><button class="rp-llms-button rp-llms-view-options__trigger "><svg width="1em" height="1em" viewBox="0 0 32 32" class="rp-llms-view-options__arrow "><path fill="currentColor" d="M16 22 6 12l1.4-1.4 8.6 8.6 8.6-8.6L26 12z"></path></svg></button></div>
<p><img src="https://assets.rspack.rs/rspack/rspack-banner-v1-7.png" alt="Rspack 1.7"/></p>
<hr/>
<p>我们很高兴地宣布 Rspack 1.7 已正式发布！这是 Rspack 1.x 的最后一个 minor 版本，主要聚焦于现有功能的稳定性改进。接下来，我们将很快带来 Rspack 2.0。</p>
<p>值得关注的变更如下：</p>
<ul>
<li>新特性<!-- -->
<ul>
<li><a href="#swc-%E6%8F%92%E4%BB%B6%E5%85%BC%E5%AE%B9%E6%80%A7%E6%8F%90%E5%8D%87" class="rp-link">SWC 插件兼容性提升</a></li>
<li><a href="#%E6%94%AF%E6%8C%81-import-bytes" class="rp-link">支持 Import Bytes</a></li>
<li><a href="#lazy-compilation" class="rp-link">Lazy compilation</a></li>
<li><a href="#%E5%AE%9E%E9%AA%8C%E7%89%B9%E6%80%A7%E7%A8%B3%E5%AE%9A%E5%8C%96" class="rp-link">实验特性稳定化</a></li>
</ul>
</li>
<li>Rstack 进展<!-- -->
<ul>
<li><a href="#rsbuild-17" class="rp-link">Rsbuild 1.7</a></li>
<li><a href="#rsdoctor-14" class="rp-link">Rsdoctor 1.4</a></li>
<li><a href="#rslib-019" class="rp-link">Rslib 0.19</a></li>
<li><a href="#rstest-07" class="rp-link">Rstest 0.7</a></li>
<li><a href="#rspress-20-rc" class="rp-link">Rspress 2.0 RC</a></li>
</ul>
</li>
</ul>
<h2 class="rp-toc-include" id="新特性"><a href="#新特性" class="rp-header-anchor rp-link" aria-hidden="true">#</a>新特性</h2>
<h3 class="rp-toc-include" id="swc-插件兼容性提升"><a href="#swc-插件兼容性提升" class="rp-header-anchor rp-link" aria-hidden="true">#</a>SWC 插件兼容性提升</h3>
<p>在过去的版本中，SWC Wasm 插件的升级成本一直较高。这是由于 SWC 的 AST 结构会随着版本演进发生变化，已有插件在 SWC 升级后可能无法继续工作，插件作者需要进行适配，插件使用者也需要同步升级依赖，这在一定程度上影响了项目的稳定性和升级体验。</p>
<p>为缓解这一问题，我们向 SWC 社区贡献了一系列 <a href="https://swc.rs/docs/plugin/ecmascript/compatibility" target="_blank" rel="noopener noreferrer" class="rp-link">兼容性改进</a>，包括：</p>
<ul>
<li>使用自描述式的 <a href="https://www.rfc-editor.org/rfc/rfc8949.html" target="_blank" rel="noopener noreferrer" class="rp-link">cbor</a> 序列化方案，取代原先对版本敏感的 <a href="https://rkyv.org/" target="_blank" rel="noopener noreferrer" class="rp-link">rkyv</a>，使 Wasm 插件能更好地适应 AST 结构的变更</li>
<li>为 AST 中的枚举类型引入 <code>Unknown</code> 变体，从而在遇到新字段或新节点时提升容错能力</li>
</ul>
<p>在 Rspack 1.7 中，我们升级了使用的 SWC 版本并支持了上述方案。在此之后，多数场景下 SWC 的升级将不会影响基于旧版本 SWC 构建的插件的正常使用。</p>
<p>目前，该方案已在大部分流行的 SWC Wasm 插件中完成接入。如果你是 SWC Wasm 插件作者，可参考 <a href="https://swc.rs/docs/plugin/ecmascript/compatibility#make-your-plugin-compatible" target="_blank" rel="noopener noreferrer" class="rp-link">官方指南</a>，接入该方案，以降低后续版本演进中的维护成本。</p>
<h3 class="rp-toc-include" id="支持-import-bytes"><a href="#支持-import-bytes" class="rp-header-anchor rp-link" aria-hidden="true">#</a>支持 Import bytes</h3>
<p>Rspack 现已原生支持 <a href="https://github.com/tc39/proposal-import-bytes" target="_blank" rel="noopener noreferrer" class="rp-link">Import Bytes</a> 提案，可以将静态资源作为 <code>Uint8Array</code> 导入，并通过 <code>TextDecoder</code> 解码。</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js"><code><span class="line"><span style="color:var(--shiki-token-comment)">// 静态导入</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> fileBytes </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;./file.bin&#x27;</span><span style="color:var(--shiki-token-keyword)"> with</span><span style="color:var(--shiki-foreground)"> { type</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;bytes&#x27;</span><span style="color:var(--shiki-foreground)"> };</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">const</span><span style="color:var(--shiki-token-constant)"> decoder</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-keyword)"> new</span><span style="color:var(--shiki-token-function)"> TextDecoder</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">&#x27;utf-8&#x27;</span><span style="color:var(--shiki-foreground)">);</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">const</span><span style="color:var(--shiki-token-constant)"> text</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-constant)"> decoder</span><span style="color:var(--shiki-token-function)">.decode</span><span style="color:var(--shiki-foreground)">(fileBytes);</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-comment)">// 动态导入</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">const</span><span style="color:var(--shiki-token-constant)"> module</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-keyword)"> await</span><span style="color:var(--shiki-token-keyword)"> import</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">&#x27;./file.bin&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> { with</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> { type</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;bytes&#x27;</span><span style="color:var(--shiki-foreground)"> } });</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">const</span><span style="color:var(--shiki-token-constant)"> decoder</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-keyword)"> new</span><span style="color:var(--shiki-token-function)"> TextDecoder</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">&#x27;utf-8&#x27;</span><span style="color:var(--shiki-foreground)">);</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">const</span><span style="color:var(--shiki-token-constant)"> text</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-constant)"> decoder</span><span style="color:var(--shiki-token-function)">.decode</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-constant)">module</span><span style="color:var(--shiki-foreground)">.default);</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h3 class="rp-toc-include" id="lazy-compilation"><a href="#lazy-compilation" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Lazy compilation</h3>
<p>在 Rspack 1.5 中，我们完成了 <a href="/zh/guide/features/lazy-compilation" class="rp-link">Lazy Compilation</a> 特性的稳定化，并在 Rsbuild 中默认对动态导入的模块启用了按需编译。</p>
<p>从 Rspack 1.7 开始，Rspack CLI 在构建 web 应用时也将默认对动态导入的模块启用按需编译。这一改进可以减少首次构建的模块数量，从而加快开发服务器的启动速度。</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-token-comment)">  // 当前默认配置</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  lazyCompilation</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    imports</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> true</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    entries</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> false</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>如果你有特殊需求，例如需要调试完整构建的产物，或分析完整的模块图，可以通过将 <a href="/zh/config/lazy-compilation" class="rp-link">lazyCompilation</a> 设置为 <code>false</code> 来显式关闭该功能。</p>
<h3 class="rp-toc-include" id="实验特性稳定化"><a href="#实验特性稳定化" class="rp-header-anchor rp-link" aria-hidden="true">#</a>实验特性稳定化</h3>
<p>在 Rspack 1.7 中，我们稳定化了多项实验性特性。以下能力已完成生产验证并进入稳定阶段，相关实验开关也随之废弃，或调整为默认行为：</p>
<ul>
<li><strong>常量内联优化</strong>：该优化已正式稳定，并在生产构建中默认启用。<!-- -->
<ul>
<li>原有的 <a href="/zh/config/deprecated-options#experimentsinlineconst" class="rp-link">experiments.inlineConst</a> 选项已废弃</li>
<li>如需关闭该行为，可通过 <a href="/zh/config/optimization#optimizationinlineexports" class="rp-link">optimization.inlineExports</a> 来控制</li>
</ul>
</li>
<li><strong>TypeScript enum 内联优化</strong>：该优化已正式稳定。<!-- -->
<ul>
<li>原有的 <a href="/zh/config/deprecated-options#experimentsinlineenum" class="rp-link">experiments.inlineEnum</a> 选项已废弃</li>
<li>使用 <a href="/zh/guide/features/builtin-swc-loader#collecttypescriptinfoexportedenum" class="rp-link">collectTypeScriptInfo.exportedEnum</a> 控制是否收集导出的 <code>enum</code> 信息</li>
<li>使用 <a href="/zh/config/optimization#optimizationinlineexports" class="rp-link">optimization.inlineExports</a> 来控制是否内联 <code>enum</code></li>
</ul>
</li>
<li><strong>类型重导出检查</strong>：该优化已正式稳定。<!-- -->
<ul>
<li>原有的 <a href="/zh/config/deprecated-options#experimentstypereexportspresence" class="rp-link">experiments.typeReexportsPresence</a> 选项已废弃</li>
</ul>
</li>
</ul>
<blockquote>
<p>参考 <a href="#%E5%8D%87%E7%BA%A7%E6%8C%87%E5%8D%97" class="rp-link">升级指南</a> 了解如何调整相关配置。</p>
</blockquote>
<h2 class="rp-toc-include" id="rstack-进展"><a href="#rstack-进展" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rstack 进展</h2>
<h3 class="rp-toc-include" id="rsbuild-17"><a href="#rsbuild-17" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rsbuild 1.7</h3>
<h4 class="rp-toc-include" id="error-overlay-改进"><a href="#error-overlay-改进" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Error overlay 改进</h4>
<p>Rsbuild 的 error overlay 现在支持显示<strong>运行时错误</strong>。当应用在运行过程中抛出异常时，错误会直接渲染到 overlay 上，帮助你更快发现并定位问题。</p>
<p><img src="https://assets.rspack.rs/rspack/assets/rspack-v1-7-rsbuild-error-overlay.png" alt="Rsbuild 1.7 Error Overlay"/></p>
<p>该功能默认关闭，可通过 <a href="https://rsbuild.rs/zh/config/dev/client#overlayruntime" target="_blank" rel="noopener noreferrer" class="rp-link">dev.client.overlay.runtime</a> 选项按需开启：</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rsbuild.config.ts</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rsbuild.config.ts"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  dev</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    client</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      overlay</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        runtime</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> true</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h4 class="rp-toc-include" id="产物体积对比"><a href="#产物体积对比" class="rp-header-anchor rp-link" aria-hidden="true">#</a>产物体积对比</h4>
<p>Rsbuild 现在支持输出产物体积对比，用来查看构建结果是否发生了体积变化。</p>
<p><img src="https://assets.rspack.rs/rspack/assets/rspack-v1-7-rsbuild-print-size-diff.png" alt="Rsbuild 1.7 Print Size Diff"/></p>
<p>开启 <a href="https://rsbuild.rs/zh/config/performance/print-file-size#diff" target="_blank" rel="noopener noreferrer" class="rp-link">performance.printFileSize.diff</a> 选项后，Rsbuild 构建完成时会记录一份产物体积快照，后续构建会自动与上一次结果对比，并在日志中直接展示体积变化。你可以清楚地看到每个文件是变大还是变小，以及整体体积的增减情况，适合在日常开发和性能回归中快速发现体积变化。</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rsbuild.config.ts</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rsbuild.config.ts"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  performance</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    printFileSize</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      diff</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> true</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h4 class="rp-toc-include" id="create-rsbuild-改进"><a href="#create-rsbuild-改进" class="rp-header-anchor rp-link" aria-hidden="true">#</a>create-rsbuild 改进</h4>
<p><code>create-rsbuild</code> 现在包含了更多开箱即用的工具。</p>
<p>在创建 Rsbuild 项目时，你现在可以选择自动集成 <a href="https://rstest.rs/" target="_blank" rel="noopener noreferrer" class="rp-link">Rstest</a> 作为测试框架，或启用 <a href="https://storybook.rsbuild.rs/" target="_blank" rel="noopener noreferrer" class="rp-link">Storybook</a> 用于 UI 组件的开发与调试。相关依赖和配置都会在初始化时一次性完成，减少重复的手动配置成本。</p>
<div class="rp-codeblock language-text"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="text"><code><span class="line"><span>◆  Select additional tools (Use &lt;space&gt; to select, &lt;enter&gt; to continue)</span></span>
<span class="line"><span>│  ◼ Rstest - testing</span></span>
<span class="line"><span>│  ◻ Biome - linting &amp; formatting</span></span>
<span class="line"><span>│  ◻ ESLint - linting</span></span>
<span class="line"><span>│  ◻ Prettier - formatting</span></span>
<span class="line"><span>│  ◻ Storybook - component development</span></span>
<span class="line"><span>└</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h3 class="rp-toc-include" id="rsdoctor-14"><a href="#rsdoctor-14" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rsdoctor 1.4</h3>
<h4 class="rp-toc-include" id="新的-treemap-视图"><a href="#新的-treemap-视图" class="rp-header-anchor rp-link" aria-hidden="true">#</a>新的 Treemap 视图</h4>
<p>Rsdoctor 1.4 对原有的 <a href="https://rsdoctor.rs/zh/guide/usage/bundle-size" target="_blank" rel="noopener noreferrer" class="rp-link">Treemap</a> 视图进行了改进。新的交互设计可以帮助你更直观地分析 bundle 的整体构成，以及各类资源和模块的体积占比。</p>
<p>在该视图中，你可以通过搜索快速定位到具体的模块或资源。点击某个模块或资源后，视图会自动聚焦并放大对应区域。双击模块还可以展开其依赖链路，逐层查看模块之间的引用关系，从而更清晰地分析体积来源。</p>
<p><img src="https://assets.rspack.rs/rspack/assets/rspack-v1-7-rsdoctor-treemap.gif" alt="Rsdoctor Treemap"/></p>
<h3 class="rp-toc-include" id="rslib-019"><a href="#rslib-019" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rslib 0.19</h3>
<h4 class="rp-toc-include" id="esm-产物稳定化"><a href="#esm-产物稳定化" class="rp-header-anchor rp-link" aria-hidden="true">#</a>ESM 产物稳定化</h4>
<p>在此前的版本中，Rslib 通过实验性配置 <a href="https://rslib.rs/zh/config/lib/experiments#experimentsadvancedesm" target="_blank" rel="noopener noreferrer" class="rp-link">experiments.advancedEsm</a> 来启用 Rspack 的 <a href="https://v1.rspack.rs/plugins/rspack/esm-library-plugin" target="_blank" rel="noopener noreferrer" class="rp-link">新版 ESM 库产物</a>，用于提升 ESM 产物的整体质量。经过多个版本的验证与打磨，该能力现已完成稳定化。</p>
<p>自 Rslib 0.19 起，Rslib 的 bundle 模式将默认启用该特性。开发者无需进行任何额外配置，即可直接获得对静态分析更友好、并完整支持代码分割的 ESM 产物。</p>
<h4 class="rp-toc-include" id="javascript-api"><a href="#javascript-api" class="rp-header-anchor rp-link" aria-hidden="true">#</a>JavaScript API</h4>
<p>Rslib 0.19 引入了 <a href="https://rslib.rs/api/start" target="_blank" rel="noopener noreferrer" class="rp-link">JavaScript API</a>，使开发者可以在 JavaScript 代码中以编程方式直接调用 Rslib 的构建能力。</p>
<p>下面是一个基础示例：</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { createRslib } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;@rslib/core&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-comment)">// 创建 Rslib 实例</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">const</span><span style="color:var(--shiki-token-constant)"> rslib</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-keyword)"> await</span><span style="color:var(--shiki-token-function)"> createRslib</span><span style="color:var(--shiki-foreground)">();</span></span>
<span class="line"><span style="color:var(--shiki-token-comment)">// 构建生产环境输出</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">await</span><span style="color:var(--shiki-token-constant)"> rslib</span><span style="color:var(--shiki-token-function)">.build</span><span style="color:var(--shiki-foreground)">();</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<blockquote>
<p>更多使用方式请参考 <a href="https://rslib.rs/api/javascript-api/core" target="_blank" rel="noopener noreferrer" class="rp-link">API 文档</a>。</p>
</blockquote>
<h3 class="rp-toc-include" id="rstest-07"><a href="#rstest-07" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rstest 0.7</h3>
<h4 class="rp-toc-include" id="配置适配器"><a href="#配置适配器" class="rp-header-anchor rp-link" aria-hidden="true">#</a>配置适配器</h4>
<p>Rstest 0.7 引入了 <a href="https://rstest.rs/zh/config/test/extends" target="_blank" rel="noopener noreferrer" class="rp-link">extends</a> 选项和适配器机制，用于直接复用现有的工具或框架配置。适配器是一个配置转换函数，可以将其他工具的配置转换为 Rstest 的配置，从而降低 Rstest 的集成成本。</p>
<p>例如，在一个使用 Rslib 的库项目中，通过 <a href="https://www.npmjs.com/package/@rstest/adapter-rslib" target="_blank" rel="noopener noreferrer" class="rp-link">@rstest/adapter-rslib</a> 适配器，你可以直接复用已有的 Rslib 配置：</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rstest.config.ts</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rstest.config.ts"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { defineConfig } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;@rstest/core&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { withRslibConfig } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;@rstest/adapter-rslib&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-token-function)"> defineConfig</span><span style="color:var(--shiki-foreground)">({</span></span>
<span class="line"><span style="color:var(--shiki-token-comment)">  // 自动读取 rslib.config.ts 并转换为 Rstest 配置</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  extends</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-function)"> withRslibConfig</span><span style="color:var(--shiki-foreground)">()</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-token-comment)">  // 其他测试配置</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  coverage</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-token-comment)">    // ...</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">});</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>适配器则负责将不同工具的配置转换为 Rstest 的配置（如 <code>define</code>、<code>alias</code> 等），而 <code>extends</code> 则负责将转换后的配置与 Rstest 的配置进行合并。通过二者的配合，任何基于 Rspack 的工具或框架，都可以以最小成本与 Rstest 集成。</p>
<p>目前 <code>@rstest/adapter-rslib</code> 适配器已正式发布，后续我们还将推出更多适配器，以对接 Rstack 的各个工具。你也可以参考 <a href="https://rstest.rs/zh/guide/integration/adapters" target="_blank" rel="noopener noreferrer" class="rp-link">Rstest - 适配器</a> 来编写自定义的适配器。</p>
<h4 class="rp-toc-include" id="测试反馈优化"><a href="#测试反馈优化" class="rp-header-anchor rp-link" aria-hidden="true">#</a>测试反馈优化</h4>
<p>Rstest 针对本地开发与调试场景进行了多项体验优化，让测试反馈更加直观：</p>
<ul>
<li>
<p><strong>更早发现卡住的测试:</strong> Rstest 现已支持在本地运行时标记长时间未完成的测试用例。当测试过程变慢时，你可以直接看到是哪个用例正在执行、可能已经卡住，而不再只能盯着终端等待整个测试超时结束。</p>
</li>
<li>
<p><strong>更清晰的超时失败反馈:</strong> 当测试因超时失败时，Rstest 现在会在错误信息中展示已执行的断言数量。这能帮助你快速判断测试是否已经部分执行，或是卡在了某个异步逻辑中，从而更快定位问题。</p>
</li>
</ul>
<h3 class="rp-toc-include" id="rspress-20-rc"><a href="#rspress-20-rc" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rspress 2.0 RC</h3>
<h4 class="rp-toc-include" id="ssg-md-特性"><a href="#ssg-md-特性" class="rp-header-anchor rp-link" aria-hidden="true">#</a>SSG-MD 特性</h4>
<p>在基于 React 动态渲染的前端框架中，往往存在静态信息难以提取的问题，Rspress 也遇到了相同的问题。Rspress 允许用户通过 <a href="https://v2.rspress.rs/zh/guide/use-mdx/components" target="_blank" rel="noopener noreferrer" class="rp-link">MDX 片段</a>、React 组件、Hooks 以及 TSX 路由等动态特性来增强文档表现力。但这些动态内容在转换为 Markdown 文本时会面临以下问题：</p>
<ul>
<li>直接将 MDX 输入给 AI 会包含大量代码语法噪音，并丢失 React 组件内容</li>
<li>将 SSG 生成的 HTML 转为 Markdown 往往效果不佳，信息质量难以保证</li>
</ul>
<p>为了解决这个问题，Rspress 2.0 引入了 <a href="https://v2.rspress.rs/zh/guide/basic/ssg-md" target="_blank" rel="noopener noreferrer" class="rp-link">SSG-MD</a> 特性。这是一个全新的功能，见名知意，与 <a href="https://v2.rspress.rs/zh/guide/basic/ssg" target="_blank" rel="noopener noreferrer" class="rp-link">静态站点生成（SSG）</a> 唯一的不同在于它将你的页面渲染为 Markdown 文件，而非 HTML 文件，并生成 <a href="https://llmstxt.org/" target="_blank" rel="noopener noreferrer" class="rp-link">llms.txt</a> 及 llms-full.txt 相关文件。相比与将 HTML 转化为 Markdown 等传统方式，SSG-MD 在渲染期间拥有更好的信息源，比如 React 虚拟 DOM，因此拥有更好的静态信息质量和灵活性。</p>
<p>启用方式非常简单：</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspress.config.ts</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspress.config.ts"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { defineConfig } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;@rspress/core&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-token-function)"> defineConfig</span><span style="color:var(--shiki-foreground)">({</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  llms</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> true</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">});</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>构建后将生成如下结构：</p>
<div class="rp-codeblock language-txt"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="txt"><code><span class="line"><span>doc_build</span></span>
<span class="line"><span>├── llms.txt          # 摘要版，包含关键文档索引</span></span>
<span class="line"><span>├── llms-full.txt     # 完整版，包含所有文档内容</span></span>
<span class="line"><span>├── guide</span></span>
<span class="line"><span>│   └── start</span></span>
<span class="line"><span>│       └── introduction.md</span></span>
<span class="line"><span>└── ...</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>对于自定义组件，你可以通过环境变量来控制其在 SSG-MD 模式下的渲染行为：</p>
<div class="rp-codeblock language-tsx"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="tsx"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> function</span><span style="color:var(--shiki-token-function)"> Tab</span><span style="color:var(--shiki-foreground)">({ label }</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> { label</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> string</span><span style="color:var(--shiki-foreground)"> }) {</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">  if</span><span style="color:var(--shiki-foreground)"> (</span><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)">.</span><span style="color:var(--shiki-token-constant)">meta</span><span style="color:var(--shiki-foreground)">.</span><span style="color:var(--shiki-token-constant)">env</span><span style="color:var(--shiki-foreground)">.</span><span style="color:var(--shiki-token-constant)">SSG_MD</span><span style="color:var(--shiki-foreground)">) {</span></span>
<span class="line"><span style="color:var(--shiki-token-comment)">    // SSG-MD 模式下输出纯文本描述</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">    return</span><span style="color:var(--shiki-foreground)"> &lt;&gt;{</span><span style="color:var(--shiki-token-string-expression)">`**Tab: </span><span style="color:var(--shiki-token-keyword)">${</span><span style="color:var(--shiki-foreground)">label</span><span style="color:var(--shiki-token-keyword)">}</span><span style="color:var(--shiki-token-string-expression)">**`</span><span style="color:var(--shiki-foreground)">}&lt;/&gt;;</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span></span>
<span class="line"><span style="color:var(--shiki-token-comment)">  // 正常渲染交互式组件</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">  return</span><span style="color:var(--shiki-foreground)"> &lt;</span><span style="color:var(--shiki-token-string-expression)">div</span><span style="color:var(--shiki-token-function)"> className</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-token-string-expression)">&quot;tab&quot;</span><span style="color:var(--shiki-foreground)">&gt;{label}&lt;/</span><span style="color:var(--shiki-token-string-expression)">div</span><span style="color:var(--shiki-foreground)">&gt;;</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">}</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>这样既保证了文档的交互体验，也能帮助 AI 理解组件的语义信息。</p>
<blockquote>
<p>详见 <a href="https://v2.rspress.rs/zh/guide/basic/ssg-md" target="_blank" rel="noopener noreferrer" class="rp-link">SSG-MD 使用指南</a></p>
</blockquote>
<h2 class="rp-toc-include" id="升级指南"><a href="#升级指南" class="rp-header-anchor rp-link" aria-hidden="true">#</a>升级指南</h2>
<h3 class="rp-toc-include" id="升级-swc-插件"><a href="#升级-swc-插件" class="rp-header-anchor rp-link" aria-hidden="true">#</a>升级 SWC 插件</h3>
<p>如果你的项目中使用了 SWC Wasm 插件（如 <code>@swc/plugin-emotion</code> 等），请升级插件至兼容 <code>swc_core@54</code> 及以上版本，否则可能因版本不兼容导致构建失败或运行异常。</p>
<blockquote>
<p>详情请查阅：<a href="/zh/errors/swc-plugin-version" class="rp-link">常见问题 - SWC 插件版本不匹配</a>。</p>
</blockquote>
<h3 class="rp-toc-include" id="移除废弃配置"><a href="#移除废弃配置" class="rp-header-anchor rp-link" aria-hidden="true">#</a>移除废弃配置</h3>
<ul>
<li>以下实验性选项已废弃，可以直接移除：</li>
</ul>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables has-diff" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line diff remove"><span style="color:var(--shiki-foreground)">  experiments</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line diff remove"><span style="color:var(--shiki-foreground)">    inlineConst</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> true</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line diff remove"><span style="color:var(--shiki-foreground)">    inlineEnum</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> true</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line diff remove"><span style="color:var(--shiki-foreground)">    typeReexportsPresence</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> true</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<ul>
<li>调整 <code>builtin:swc-loader</code> 中的 <a href="/zh/guide/features/builtin-swc-loader#collecttypescriptinfo" class="rp-link">collectTypeScriptInfo</a> 选项位置，移除 <code>rspackExperiments</code> 层级：</li>
</ul>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables has-diff" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  module</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    rules</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        test</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> /\.ts</span><span style="color:var(--shiki-token-keyword)">$</span><span style="color:var(--shiki-token-string-expression)">/</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        loader</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;builtin:swc-loader&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        options</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line diff remove"><span style="color:var(--shiki-foreground)">          rspackExperiments</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">            collectTypeScriptInfo</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">              exportedEnum</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> true</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">              typeExports</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> true</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">            }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line diff remove"><span style="color:var(--shiki-foreground)">          }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    ]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div><!--/$-->]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Rspack 1.6 发布公告]]></title>
            <link>https://rspack.rs/zh/blog/announcing-1-6</link>
            <guid isPermaLink="false">/zh/blog/announcing-1-6</guid>
            <pubDate>Thu, 30 Oct 2025 16:00:00 GMT</pubDate>
            <description><![CDATA[Rspack 1.6 版本发布，带来了更好的 ESM 输出、增强 tree shaking 能力、支持 defer import 语法、稳定 layers 特性，以及默认启用 barrel 文件优化。]]></description>
            <content:encoded><![CDATA[<!--$--><p><em>2025 年 10 月 30 日</em></p>
<h1 class="rp-toc-include" id="rspack-16-发布公告"><a href="#rspack-16-发布公告" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rspack 1.6 发布公告<!-- --> </h1><div class="rp-not-doc rp-llms-container"><button class="rp-not-doc rp-llms-button rp-llms-copy-button"><div class="rp-llms-copy-button__icon-wrapper"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-llms-copy-button__icon-success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-llms-copy-button__icon-copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg></div><span>复制 Markdown</span></button><button class="rp-llms-button rp-llms-view-options__trigger "><svg width="1em" height="1em" viewBox="0 0 32 32" class="rp-llms-view-options__arrow "><path fill="currentColor" d="M16 22 6 12l1.4-1.4 8.6 8.6 8.6-8.6L26 12z"></path></svg></button></div>
<p><img src="https://assets.rspack.rs/rspack/rspack-banner-v1-6.png" alt="Rspack 1.6"/></p>
<hr/>
<p>我们很高兴地宣布 Rspack 1.6 已正式发布！</p>
<p>值得关注的变更如下：</p>
<ul>
<li>新特性<!-- -->
<ul>
<li><a href="#%E5%A2%9E%E5%BC%BA-tree-shaking" class="rp-link">增强 Tree shaking</a></li>
<li><a href="#%E6%94%AF%E6%8C%81-import-defer" class="rp-link">支持 import defer</a></li>
<li><a href="#%E4%BC%98%E5%8C%96-esm-%E4%BA%A7%E7%89%A9" class="rp-link">优化 ESM 产物</a></li>
<li><a href="#%E9%BB%98%E8%AE%A4%E5%90%AF%E7%94%A8-barrel-%E4%BC%98%E5%8C%96" class="rp-link">默认启用 barrel 优化</a></li>
<li><a href="#layers-%E7%89%B9%E6%80%A7%E7%A8%B3%E5%AE%9A" class="rp-link">layers 特性稳定</a></li>
<li><a href="#%E4%BF%9D%E7%95%99-jsx-%E8%AF%AD%E6%B3%95" class="rp-link">保留 JSX 语法</a></li>
<li><a href="#%E6%8F%90%E5%8F%96-source-map" class="rp-link">提取 source map</a></li>
<li><a href="#%E6%80%A7%E8%83%BD%E6%8F%90%E5%8D%87" class="rp-link">性能提升</a></li>
</ul>
</li>
<li>Rstack 进展<!-- -->
<ul>
<li><a href="#rsbuild-1-6" class="rp-link">Rsbuild 1.6</a></li>
<li><a href="#rspress-v2-beta" class="rp-link">Rspress v2 beta</a></li>
<li><a href="#rslib-0-16" class="rp-link">Rslib 0.16</a></li>
<li><a href="#rstest-0-6" class="rp-link">Rstest 0.6</a></li>
<li><a href="#rsdoctor-1-3" class="rp-link">Rsdoctor 1.3</a></li>
</ul>
</li>
<li>生态系统<!-- -->
<ul>
<li><a href="#next-rspack" class="rp-link">next-rspack</a></li>
</ul>
</li>
</ul>
<h2 class="rp-toc-include" id="新功能"><a href="#新功能" class="rp-header-anchor rp-link" aria-hidden="true">#</a>新功能</h2>
<h3 class="rp-toc-include" id="增强-tree-shaking"><a href="#增强-tree-shaking" class="rp-header-anchor rp-link" aria-hidden="true">#</a>增强 Tree shaking</h3>
<p>Rspack 1.6 增强了对动态导入 tree shaking 的支持。在此前的版本中，Rspack 仅能对动态导入中的解构赋值进行 tree shaking，而其他形式的导入则不会被分析。</p>
<p>现在，Rspack 为动态导入引入了更全面的静态分析，能够识别并处理多种使用模式，从而精准地移除未被使用的导出内容，进一步减小最终打包产物的体积。</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js"><code><span class="line"><span style="color:var(--shiki-token-comment)">// Rspack 1.5 - 仅支持分析解构赋值</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">const</span><span style="color:var(--shiki-foreground)"> { </span><span style="color:var(--shiki-token-constant)">value</span><span style="color:var(--shiki-foreground)"> } </span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-token-keyword)"> await</span><span style="color:var(--shiki-token-keyword)"> import</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">&#x27;./module&#x27;</span><span style="color:var(--shiki-foreground)">);</span></span>
<span class="line"><span style="color:var(--shiki-token-constant)">console</span><span style="color:var(--shiki-token-function)">.log</span><span style="color:var(--shiki-foreground)">(value);</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-comment)">// Rspack 1.6 - 支持分析以下情况</span></span>
<span class="line"><span style="color:var(--shiki-token-comment)">// Case 1</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">const</span><span style="color:var(--shiki-token-constant)"> mod</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-keyword)"> await</span><span style="color:var(--shiki-token-keyword)"> import</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">&#x27;./module&#x27;</span><span style="color:var(--shiki-foreground)">);</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">const</span><span style="color:var(--shiki-foreground)"> { </span><span style="color:var(--shiki-token-constant)">value</span><span style="color:var(--shiki-foreground)"> } </span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-foreground)"> mod;</span></span>
<span class="line"><span style="color:var(--shiki-token-constant)">console</span><span style="color:var(--shiki-token-function)">.log</span><span style="color:var(--shiki-foreground)">(value);</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-comment)">// Case 2</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">const</span><span style="color:var(--shiki-token-constant)"> mod</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-keyword)"> await</span><span style="color:var(--shiki-token-keyword)"> import</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">&#x27;./module&#x27;</span><span style="color:var(--shiki-foreground)">);</span></span>
<span class="line"><span style="color:var(--shiki-token-constant)">console</span><span style="color:var(--shiki-token-function)">.log</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-constant)">mod</span><span style="color:var(--shiki-foreground)">.value);</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-comment)">// Case 3</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">&#x27;./module&#x27;</span><span style="color:var(--shiki-foreground)">)</span><span style="color:var(--shiki-token-function)">.then</span><span style="color:var(--shiki-foreground)">(({ value }) </span><span style="color:var(--shiki-token-keyword)">=&gt;</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-token-constant)">  console</span><span style="color:var(--shiki-token-function)">.log</span><span style="color:var(--shiki-foreground)">(value);</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">});</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-comment)">// Case 4</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">&#x27;./module&#x27;</span><span style="color:var(--shiki-foreground)">)</span><span style="color:var(--shiki-token-function)">.then</span><span style="color:var(--shiki-foreground)">((mod) </span><span style="color:var(--shiki-token-keyword)">=&gt;</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">  const</span><span style="color:var(--shiki-foreground)"> { </span><span style="color:var(--shiki-token-constant)">value</span><span style="color:var(--shiki-foreground)"> } </span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-foreground)"> mod;</span></span>
<span class="line"><span style="color:var(--shiki-token-constant)">  console</span><span style="color:var(--shiki-token-function)">.log</span><span style="color:var(--shiki-foreground)">(value);</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">});</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-comment)">// Case 5</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">&#x27;./module&#x27;</span><span style="color:var(--shiki-foreground)">)</span><span style="color:var(--shiki-token-function)">.then</span><span style="color:var(--shiki-foreground)">((mod) </span><span style="color:var(--shiki-token-keyword)">=&gt;</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-token-constant)">  console</span><span style="color:var(--shiki-token-function)">.log</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-constant)">mod</span><span style="color:var(--shiki-foreground)">.value);</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">});</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h3 class="rp-toc-include" id="支持-import-defer"><a href="#支持-import-defer" class="rp-header-anchor rp-link" aria-hidden="true">#</a>支持 import defer</h3>
<p>Rspack 现已支持 <a href="https://github.com/tc39/proposal-defer-import-eval" target="_blank" rel="noopener noreferrer" class="rp-link">import defer</a> 语法。</p>
<p><code>import defer</code> 是 JavaScript 中一个新特性，也已经在 <a href="https://devblogs.microsoft.com/typescript/announcing-typescript-5-9-beta/#support-for-import-defer" target="_blank" rel="noopener noreferrer" class="rp-link">TypeScript 5.9</a> 中得到支持，它允许你在导入模块时不立即执行模块及其依赖，从而更好地控制代码的加载和副作用发生的时机。</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> defer </span><span style="color:var(--shiki-token-constant)">*</span><span style="color:var(--shiki-token-keyword)"> as</span><span style="color:var(--shiki-foreground)"> foo </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;./foo&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>你可以通过 <a href="/zh/config/experiments#experimentsdeferimport" class="rp-link">experiments.deferImport</a> 启用此特性：</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  experiments</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    deferImport</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> true</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<blockquote>
<p>目前 Rspack 仅支持 <code>import defer</code> 语法，<code>import.defer()</code> 的函数形式将在后续版本中实现。</p>
</blockquote>
<h3 class="rp-toc-include" id="优化-esm-产物"><a href="#优化-esm-产物" class="rp-header-anchor rp-link" aria-hidden="true">#</a>优化 ESM 产物</h3>
<p>如何优化 ESM 产物一直是 Rspack 面临的难题之一。过去我们通过 <a href="/zh/config/optimization#optimizationconcatenatemodules" class="rp-link">module concatenation</a> 来优化 ESM 输出，但这种方式存在一些局限：</p>
<ul>
<li><strong>输出不够纯净</strong>：生成文件中包含了 Rspack 运行时代码</li>
<li><strong>可能出错</strong>：某些模块无法被正确合并，可能导致产物行为异常</li>
<li><strong>有限的代码分割支持</strong>：代码分割后的产物会变得复杂，难以进行静态分析和优化</li>
</ul>
<p>为了彻底解决这些问题，我们引入了实验性的 <a href="https://v1.rspack.rs/plugins/rspack/esm-library-plugin" target="_blank" rel="noopener noreferrer" class="rp-link">EsmLibraryPlugin</a> 插件，它专为构建 ESM 库设计，让生成的代码更加简洁和高效：</p>
<ul>
<li><strong>完全接管打包过程</strong>：在编译阶段完成模块连接，不再依赖 Rspack 的运行时代码</li>
<li><strong>支持代码分割</strong>：分割后的代码可被静态分析和 tree shaking 友好</li>
</ul>
<p>下图展示了使用该插件前后的代码分割产物对比：左侧为之前的产物，右侧为使用 EsmLibraryPlugin 后的输出：</p>
<p><img src="https://assets.rspack.rs/rspack/assets/rspack-v1-6-esm-diff.png" alt="Rspack 1.6 ESM output diff"/></p>
<p>目前，EsmLibraryPlugin 已基本开发完成，并正在集成至 Rslib 中，以提供开箱即用的体验。</p>
<p>你也可以通过以下配置手动启用它：</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { rspack } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;@rspack/core&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  plugins</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span><span style="color:var(--shiki-token-keyword)">new</span><span style="color:var(--shiki-token-constant)"> rspack</span><span style="color:var(--shiki-token-function)">.</span><span style="color:var(--shiki-token-constant)">experiments</span><span style="color:var(--shiki-token-function)">.EsmLibraryPlugin</span><span style="color:var(--shiki-foreground)">()]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  optimization</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-token-comment)">    // Recommended to enable; otherwise, consumers must import runtime code from the entry.</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    runtimeChunk</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> true</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>此外，我们还提供了 <code>preserveModules</code> 选项，可让输出结构与源码目录保持一致：</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> path </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;node:path&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  plugins</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">    new</span><span style="color:var(--shiki-token-constant)"> rspack</span><span style="color:var(--shiki-token-function)">.</span><span style="color:var(--shiki-token-constant)">experiments</span><span style="color:var(--shiki-token-function)">.EsmLibraryPlugin</span><span style="color:var(--shiki-foreground)">({</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      preserveModules</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> path</span><span style="color:var(--shiki-token-function)">.resolve</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)">.</span><span style="color:var(--shiki-token-constant)">meta</span><span style="color:var(--shiki-foreground)">.dirname</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-string-expression)"> &#x27;./src&#x27;</span><span style="color:var(--shiki-foreground)">)</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    })</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  ]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h3 class="rp-toc-include" id="默认启用-barrel-优化"><a href="#默认启用-barrel-优化" class="rp-header-anchor rp-link" aria-hidden="true">#</a>默认启用 barrel 优化</h3>
<p>在 Rspack 1.5 中，我们引入了实验性的 <a href="/zh/config/experiments#experimentslazybarrel" class="rp-link">lazyBarrel</a> 优化功能，专门用于提升 barrel 文件（桶文件）的构建性能。经过一段时间的生产环境实践和用户反馈收集，我们确认 lazyBarrel 功能已经达到稳定状态，因此在 Rspack 1.6 中将其设为默认启用。</p>
<div class="rp-callout rp-callout--info"><div class="rp-callout__title">Info</div><div class="rp-callout__content"><p>
什么是 barrel 文件？ Barrel 文件是指那些主要用于重新导出其他模块内容的文件，通常用于简化导入路径和提供统一的 API 入口。</p></div></div>
<h3 class="rp-toc-include" id="layers-特性稳定"><a href="#layers-特性稳定" class="rp-header-anchor rp-link" aria-hidden="true">#</a>layers 特性稳定</h3>
<p>layer 是一种用于对模块进行分层管理的特性，可以用于 React Server Components 等进阶场景。通过为模块指定不同的 layer，你可以更灵活地控制它们的构建行为，例如：</p>
<ul>
<li>将不同 layer 的模块编译到不同的目标环境</li>
<li>将它们输出到不同的产物目录中</li>
</ul>
<p>从 Rspack 1.6 开始，layer 特性已经足够稳定，因此我们废弃了原先的实验性开关 <a href="/zh/config/experiments#experimentslayers" class="rp-link">experiments.layers</a>。现在，你可以直接使用 layer 特性，不再需要实验性开关。</p>
<p>想了解更多 layer 的细节和使用方式，可以阅读我们新增的 <a href="/zh/guide/features/layer#layer" class="rp-link">layer 指南</a>。</p>
<h3 class="rp-toc-include" id="保留-jsx-语法"><a href="#保留-jsx-语法" class="rp-header-anchor rp-link" aria-hidden="true">#</a>保留 JSX 语法</h3>
<p>Rspack 现在支持在产物中保留 JSX 语法。当启用相关选项时，Rspack 只会对 JSX 进行语法分析，而不会将其转换为 JavaScript。</p>
<p>这一特性在构建一些使用 JSX 的库时尤其实用。例如，在使用 Rslib 构建组件库时，可以选择保留 JSX 原样输出，由消费端在使用阶段再完成 JSX 转换。</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  module</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    parser</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      javascript</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        jsx</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> true</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-comment)"> // Enable JSX parsing</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    rules</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        test</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> /\.jsx</span><span style="color:var(--shiki-token-keyword)">?$</span><span style="color:var(--shiki-token-string-expression)">/</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        use</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          loader</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;builtin:swc-loader&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          options</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">            jsc</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">              parser</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> { jsx</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> true</span><span style="color:var(--shiki-foreground)"> }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">              transform</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-token-comment)">                // Preserve JSX syntax</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">                react</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> { runtime</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;preserve&#x27;</span><span style="color:var(--shiki-foreground)"> }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">              }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">            }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    ]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h3 class="rp-toc-include" id="提取-source-map"><a href="#提取-source-map" class="rp-header-anchor rp-link" aria-hidden="true">#</a>提取 source map</h3>
<p>Rspack 现在支持通过 <a href="/zh/config/module-rules#rulesextractsourcemap" class="rp-link">rules[].extractSourceMap</a> 从文件中提取现有的源码映射数据（从它们的 <code>//# sourceMappingURL</code> 注释中）。这个功能对于保留第三方库提供的源码映射特别有用，确保即使在这些库被打包或转换时，调试信息仍然保持准确。</p>
<p>这个功能可以作为 <a href="https://github.com/webpack-contrib/source-map-loader" target="_blank" rel="noopener noreferrer" class="rp-link">source-map-loader</a> 的内置替代方案，提供了更好的性能和与构建过程更紧密的集成。</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  module</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    rules</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        test</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> /\.m</span><span style="color:var(--shiki-token-keyword)">?</span><span style="color:var(--shiki-token-string-expression)">js</span><span style="color:var(--shiki-token-keyword)">$</span><span style="color:var(--shiki-token-string-expression)">/</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        extractSourceMap</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> true</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    ]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h3 class="rp-toc-include" id="性能提升"><a href="#性能提升" class="rp-header-anchor rp-link" aria-hidden="true">#</a>性能提升</h3>
<p>Rspack 1.6 带来了多项性能优化，相较于 Rspack 1.5.0，性能提升如下：</p>
<ul>
<li>CLI 启动速度提升约 <strong>50 ms</strong></li>
<li>构建 10000 个 React 组件的速度提升 <strong>11%</strong></li>
<li>构建多个 UI 组件库的速度提升 <strong>31%</strong>（得益于默认启用的 barrel 文件优化）</li>
</ul>
<blockquote>
<p>数据来源：<a href="https://github.com/rstackjs/build-tools-performance" target="_blank" rel="noopener noreferrer" class="rp-link">Rspack benchmark</a></p>
</blockquote>
<h2 class="rp-toc-include" id="rstack-进展"><a href="#rstack-进展" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rstack 进展</h2>
<p><a href="/zh/guide/start/ecosystem#rstack" class="rp-link">Rstack</a> 是一个以 Rspack 为核心的 JavaScript 统一工具链，具有优秀的性能和一致的架构。</p>
<h3 class="rp-toc-include" id="rsbuild-16"><a href="#rsbuild-16" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rsbuild 1.6</h3>
<h4 class="rp-toc-include" id="转发浏览器日志"><a href="#转发浏览器日志" class="rp-header-anchor rp-link" aria-hidden="true">#</a>转发浏览器日志</h4>
<p>Rsbuild 现在会自动将浏览器中的错误日志转发到终端，帮助你在开发过程中便捷地查看运行时报错，这也使 Coding Agents 能够从终端日志中获取更完整的上下文，从而更好地分析和定位错误。</p>
<p><img src="https://assets.rspack.rs/rspack/assets/rspack-v1-6-error-forward.png" alt="rsbuild-error-forward"/></p>
<p>如果你不需要该功能，可以将 <a href="https://rsbuild.rs/config/dev/browser-logs" target="_blank" rel="noopener noreferrer" class="rp-link">dev.browserLogs</a> 设置为 false 来禁用它：</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rsbuild.config.ts</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rsbuild.config.ts"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  dev</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    browserLogs</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> false</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h4 class="rp-toc-include" id="构建-esm-应用"><a href="#构建-esm-应用" class="rp-header-anchor rp-link" aria-hidden="true">#</a>构建 ESM 应用</h4>
<p>Rsbuild 现在支持为 Web 应用构建 ES Modules 格式产物，只需启用 <a href="https://rsbuild.rs/zh/config/output/module" target="_blank" rel="noopener noreferrer" class="rp-link">output.module: true</a> 即可：</p>
<div class="rp-codeblock language-ts"><div class="rp-codeblock__title">rsbuild.config.ts</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="ts" data-title="rsbuild.config.ts"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  output</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    module</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> true</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>启用后，Rsbuild 将不再默认生成 IIFE 格式的脚本，而是输出标准的 ESM 格式，并自动将生成的 <code>&lt;script&gt;</code> 标签设置为 <code>type=&quot;module&quot;</code>。</p>
<h4 class="rp-toc-include" id="更快地加载配置文件"><a href="#更快地加载配置文件" class="rp-header-anchor rp-link" aria-hidden="true">#</a>更快地加载配置文件</h4>
<p>由于 Node.js 22 已经原生支持了 TypeScript，Rsbuild 现在默认会使用 Node.js 的原生加载器来解析配置文件；如果加载失败，则会自动回退到 <a href="https://github.com/unjs/jiti" target="_blank" rel="noopener noreferrer" class="rp-link">Jiti</a>。在使用 Node.js 22 及以上版本时，这一机制能够确保模块解析行为与 Node.js 原生保持一致，同时带来更好的加载性能。</p>
<p>你也可以通过 Rsbuild CLI 的 --config-loader 选项手动指定加载方式：</p>
<div class="rp-codeblock language-bash"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="bash"><code><span class="line"><span style="color:var(--shiki-token-comment)"># 强制使用原生加载</span></span>
<span class="line"><span style="color:var(--shiki-token-function)">rsbuild</span><span style="color:var(--shiki-token-string)"> build</span><span style="color:var(--shiki-token-string)"> --config-loader</span><span style="color:var(--shiki-token-string)"> native</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-comment)"># 强制使用 Jiti 加载</span></span>
<span class="line"><span style="color:var(--shiki-token-function)">rsbuild</span><span style="color:var(--shiki-token-string)"> build</span><span style="color:var(--shiki-token-string)"> --config-loader</span><span style="color:var(--shiki-token-string)"> jiti</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h3 class="rp-toc-include" id="rspress-v2-beta"><a href="#rspress-v2-beta" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rspress v2 beta</h3>
<h4 class="rp-toc-include" id="新主题预览"><a href="#新主题预览" class="rp-header-anchor rp-link" aria-hidden="true">#</a>新主题预览</h4>
<p>Rspress 的新主题已进入预览阶段，并已经上线至 v2 官网。🎉</p>
<p>新主题在视觉与交互设计上进行了全面升级，带来更沉浸、更舒适的文档阅读体验。同时开放了更多的主题接口与 CSS 类名，方便开发者自由地定制 UI。</p>
<blockquote>
<p>👉 前往 <a href="https://v2.rspress.rs/" target="_blank" rel="noopener noreferrer" class="rp-link">Rspress v2 官网</a> 体验</p>
</blockquote>
<p><img src="https://assets.rspack.rs/rspack/assets/rspack-v1-6-rspress.gif" alt="rspress-v2-theme"/></p>
<h4 class="rp-toc-include" id="子页面切换"><a href="#子页面切换" class="rp-header-anchor rp-link" aria-hidden="true">#</a>子页面切换</h4>
<p>Rspress V2 新增 <a href="https://v2.rspress.rs/zh/ui/components/page-tabs" target="_blank" rel="noopener noreferrer" class="rp-link">PageTabs</a> 组件，可在同一页面中创建多个子标签页，将长篇内容自然拆分为结构清晰的子页面。</p>
<p><img src="https://assets.rspack.rs/rspack/assets/rspack-v1-6-page-tabs.png" alt="Rspress 子页面切换组件"/></p>
<h3 class="rp-toc-include" id="rslib-016"><a href="#rslib-016" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rslib 0.16</h3>
<h4 class="rp-toc-include" id="更快的类型生成"><a href="#更快的类型生成" class="rp-header-anchor rp-link" aria-hidden="true">#</a>更快的类型生成</h4>
<p>Rslib 现在支持基于 <a href="https://github.com/microsoft/typescript-go" target="_blank" rel="noopener noreferrer" class="rp-link">typescript-go</a> 生成类型声明文件，你只需开启 <a href="https://rslib.rs/zh/config/lib/dts#dtstsgo" target="_blank" rel="noopener noreferrer" class="rp-link">dts.tsgo</a>，即可让类型检查和类型生成的性能提升约 <strong>300%</strong>，在大型项目中收益更为明显。</p>
<div class="rp-codeblock language-ts"><div class="rp-codeblock__title">rslib.config.ts</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="ts" data-title="rslib.config.ts"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  lib</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      dts</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> { tsgo</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> true</span><span style="color:var(--shiki-foreground)"> }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  ]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h4 class="rp-toc-include" id="保留-jsx-语法-1"><a href="#保留-jsx-语法-1" class="rp-header-anchor rp-link" aria-hidden="true">#</a>保留 JSX 语法</h4>
<p>Rslib 现在支持在构建产物中保留原始 JSX，只需将 runtime 设置为 <a href="https://rsbuild.rs/zh/plugins/list/plugin-react#preserve" target="_blank" rel="noopener noreferrer" class="rp-link"><code>&#x27;preserve&#x27;</code></a> 即可。在该模式下，JSX 语法将保留原样，不做任何转换，方便后续由其他打包工具处理。</p>
<div class="rp-codeblock language-ts"><div class="rp-codeblock__title">rslib.config.ts</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="ts" data-title="rslib.config.ts"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { pluginReact } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;@rsbuild/plugin-react&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  lib</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      bundle</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> false</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      format</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;esm&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  ]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  plugins</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span></span>
<span class="line"><span style="color:var(--shiki-token-function)">    pluginReact</span><span style="color:var(--shiki-foreground)">({</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      swcReactOptions</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        runtime</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;preserve&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    })</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  ]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h4 class="rp-toc-include" id="更多-cli-选项"><a href="#更多-cli-选项" class="rp-header-anchor rp-link" aria-hidden="true">#</a>更多 CLI 选项</h4>
<p>Rslib 的 build 命令中支持了更多的 <a href="https://rslib.rs/zh/guide/basic/cli#rslib-build" target="_blank" rel="noopener noreferrer" class="rp-link">CLI 选项</a>，这些选项的优先级高于配置文件。</p>
<div class="rp-codeblock language-json"><div class="rp-codeblock__title">package.json</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="json" data-title="package.json"><code><span class="line"><span style="color:var(--shiki-foreground)">{</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">  &quot;scripts&quot;</span><span style="color:var(--shiki-token-punctuation)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">    &quot;build&quot;</span><span style="color:var(--shiki-token-punctuation)">:</span><span style="color:var(--shiki-token-string-expression)"> &quot;rslib build --entry index.ts --minify --tsconfig tsconfig.build.json&quot;</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">}</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>这允许你在没有配置文件的情况下使用 Rslib，CLI 将自动使用仅包含单个 <a href="https://rslib.rs/zh/config/lib/" target="_blank" rel="noopener noreferrer" class="rp-link">lib</a> 的默认配置，并根据命令行参数完成构建。</p>
<h3 class="rp-toc-include" id="rstest-06"><a href="#rstest-06" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rstest 0.6</h3>
<h4 class="rp-toc-include" id="vs-code-扩展"><a href="#vs-code-扩展" class="rp-header-anchor rp-link" aria-hidden="true">#</a>VS Code 扩展</h4>
<p><a href="https://marketplace.visualstudio.com/items?itemName=rstack.rstest" target="_blank" rel="noopener noreferrer" class="rp-link">Rstest VS Code 扩展</a> 已发布，它允许你在编辑器中发现、运行和调试测试用例，帮助你高效地管理测试用例、快速查看测试结果。</p>
<p><img src="https://assets.rspack.rs/rspack/assets/rspack-v1-6-rstest-vscode-ext.gif" alt="rstest-vscode-extension"/></p>
<h4 class="rp-toc-include" id="覆盖率支持"><a href="#覆盖率支持" class="rp-header-anchor rp-link" aria-hidden="true">#</a>覆盖率支持</h4>
<p>Rstest 现已支持使用 istanbul 收集代码覆盖率并生成覆盖率报告，详见 <a href="https://rstest.rs/zh/config/test/coverage" target="_blank" rel="noopener noreferrer" class="rp-link">Rstest - 代码覆盖率</a>。</p>
<p><img src="https://assets.rspack.rs/rspack/assets/rspack-v1-6-rstest-cov.png" alt="rstest-coverage"/></p>
<h3 class="rp-toc-include" id="rsdoctor-13"><a href="#rsdoctor-13" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rsdoctor 1.3</h3>
<h4 class="rp-toc-include" id="rsdoctor-github-actions"><a href="#rsdoctor-github-actions" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rsdoctor GitHub Actions</h4>
<p>Rsdoctor 现在提供了 <a href="https://github.com/web-infra-dev/rsdoctor-action" target="_blank" rel="noopener noreferrer" class="rp-link">GitHub bundle diff action</a>，可以在 CI 阶段自动检测和对比构建产物的体积变化，帮助团队及时发现并预防包体积劣化。</p>
<p><img src="https://assets.rspack.rs/rspack/assets/rspack-v1-6-bundle-diff.png" alt="Rsdoctor GitHub Actions"/></p>
<h4 class="rp-toc-include" id="单一-json-数据报告"><a href="#单一-json-数据报告" class="rp-header-anchor rp-link" aria-hidden="true">#</a>单一 JSON 数据报告</h4>
<p>Rsdoctor 现支持在 Brief 模式下导出 <a href="https://rsdoctor.rs/zh/config/options/output#mode-brief" target="_blank" rel="noopener noreferrer" class="rp-link">单一 JSON 报告文件</a>，该文件可方便地用于存储、分享或二次数据分析。此外，我们新增了 <a href="https://rsdoctor.rs/zh/guide/start/playground" target="_blank" rel="noopener noreferrer" class="rp-link">Playground 页面</a>，开发者可以上传 JSON 报告文件，重新打开并可视化查看分析结果。</p>
<h2 class="rp-toc-include" id="生态"><a href="#生态" class="rp-header-anchor rp-link" aria-hidden="true">#</a>生态</h2>
<h3 class="rp-toc-include" id="next-rspack"><a href="#next-rspack" class="rp-header-anchor rp-link" aria-hidden="true">#</a>next-rspack</h3>
<p>在 Next.js 16 中，next-rspack 已接入 Rspack 的 <a href="https://github.com/rstackjs/rspack-binding-template" target="_blank" rel="noopener noreferrer" class="rp-link">定制 Rust binding 方案</a>，带来了可观的性能提升：</p>
<ul>
<li>build 性能提升 24%</li>
<li>dev 性能提升 10%</li>
</ul>
<p>在定制的 Rspack Rust binding 中，我们将 Next.js 的 <code>externals</code> 逻辑迁移到 Rust 侧，显著减少了 JS 与 Rust 之间的通信开销。</p>
<div class="rp-table-scroll-container rp-scrollbar"><table><thead><tr><th>工具</th><th>build 时间（无缓存）</th><th>dev 时间（无缓存）</th></tr></thead><tbody><tr><td>Rspack (next@16.0.0)</td><td>3.8s</td><td>1.7s</td></tr><tr><td>Rspack (next@15.4.0)</td><td>5.0s</td><td>1.9s</td></tr><tr><td>webpack</td><td>14.0s</td><td>7.8s</td></tr></tbody></table></div>
<p>基准测试基于 <a href="https://github.com/SyMind/chakra-ui-docs/tree/next-rspack" target="_blank" rel="noopener noreferrer" class="rp-link">chakra-ui-docs</a> 仓库进行，完整的性能数据可在此查看：<a href="https://github.com/SyMind/chakra-ui-docs/blob/next-rspack/PERF.md" target="_blank" rel="noopener noreferrer" class="rp-link">PERF.md</a>。</p>
<h2 class="rp-toc-include" id="升级指南"><a href="#升级指南" class="rp-header-anchor rp-link" aria-hidden="true">#</a>升级指南</h2>
<h3 class="rp-toc-include" id="升级-swc-插件"><a href="#升级-swc-插件" class="rp-header-anchor rp-link" aria-hidden="true">#</a>升级 SWC 插件</h3>
<p>如果你的项目中使用了 SWC Wasm 插件（如 <code>@swc/plugin-emotion</code> 等），需要将插件升级至兼容 <code>swc_core@46</code> 的版本，否则可能因版本不兼容导致构建报错。</p>
<blockquote>
<p>详情请查阅：<a href="/zh/errors/swc-plugin-version" class="rp-link">常见问题 - SWC 插件版本不匹配</a>。</p>
</blockquote>
<h3 class="rp-toc-include" id="移除-experimentslayer"><a href="#移除-experimentslayer" class="rp-header-anchor rp-link" aria-hidden="true">#</a>移除 <code>experiments.layer</code></h3>
<p><code>experiments.layer</code> 选项已经废弃，可以直接移除：</p>
<div class="rp-codeblock language-diff"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="diff" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-foreground)">export default {</span></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">-  experiments: {</span></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">-   layer: true,</span></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">-  },</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div><!--/$-->]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Rspack 1.5 发布公告]]></title>
            <link>https://rspack.rs/zh/blog/announcing-1-5</link>
            <guid isPermaLink="false">/zh/blog/announcing-1-5</guid>
            <pubDate>Tue, 26 Aug 2025 11:00:00 GMT</pubDate>
            <description><![CDATA[Rspack 1.5 版本发布，支持 Barrel 文件优化、常量内联优化，新增了内置文件系统监听器、虚拟模块插件和 Rust 扩展机制，并不再支持 Node 16。]]></description>
            <content:encoded><![CDATA[<!--$--><p><em>2025 年 8 月 26 日</em></p>
<h1 class="rp-toc-include" id="rspack-15-发布公告"><a href="#rspack-15-发布公告" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rspack 1.5 发布公告<!-- --> </h1><div class="rp-not-doc rp-llms-container"><button class="rp-not-doc rp-llms-button rp-llms-copy-button"><div class="rp-llms-copy-button__icon-wrapper"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-llms-copy-button__icon-success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-llms-copy-button__icon-copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg></div><span>复制 Markdown</span></button><button class="rp-llms-button rp-llms-view-options__trigger "><svg width="1em" height="1em" viewBox="0 0 32 32" class="rp-llms-view-options__arrow "><path fill="currentColor" d="M16 22 6 12l1.4-1.4 8.6 8.6 8.6-8.6L26 12z"></path></svg></button></div>
<p><img src="https://assets.rspack.rs/rspack/rspack-banner-v1-5.png" alt="Rspack 1.5"/></p>
<hr/>
<p>我们很高兴地宣布 Rspack 1.5！</p>
<p>值得关注的变更如下：</p>
<ul>
<li>新功能<!-- -->
<ul>
<li><a href="#barrel-%E6%96%87%E4%BB%B6%E4%BC%98%E5%8C%96" class="rp-link">Barrel 文件优化</a></li>
<li><a href="#%E6%9B%B4%E5%BF%AB%E7%9A%84%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F%E7%9B%91%E5%90%AC%E5%99%A8" class="rp-link">更快的文件系统监听器</a></li>
<li><a href="#%E6%94%B9%E8%BF%9B%E6%B5%8F%E8%A7%88%E5%99%A8%E6%94%AF%E6%8C%81" class="rp-link">改进浏览器支持</a></li>
<li><a href="#%E4%BD%BF%E7%94%A8-rust-%E6%89%A9%E5%B1%95-rspack" class="rp-link">使用 Rust 扩展 Rspack</a></li>
<li><a href="#%E5%B8%B8%E9%87%8F%E5%86%85%E8%81%94%E4%BC%98%E5%8C%96" class="rp-link">常量内联优化</a></li>
<li><a href="#%E7%B1%BB%E5%9E%8B%E9%87%8D%E5%AF%BC%E5%87%BA%E5%88%86%E6%9E%90" class="rp-link">类型重导出分析</a></li>
<li><a href="#%E5%86%85%E7%BD%AE%E8%99%9A%E6%8B%9F%E6%A8%A1%E5%9D%97%E6%8F%92%E4%BB%B6" class="rp-link">内置虚拟模块插件</a></li>
<li><a href="#%E6%A8%A1%E5%9D%97%E8%81%94%E9%82%A6%E8%BF%90%E8%A1%8C%E6%97%B6%E6%8F%90%E5%8D%87" class="rp-link">模块联邦运行时提升</a></li>
<li><a href="#%E5%AE%89%E8%A3%85%E4%BD%93%E7%A7%AF%E4%BC%98%E5%8C%96" class="rp-link">安装体积优化</a></li>
<li><a href="#seal-%E9%98%B6%E6%AE%B5%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96" class="rp-link">Seal 阶段性能优化</a></li>
</ul>
</li>
<li>其他<!-- -->
<ul>
<li><a href="#%E4%B8%8D%E5%86%8D%E6%94%AF%E6%8C%81-nodejs-16" class="rp-link">不再支持 Node.js 16</a></li>
<li><a href="#resolver-javascript-api" class="rp-link">Resolver JavaScript API</a></li>
</ul>
</li>
<li>Rstack 进展<!-- -->
<ul>
<li><a href="#rslint-%E5%8F%91%E5%B8%83" class="rp-link">Rslint 发布</a></li>
<li><a href="#rsbuild-15" class="rp-link">Rsbuild 1.5</a></li>
<li><a href="#rslib-012" class="rp-link">Rslib 0.12</a></li>
<li><a href="#rspress-20-beta" class="rp-link">Rspress 2.0 beta</a></li>
<li><a href="#rsdoctor-12" class="rp-link">Rsdoctor 1.2</a></li>
<li><a href="#rstest-02" class="rp-link">Rstest 0.2</a></li>
</ul>
</li>
</ul>
<h2 class="rp-toc-include" id="新功能"><a href="#新功能" class="rp-header-anchor rp-link" aria-hidden="true">#</a>新功能</h2>
<h3 class="rp-toc-include" id="barrel-文件优化"><a href="#barrel-文件优化" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Barrel 文件优化</h3>
<p>Barrel 文件是一种常见的模块导出模式，它通过创建统一的入口文件来重新导出多个模块，通常命名为 <code>index.js</code> 或 <code>index.ts</code>，例如：</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-foreground)"> { Button</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> Tab } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;./components&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-constant)"> *</span><span style="color:var(--shiki-token-keyword)"> as</span><span style="color:var(--shiki-foreground)"> utils </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;./utils&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-constant)"> *</span><span style="color:var(--shiki-token-keyword)"> from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;./hooks&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>虽然这种模式简化了模块导入的使用方式，但是在构建过程中会带来性能问题：当导入 barrel 文件中的某个模块时，Rspack 需要解析和构建 barrel 文件依赖的所有模块，即使实际只使用了其中的一小部分。</p>
<p>为了解决这一问题，Rspack 1.5 引入了实验性的 <a href="/zh/config/experiments#experimentslazybarrel" class="rp-link">lazyBarrel</a> 功能，它能够自动识别无副作用的 barrel 文件，对其中的重导出进行延迟构建优化，只在真正需要时才会解析和构建相关模块，从而显著减少不必要的模块解析和构建开销。这一优化对于包含大量 barrel 文件的项目尤其有效，能够带来显著的构建性能提升。</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  experiments</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    lazyBarrel</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> true</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>在实际测试中，开启 barrel 文件优化后，两个不同规模的应用都获得了明显的构建性能提升：</p>
<ul>
<li><a href="https://github.com/rstackjs/build-tools-performance/tree/main/cases/ui-components" target="_blank" rel="noopener noreferrer" class="rp-link">Benchmark 应用</a>：</li>
</ul>
<div class="rp-table-scroll-container rp-scrollbar"><table><thead><tr><th>指标</th><th>开启前</th><th>开启后</th><th>优化</th></tr></thead><tbody><tr><td>构建时间</td><td>1.47s</td><td>1.19s</td><td><code>-20%</code></td></tr><tr><td>模块路径解析次数</td><td>39,675 次</td><td>20,071 次</td><td><code>-49%</code></td></tr><tr><td>模块构建次数</td><td>9,358 次</td><td>5,062 次</td><td><code>-46%</code></td></tr></tbody></table></div>
<ul>
<li>来自字节跳动的应用：</li>
</ul>
<div class="rp-table-scroll-container rp-scrollbar"><table><thead><tr><th>指标</th><th>开启前</th><th>开启后</th><th>优化</th></tr></thead><tbody><tr><td>构建时间</td><td>17.9s</td><td>16.0s</td><td><code>-10%</code></td></tr><tr><td>模块路径解析次数</td><td>181,078 次</td><td>137,232 次</td><td><code>-24%</code></td></tr><tr><td>模块构建次数</td><td>38,046 次</td><td>29,405 次</td><td><code>-23%</code></td></tr></tbody></table></div>
<p>我们已经在 Rsbuild 1.5 中默认开启了 barrel 文件优化，并计划在 Rspack 1.6 中为所有项目默认启用该功能。详见 <a href="/zh/config/experiments#experimentslazybarrel" class="rp-link">experiments.lazyBarrel 文档</a>。</p>
<h3 class="rp-toc-include" id="更快的文件系统监听器"><a href="#更快的文件系统监听器" class="rp-header-anchor rp-link" aria-hidden="true">#</a>更快的文件系统监听器</h3>
<p>此前，Rspack 使用文件系统监听器 <a href="https://github.com/webpack/watchpack" target="_blank" rel="noopener noreferrer" class="rp-link">watchpack</a> 来监听文件变化。在实际使用中，我们发现 <code>watchpack</code> 存在性能瓶颈。例如，每次文件变更都会重新创建实例，在大型项目中会消耗大量的 CPU 和内存资源（参见 <a href="https://github.com/web-infra-dev/rspack/issues/7490" target="_blank" rel="noopener noreferrer" class="rp-link">#7490</a>）。</p>
<p>为解决这一问题，我们基于 Rust 打造了原生的文件系统监听器，新的实现具有以下优势：</p>
<ul>
<li><strong>高性能</strong>：HMR 速度提升至多 50%</li>
<li><strong>增量更新</strong>：只处理实际发生变化的文件</li>
<li><strong>持久化运行</strong>：在整个开发过程中持续工作，无需反复重建</li>
</ul>
<p>你可以通过配置 <a href="/zh/config/experiments#experimentsnativewatcher" class="rp-link">experiments.nativeWatcher</a> 来尝试新版 watcher：</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  experiments</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    nativeWatcher</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> true</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  watchOptions</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-token-comment)">    // Other watch options...</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h3 class="rp-toc-include" id="改进浏览器支持"><a href="#改进浏览器支持" class="rp-header-anchor rp-link" aria-hidden="true">#</a>改进浏览器支持</h3>
<p>在先前的 Rspack 1.4 中，我们正式引入了 Wasm target 支持，这意味着 Rspack 可以在基于 WebContainers 的浏览器环境中运行，例如 <a href="https://stackblitz.com/" target="_blank" rel="noopener noreferrer" class="rp-link">StackBlitz</a>。</p>
<p>现在你可以<strong>直接在任何现代浏览器中使用 Rspack</strong>了。 新发布的 <a href="/zh/api/javascript-api/browser" class="rp-link">@rspack/browser</a> 是专为纯浏览器环境设计的版本，而无需依赖 WebContainers 或是特定平台。<code>@rspack/browser</code> 为 Web 项目的在线打包提供底层支持，提供了更轻量的问题复现、配置分享方案，并通过提供在线交互式 Demo 的方式帮助开发者入门和学习 Rspack。</p>
<p><img src="https://assets.rspack.rs/rspack/assets/rspack-v1-5-repl.rspack.png" alt="rspack-web-repl"/></p>
<p><code>@rspack/browser</code> 提供的 API 和 <code>@rspack/core</code> 的 JavaScript API 是对齐的。在此基础上，额外提供了为适配浏览器环境的特性和 API：</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { rspack</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> builtinMemFs } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;@rspack/browser&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-comment)">// Write files to memfs</span></span>
<span class="line"><span style="color:var(--shiki-token-constant)">builtinMemFs</span><span style="color:var(--shiki-token-function)">.</span><span style="color:var(--shiki-token-constant)">volume</span><span style="color:var(--shiki-token-function)">.fromJSON</span><span style="color:var(--shiki-foreground)">({</span></span>
<span class="line"><span style="color:var(--shiki-token-comment)">  // ...project files</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">});</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-comment)">// Just like using JavaScript API of @rspack/core</span></span>
<span class="line"><span style="color:var(--shiki-token-function)">rspack</span><span style="color:var(--shiki-foreground)">({}</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> (err</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> stats) </span><span style="color:var(--shiki-token-keyword)">=&gt;</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">  if</span><span style="color:var(--shiki-foreground)"> (err </span><span style="color:var(--shiki-token-keyword)">||</span><span style="color:var(--shiki-token-constant)"> stats</span><span style="color:var(--shiki-token-function)">.hasErrors</span><span style="color:var(--shiki-foreground)">()) {</span></span>
<span class="line"><span style="color:var(--shiki-token-comment)">    // ...</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span></span>
<span class="line"><span style="color:var(--shiki-token-comment)">  // Get output from memfs after bundling</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">  const</span><span style="color:var(--shiki-token-constant)"> files</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-constant)"> builtinMemFs</span><span style="color:var(--shiki-token-function)">.</span><span style="color:var(--shiki-token-constant)">volume</span><span style="color:var(--shiki-token-function)">.toJSON</span><span style="color:var(--shiki-foreground)">();</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">});</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>目前 <code>@rspack/browser</code> 还处于实验性阶段，可能会引入不兼容更新。未来我们将持续完善在线打包所需的能力，欢迎前往 <a href="https://playground.rspack.rs/" target="_blank" rel="noopener noreferrer" class="rp-link">Rspack Playground</a> 进行体验。</p>
<h3 class="rp-toc-include" id="使用-rust-扩展-rspack"><a href="#使用-rust-扩展-rspack" class="rp-header-anchor rp-link" aria-hidden="true">#</a>使用 Rust 扩展 Rspack</h3>
<p>现在你可以直接使用 Rust 来扩展 Rspack 了！通过我们提供的仓库模板，你能够编写自定义的 Rust plugin 和 Rust loader，并替换 Rspack 默认的原生 binding。</p>
<p>在 JavaScript 插件中，Rust 和 JavaScript 之间的数据传递和类型转换会产生一定的性能开销。通过定制 Rspack 的 binding，你的自定义代码将直接与 Rspack Rust core 集成，消除了跨语言通信的开销，同时保持对所有 Rspack JavaScript API 的支持。</p>
<p>这种方式适用于替换频繁与 Rust 通信的 Hooks（如 <code>compilation.hooks.processAssets</code>），以及计算密集型的自定义 loader，在这些场景下可以获得更好的构建性能。</p>
<p>主要特性：</p>
<ul>
<li><strong>原生性能</strong> —— Rust 编写的扩展享受与 Rspack Rust core 相同的原生性能。</li>
<li><strong>完全兼容</strong> —— 保留所有现有的 JavaScript API，无需修改现有项目。</li>
<li><strong>开发便捷</strong> —— 官方模板提供了完整的开发环境和发布流程。</li>
</ul>
<p>你可以使用 <a href="https://github.com/rstackjs/rspack-binding-template" target="_blank" rel="noopener noreferrer" class="rp-link">官方模板</a> 快速开始，更多信息请参考 <a href="https://rstackjs.github.io/rspack-rust-book/custom-binding/getting-started/rationale.html" target="_blank" rel="noopener noreferrer" class="rp-link">设计理念</a>。需要注意的是，使用此方案会带来额外的维护成本，建议仅在需要极致性能优化时使用。</p>
<h3 class="rp-toc-include" id="常量内联优化"><a href="#常量内联优化" class="rp-header-anchor rp-link" aria-hidden="true">#</a>常量内联优化</h3>
<p>在组织项目代码时，我们通常会将常量集中管理，例如 <code>constants.js</code> 或者 TypeScript 项目中包含 enums 的 <code>types.ts</code> 文件。</p>
<p>Rspack 引入了 <a href="/zh/config/experiments#experimentsinlineconst" class="rp-link">experiments.inlineConst</a> 和 <a href="/zh/config/experiments#experimentsinlineenum" class="rp-link">experiments.inlineEnum</a> 两个实验性功能，用于对常量进行跨模块内联优化。这些优化可以帮助压缩工具更加进行准确的静态分析，消除无用代码分支，从而进一步减小产物的体积。</p>
<p><code>inlineConst</code> 能够对模块图中叶子节点模块中的常量进行跨模块内联，例如以下示例：</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js"><code><span class="line"><span style="color:var(--shiki-token-comment)">// font-settings.js</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-token-constant)"> bold</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-constant)"> 0b001</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-token-constant)"> italic</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-constant)"> 0b010</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-comment)">// index.js</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { bold</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> italic } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;./font-settings&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">const</span><span style="color:var(--shiki-token-constant)"> fontStyle</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-foreground)"> {};</span></span>
<span class="line"><span style="color:var(--shiki-token-comment)">// MY_FONT is defined by DefinePlugin({ FONT: 0b001 })</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">if</span><span style="color:var(--shiki-foreground)"> (</span><span style="color:var(--shiki-token-constant)">MY_FONT</span><span style="color:var(--shiki-token-keyword)"> &amp;</span><span style="color:var(--shiki-foreground)"> bold) fontStyle[</span><span style="color:var(--shiki-token-string-expression)">&#x27;font-weight&#x27;</span><span style="color:var(--shiki-foreground)">] </span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-token-string-expression)"> &#x27;bold&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">if</span><span style="color:var(--shiki-foreground)"> (</span><span style="color:var(--shiki-token-constant)">MY_FONT</span><span style="color:var(--shiki-token-keyword)"> &amp;</span><span style="color:var(--shiki-foreground)"> italic) fontStyle[</span><span style="color:var(--shiki-token-string-expression)">&#x27;font-style&#x27;</span><span style="color:var(--shiki-foreground)">] </span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-token-string-expression)"> &#x27;italic&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"><span style="color:var(--shiki-token-function)">applyFont</span><span style="color:var(--shiki-foreground)">(fontStyle);</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>启用 <code>inlineConst</code> 后，示例中的 <code>if</code> 分支能够明确地被压缩工具优化，生成更精简的产物：</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js"><code><span class="line"><span style="color:var(--shiki-foreground)">(() </span><span style="color:var(--shiki-token-keyword)">=&gt;</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-token-string-expression)">  &#x27;use strict&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">  let</span><span style="color:var(--shiki-foreground)"> t </span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-foreground)"> {};</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  t[</span><span style="color:var(--shiki-token-string-expression)">&#x27;font-weight&#x27;</span><span style="color:var(--shiki-foreground)">] </span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-token-string-expression)"> &#x27;bold&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"><span style="color:var(--shiki-token-function)">  applyFont</span><span style="color:var(--shiki-foreground)">(t);</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">})();</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<blockquote>
<p>详见 <a href="/zh/config/experiments#experimentsinlineconst" class="rp-link">experiments.inlineConst 文档</a>，该功能计划在 v1.6 中默认启用。</p>
</blockquote>
<p><code>inlineEnum</code> 会对 TypeScript 的 enums 进行跨模块内联优化，工作原理与 <code>inlineConst</code> 类似。</p>
<div class="rp-codeblock language-ts"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="ts"><code><span class="line"><span style="color:var(--shiki-token-comment)">// types.ts</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> enum</span><span style="color:var(--shiki-token-function)"> Kind</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  A</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  B</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">}</span></span>
<span class="line"><span style="color:var(--shiki-token-comment)">// index.ts</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { Kind } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;./types.ts&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"><span style="color:var(--shiki-token-constant)">console</span><span style="color:var(--shiki-token-function)">.log</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-constant)">Kind</span><span style="color:var(--shiki-foreground)">.</span><span style="color:var(--shiki-token-constant)">A</span><span style="color:var(--shiki-foreground)">);</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>启用 <code>inlineEnum</code> 后：</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js"><code><span class="line"><span style="color:var(--shiki-foreground)">(() </span><span style="color:var(--shiki-token-keyword)">=&gt;</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-token-constant)">  console</span><span style="color:var(--shiki-token-function)">.log</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-constant)">0</span><span style="color:var(--shiki-foreground)">);</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">})();</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>需要注意的是，启用 <code>inlineEnum</code> 后，Rspack 默认会内联所有 enums。如果你希望只内联 const enums，可以参考此 <a href="https://github.com/rstackjs/rstack-examples/tree/main/rspack/inline-const-enum" target="_blank" rel="noopener noreferrer" class="rp-link">示例</a>。</p>
<blockquote>
<p>详见 <a href="/zh/config/experiments#experimentsinlineenum" class="rp-link">experiments.inlineEnum</a>。</p>
</blockquote>
<h3 class="rp-toc-include" id="类型重导出分析"><a href="#类型重导出分析" class="rp-header-anchor rp-link" aria-hidden="true">#</a>类型重导出分析</h3>
<p>在 TypeScript 项目中，类型重导出是一种常见的模式：</p>
<div class="rp-codeblock language-ts"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="ts"><code><span class="line"><span style="color:var(--shiki-token-comment)">// index.ts</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-foreground)"> { MyType } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;./types.ts&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-comment)">// types.ts</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> type</span><span style="color:var(--shiki-token-function)"> MyType</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  name</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> string</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>在之前的版本中，如果你在重导出类型时没有添加 <code>type</code> 修饰符，Rspack 可能会抛出警告，例如 <code>export &#x27;MyType&#x27; (reexported as &#x27;MyType&#x27;) was not found</code>。</p>
<p>这是因为 Rspack 在解析模块时，采用独立的方式处理每个模块，导致类型的导出（例子中的 <code>MyType</code>）被错误识别为一个值而非类型，由于在 <code>./types.ts</code> 中找不到相应的值导出，因此触发了上述警告。</p>
<p>Rspack 1.5 引入了 <a href="/zh/config/experiments#experimentstypereexportspresence" class="rp-link">experiments.typeReexportsPresence</a> 配置，用于改进对 Typescript 类型导出的识别。开启此配置后，Rspack 能够正确识别跨模块分析类型重导出，从而避免误报警告。</p>
<blockquote>
<p>详见 <a href="/zh/config/experiments#experimentstypereexportspresence" class="rp-link">experiments.typeReexportsPresence</a>。</p>
</blockquote>
<h3 class="rp-toc-include" id="内置虚拟模块插件"><a href="#内置虚拟模块插件" class="rp-header-anchor rp-link" aria-hidden="true">#</a>内置虚拟模块插件</h3>
<p>在 Rspack 1.4 中，我们引入了<a href="/zh/blog/announcing-1-4#custom-input-file-system" class="rp-link">自定义 InputFileSystem</a> 功能，配合 <code>webpack-virtual-modules</code> 插件可以支持虚拟模块。然而，当虚拟模块数量较大时，该方式仍然存在性能瓶颈。</p>
<p>为了更好地支持虚拟模块，Rspack 1.5 新增了内置的 <a href="/zh/plugins/rspack/virtual-modules-plugin" class="rp-link">VirtualModulesPlugin</a>，它基于 Rust 实现，将虚拟模块的存储和管理迁移到 Rust 层，有效减少了模块读取和解析的开销，在处理大量虚拟模块时能够保持更好的性能表现。</p>
<p><code>VirtualModulesPlugin</code> 与 <code>webpack-virtual-modules</code> 保持了一致的 API 设计，以便你可以轻松地迁移：</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { rspack } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;@rspack/core&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  plugins</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">    new</span><span style="color:var(--shiki-token-constant)"> rspack</span><span style="color:var(--shiki-token-function)">.</span><span style="color:var(--shiki-token-constant)">experiments</span><span style="color:var(--shiki-token-function)">.VirtualModulesPlugin</span><span style="color:var(--shiki-foreground)">({</span></span>
<span class="line"><span style="color:var(--shiki-token-string-expression)">      &#x27;src/generated/config.js&#x27;</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;export default { version: &quot;1.0.0&quot; };&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    })</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  ]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<blockquote>
<p>感谢我们的社区伙伴 <a href="https://github.com/nilptr" target="_blank" rel="noopener noreferrer" class="rp-link">@nilptr</a> 的<a href="https://github.com/web-infra-dev/rspack/pull/11021" target="_blank" rel="noopener noreferrer" class="rp-link">贡献</a>。</p>
</blockquote>
<h3 class="rp-toc-include" id="模块联邦运行时提升"><a href="#模块联邦运行时提升" class="rp-header-anchor rp-link" aria-hidden="true">#</a>模块联邦运行时提升</h3>
<p>此前 Module Federation 的运行时是通过在入口模块打补丁的形式运行起来的。新版的 Module Federation 插件通过将自己的运行时代码和 Rspack 的运行时代码合并，同时将 Module Federation 运行时代码提升到了运行时 chunk 中。这样能在应用启动前就将 Module Federation 的运行时提前准备好了。</p>
<p>这样改动带来如下收益：</p>
<ol>
<li>在多入口的场景下产物尺寸减少</li>
<li>修复了 Module Federation 初始化出错的问题</li>
<li>Module Federation 可以提取到运行时 chunk 中</li>
<li>提供一套基于 hook 的插件体系</li>
</ol>
<p>下面是一个演示项目在使用新版 Module Federation 插件所带来的产物体积优化对比。</p>
<div class="rp-table-scroll-container rp-scrollbar"><table><thead><tr><th style="text-align:left">配置</th><th style="text-align:right">Before</th><th style="text-align:right">After</th><th style="text-align:right">优化</th></tr></thead><tbody><tr><td style="text-align:left">Multiple Entries (default)</td><td style="text-align:right">210kb</td><td style="text-align:right">210kb</td><td style="text-align:right"><code>0%</code></td></tr><tr><td style="text-align:left">Multiple Entries + runtimeChunk: true</td><td style="text-align:right">210kb</td><td style="text-align:right">150kb</td><td style="text-align:right"><code>-29%</code></td></tr><tr><td style="text-align:left">Multiple Entries + runtimeChunk: &#x27;single&#x27;</td><td style="text-align:right">210kb</td><td style="text-align:right">70kb</td><td style="text-align:right"><code>-67%</code></td></tr></tbody></table></div>
<p>关于本次 Module Federation 插件的改动详情，请参阅 <a href="https://gist.github.com/ScriptedAlchemy/a71ccbdfb933e8a4cd0131801a2c26b5#file-hoisted-runtime-internal-md" target="_blank" rel="noopener noreferrer" class="rp-link">这里</a>。</p>
<h3 class="rp-toc-include" id="安装体积优化"><a href="#安装体积优化" class="rp-header-anchor rp-link" aria-hidden="true">#</a>安装体积优化</h3>
<p>自 1.4 以来，我们做了一系列优化来降低 Rspack 的安装体积，安装包大小从 Rspack 1.4.0 的 <code>63.7MB</code> 减少到了 Rspack 1.5.0 的 <code>49.9MB</code>。</p>
<p><img src="https://assets.rspack.rs/rspack/assets/rspack-v1-5-rspack-install-size.png" alt="binary-size-by-dates"/></p>
<p>其中几个效果显著的优化点：</p>
<ul>
<li>通过调整 <a href="https://github.com/web-infra-dev/rspack/pull/11077" target="_blank" rel="noopener noreferrer" class="rp-link">编译参数</a> 减少 5MB。</li>
<li>通过优化上游依赖 <a href="https://github.com/wasmerio/wasmer/pull/5621/files" target="_blank" rel="noopener noreferrer" class="rp-link">wasmer</a> 和 <a href="https://github.com/swc-project/swc/pull/10638" target="_blank" rel="noopener noreferrer" class="rp-link">SWC</a> 减少 3MB。</li>
<li>通过控制 <a href="https://github.com/web-infra-dev/rspack/pull/10965" target="_blank" rel="noopener noreferrer" class="rp-link">feature 开关</a> 减少 2MB。</li>
<li>通过优化 <a href="https://github.com/browserslist/browserslist-rs/pull/32" target="_blank" rel="noopener noreferrer" class="rp-link">browserlist-rs</a> 的数据结构减少 2MB。</li>
</ul>
<p>为了进一步优化安装体积，我们集成了 <a href="https://github.com/web-infra-dev/rspack/blob/main/.github/actions/binary-limit/action.yml" target="_blank" rel="noopener noreferrer" class="rp-link">自动体积检查</a> 到日常工作流中，持续关注该指标变化。</p>
<h3 class="rp-toc-include" id="seal-阶段性能优化"><a href="#seal-阶段性能优化" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Seal 阶段性能优化</h3>
<p>在构建性能方面，Rspack 1.5 针对 Seal 阶段（代码生成和优化的阶段）进行了大量优化，通过优化数据结构、提升并行度、增加热点代码缓存等手段，提升了大型项目的构建性能。得益于并行化优化，在多核机器上性能提升更为显著。</p>
<p>以字节跳动的某大型应用为例，该项目包含约 40,000 个模块，整体 Seal 阶段耗时降低约 50%，各主要阶段均有显著优化：</p>
<div class="rp-table-scroll-container rp-scrollbar"><table><thead><tr><th>阶段</th><th style="text-align:right">v1.4.0</th><th style="text-align:right">v1.5.0</th><th style="text-align:right">优化</th></tr></thead><tbody><tr><td>Flag dependency exports</td><td style="text-align:right">394ms</td><td style="text-align:right">181ms</td><td style="text-align:right"><code>-54%</code></td></tr><tr><td>Flag dependency usage</td><td style="text-align:right">1828ms</td><td style="text-align:right">454ms</td><td style="text-align:right"><code>-75%</code></td></tr><tr><td>Code splitting</td><td style="text-align:right">2019ms</td><td style="text-align:right">777ms</td><td style="text-align:right"><code>-62%</code></td></tr><tr><td>Bundle splitting</td><td style="text-align:right">1588ms</td><td style="text-align:right">712ms</td><td style="text-align:right"><code>-55%</code></td></tr><tr><td>Module concatenation</td><td style="text-align:right">2645ms</td><td style="text-align:right">616ms</td><td style="text-align:right"><code>-76%</code></td></tr><tr><td>Content hash calculation</td><td style="text-align:right">881ms</td><td style="text-align:right">404ms</td><td style="text-align:right"><code>-54%</code></td></tr></tbody></table></div>
<h2 class="rp-toc-include" id="其他"><a href="#其他" class="rp-header-anchor rp-link" aria-hidden="true">#</a>其他</h2>
<h3 class="rp-toc-include" id="不再支持-nodejs-16"><a href="#不再支持-nodejs-16" class="rp-header-anchor rp-link" aria-hidden="true">#</a>不再支持 Node.js 16</h3>
<p>鉴于 Node.js 16 已于 2023 年 9 月 11 日停止维护，同时众多社区 npm 包（如 <code>webpack-dev-server</code>、<code>css-loader</code>、<code>sass-loader</code> 等）也相继停止了对 Node.js 16 的支持，为了降低维护开销，Rspack 1.5 将不再支持 Node.js 16。</p>
<p>各包的 Node.js 版本要求变化：</p>
<div class="rp-table-scroll-container rp-scrollbar"><table><thead><tr><th>包名</th><th style="text-align:right">v1.4</th><th style="text-align:right">v1.5</th></tr></thead><tbody><tr><td>@rspack/core</td><td style="text-align:right"><code>&gt;=16.0.0</code></td><td style="text-align:right"><code>&gt;=18.12.0</code></td></tr><tr><td>@rspack/cli</td><td style="text-align:right"><code>&gt;=18.12.0</code></td><td style="text-align:right"><code>&gt;=18.12.0</code></td></tr><tr><td>@rspack/dev-server</td><td style="text-align:right"><code>&gt;=18.12.0</code></td><td style="text-align:right"><code>&gt;=18.12.0</code></td></tr><tr><td>@rsbuild/core</td><td style="text-align:right"><code>&gt;=16.10.0</code></td><td style="text-align:right"><code>&gt;=18.12.0</code></td></tr></tbody></table></div>
<div class="rp-callout rp-callout--tip"><div class="rp-callout__title">Tip</div><div class="rp-callout__content"><p>
⚠️ 这是一个破坏性变更。如果你目前使用的是 Node.js 16，需要升级到 Node.js 18.12.0 或更高版本才能使用 Rspack 1.5。</p></div></div>
<p>当前还使用 Node.js 16 的项目，请按照以下步骤进行升级：</p>
<ol>
<li><strong>升级 Node.js 版本</strong>：建议升级到 Node.js 18.12.0 或更高版本（推荐使用 Node.js 22 LTS）</li>
<li><strong>更新 CI/CD 配置</strong>：请相应地更新你的持续集成配置，确保使用兼容的 Node.js 版本</li>
</ol>
<h3 class="rp-toc-include" id="resolver-javascript-api"><a href="#resolver-javascript-api" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Resolver JavaScript API</h3>
<p>为了让 Rspack 用户能够更便捷地使用 Rspack 的模块解析功能，我们已将 <a href="https://github.com/rstackjs/rspack-resolver" target="_blank" rel="noopener noreferrer" class="rp-link">rspack-resolver</a> 集成到 Rspack 的 JavaScript API 中，它提供了类似 <a href="https://github.com/webpack/enhanced-resolve" target="_blank" rel="noopener noreferrer" class="rp-link">enhanced-resolve</a> 的模块解析能力。</p>
<p>使用方法请参阅 <a href="/zh/api/javascript-api/resolver#resolver-api" class="rp-link">Resolver API 文档</a>。</p>
<h3 class="rp-toc-include" id="稳定化-lazy-compilation"><a href="#稳定化-lazy-compilation" class="rp-header-anchor rp-link" aria-hidden="true">#</a>稳定化 lazy compilation</h3>
<p>经过充分验证，<a href="/zh/config/experiments#experimentslazycompilation" class="rp-link">experiments.lazyCompilation</a> 配置项已从实验性特性升级为稳定特性，并移动到了 Rspack 配置顶层：</p>
<div class="rp-codeblock language-diff"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="diff" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-foreground)">export default {</span></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">- experiments: {</span></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">-   lazyCompilation: true,</span></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">- },</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+ lazyCompilation: true,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<blockquote>
<p>原有的 <code>experiments.lazyCompilation</code> 配置仍然可以继续使用，但会打印一条废弃警告。</p>
</blockquote>
<h3 class="rp-toc-include" id="废弃的选项"><a href="#废弃的选项" class="rp-header-anchor rp-link" aria-hidden="true">#</a>废弃的选项</h3>
<p>Rspack 的 <a href="/zh/config/experiments#experimentstoplevelawait" class="rp-link">experiments.topLevelAwait</a> 选项用于控制对 top level await 的支持，一直以来都是默认开启的。经过观察，我们发现没有实际场景需要关闭 top level await 支持，因此我们决定废弃这个选项，并计划在 Rspack 2.0 中移除它，届时将无法禁用 top level await 支持。</p>
<h2 class="rp-toc-include" id="rstack-进展"><a href="#rstack-进展" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rstack 进展</h2>
<p><a href="/zh/guide/start/ecosystem#rstack" class="rp-link">Rstack</a> 是一个以 Rspack 为核心的 JavaScript 统一工具链，具有优秀的性能和一致的架构。</p>
<h3 class="rp-toc-include" id="rslint-发布"><a href="#rslint-发布" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rslint 发布</h3>
<p><img src="https://assets.rspack.rs/rslint/rslint-banner.png" alt="rslint-banner"/></p>
<p>我们很高兴地宣布 <a href="https://rslint.rs/" target="_blank" rel="noopener noreferrer" class="rp-link">Rslint</a> 的发布！
Rslint 是一个 TypeScript 优先的新一代 Linter，由 Go 编写，并基于 typescript-go 提供的类型检查能力。
它起源于 <a href="https://github.com/auvred" target="_blank" rel="noopener noreferrer" class="rp-link">@auvred</a> 开发的 <a href="https://github.com/typescript-eslint/tsgolint" target="_blank" rel="noopener noreferrer" class="rp-link">tsgolint</a>，并在此基础上进行了扩展和优化。</p>
<p>Rslint 目前支持如下功能：</p>
<ul>
<li>ESLint 风格的配置与指令：几乎无缝上手</li>
<li>IDE 支持：提供 VS Code 插件，支持 Cursor、Trae 等 IDE</li>
<li>自动修复：<code>rslint --fix</code> 一键修复代码问题</li>
<li>规则支持：已实现 50+ 条 <code>@typescript-eslint</code> 规则</li>
<li>测试验证：运行原始 <code>typescript-eslint</code> 测试套件，确保规则正确性</li>
</ul>
<p>Rslint 仍处于早期阶段，我们正在积极开发更多功能和规则支持。欢迎大家尝试使用，并给予宝贵的反馈，帮助我们一起打磨 Rslint！</p>
<h3 class="rp-toc-include" id="rsbuild-15"><a href="#rsbuild-15" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rsbuild 1.5</h3>
<p>开箱即用一直是 Rsbuild 的核心设计理念。在 Rsbuild 1.5 中，我们默认启用了多项 Rspack 的最新特性，带来更优秀的构建性能，包括：</p>
<ul>
<li>启用 <a href="/zh/config/lazy-compilation" class="rp-link">lazyCompilation</a> 来按需编译动态导入的模块，这可以提升开发服务器的启动速度。</li>
<li>启用 <a href="/zh/config/experiments#experimentslazybarrel" class="rp-link">lazyBarrel</a> 来优化 barrel 文件的构建速度，减少不必要的模块解析。</li>
<li>启用 <a href="/zh/config/experiments#experimentsinlineenum" class="rp-link">inlineEnum</a> 来内联 TypeScript 枚举，这可以减少枚举被编译后的包体积。</li>
<li>启用 <a href="/zh/config/experiments#experimentsinlineenum" class="rp-link">typeReexportsPresence</a> 来正确识别 TypeScript 类型重导出，提升类型处理的准确性。</li>
</ul>
<blockquote>
<p>将 Rsbuild 升级至最新版本后，上述特性将默认启用，无需任何额外配置。</p>
</blockquote>
<p>Rsbuild 1.5 还新增了 <a href="https://rsbuild.rs/zh/config/output/module" target="_blank" rel="noopener noreferrer" class="rp-link">output.module</a> 选项，用于输出 ES modules 格式的构建产物。</p>
<p>目前该选项针对 Node.js bundles 提供了 ESM 格式支持，未来我们将继续增加对 web 应用 ESM 格式的支持。</p>
<div class="rp-codeblock language-ts"><div class="rp-codeblock__title">rsbuild.config.ts</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="ts" data-title="rsbuild.config.ts"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  output</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    target</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;node&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    module</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> true</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h3 class="rp-toc-include" id="rslib-012"><a href="#rslib-012" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rslib 0.12</h3>
<p>在 Rslib 0.12 版本中，我们在项目模板中集成了 Rstest 测试框架。如果需要，你可以使用 Rstest 来测试你的库项目，通过统一的 Rstack 工具链进行开发和测试。</p>
<p><img src="https://assets.rspack.rs/rspack/assets/rspack-v1-5-rslib-using-rstest.png" alt="Using Rstest"/></p>
<p>此外，我们正在积极设计并开发全新的 ESM 产物生成方案，旨在提供类似 esbuild 和 Rollup 的 ESM 产物质量，同时保持与 webpack 一致的 interop 行为以确保正确性。详见 <a href="https://jserfeng.github.io/interop-test/by-test-case" target="_blank" rel="noopener noreferrer" class="rp-link">interop 测试</a>。</p>
<h3 class="rp-toc-include" id="rspress-20-beta"><a href="#rspress-20-beta" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rspress 2.0 beta</h3>
<p>Rspress 2.0 目前处于 beta 阶段，开发工作接近尾声，我们计划在两个月内发布正式版本。</p>
<p>最新 beta 版本新增了 Markdown 文本复制组件，方便用户将文档内容提供给大模型进行分析和处理，你可以在各个 Rstack 文档站点体验这个功能：</p>
<p><img src="https://assets.rspack.rs/rspack/assets/rspack-v1-5-rspress-plugin-llms-ui.png" alt="plugin-llms Demo"/></p>
<blockquote>
<p>该功能基于 @rspress/plugin-llms 插件实现，自动生成符合 <a href="https://llmstxt.org/" target="_blank" rel="noopener noreferrer" class="rp-link">llms.txt</a> 标准的文件，使用方法请参考 <a href="https://v2.rspress.rs/plugin/official-plugins/llms" target="_blank" rel="noopener noreferrer" class="rp-link">@rspress/plugin-llms 文档</a>。</p>
</blockquote>
<h3 class="rp-toc-include" id="rsdoctor-12"><a href="#rsdoctor-12" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rsdoctor 1.2</h3>
<p>Rsdoctor 1.2 版本带来了多项重要更新，新增了对聚合模块的精确分析能力，以及带来全新的 Treemap 视图。这些功能提升了构建产物分析的准确性和可视化体验，可以帮助你更好地理解和优化项目的打包产物。</p>
<p>请查看 <a href="https://rsdoctor.rs/zh/blog/release/release-note-1_2" target="_blank" rel="noopener noreferrer" class="rp-link">Rsdoctor 1.2 发布博客</a> 了解更多。</p>
<h3 class="rp-toc-include" id="rstest-02"><a href="#rstest-02" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rstest 0.2</h3>
<p>经过两个月的持续迭代和 10 多个版本的优化，Rstest 0.2 在功能和稳定性方面都有了显著改进，带来以下新特性：</p>
<ul>
<li><strong>Mock API</strong>：Rstest 现在提供了完整的 <a href="https://rstest.rs/api/rstest/mockModules" target="_blank" rel="noopener noreferrer" class="rp-link">mock API</a>，用于在测试环境中替换模块的实际实现，支持对 ES 模块进行模拟操作。</li>
<li><strong>Watch 模式优化</strong>：在 watch 模式下，Rstest 现在支持增量重新运行。当测试文件或其依赖的模块发生变化时，Rstest 会只重新运行相关的测试文件，从而提升测试执行效率。</li>
<li><strong>CLI 快捷键</strong>：watch 模式现在提供了键盘快捷键，你可以使用快捷键来执行各种常用操作。</li>
</ul>
<p><img src="https://assets.rspack.rs/rspack/assets/rspack-v1-5-rstest-cli-shortcuts.png" alt="Rstest 快捷键"/></p><!--/$-->]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Rspack 1.4 发布公告]]></title>
            <link>https://rspack.rs/zh/blog/announcing-1-4</link>
            <guid isPermaLink="false">/zh/blog/announcing-1-4</guid>
            <pubDate>Thu, 26 Jun 2025 16:00:00 GMT</pubDate>
            <description><![CDATA[Rspack 1.4 版本发布，支持在浏览器中运行、默认启用增量构建，同时集成更快的 SWC、生成更小的构建产物，并引入了 `CssChunkingPlugin` 等新功能。]]></description>
            <content:encoded><![CDATA[<!--$--><p><em>2025 年 6 月 26 日</em></p>
<h1 class="rp-toc-include" id="rspack-14-发布公告"><a href="#rspack-14-发布公告" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rspack 1.4 发布公告<!-- --> </h1><div class="rp-not-doc rp-llms-container"><button class="rp-not-doc rp-llms-button rp-llms-copy-button"><div class="rp-llms-copy-button__icon-wrapper"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-llms-copy-button__icon-success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-llms-copy-button__icon-copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg></div><span>复制 Markdown</span></button><button class="rp-llms-button rp-llms-view-options__trigger "><svg width="1em" height="1em" viewBox="0 0 32 32" class="rp-llms-view-options__arrow "><path fill="currentColor" d="M16 22 6 12l1.4-1.4 8.6 8.6 8.6-8.6L26 12z"></path></svg></button></div>
<p><img src="https://assets.rspack.rs/rspack/rspack-banner-v1-4.png" alt="Rspack 1.4"/></p>
<hr/>
<p>Rspack 1.4 已经正式发布！</p>
<p>值得关注的变更如下：</p>
<ul>
<li>新功能<!-- -->
<ul>
<li><a href="#%E5%9C%A8%E6%B5%8F%E8%A7%88%E5%99%A8%E4%B8%AD%E8%BF%90%E8%A1%8C" class="rp-link">在浏览器中运行</a></li>
<li><a href="#%E6%9B%B4%E5%BF%AB%E7%9A%84-swc" class="rp-link">更快的 SWC</a></li>
<li><a href="#%E6%9B%B4%E5%B0%8F%E7%9A%84%E6%9E%84%E5%BB%BA%E4%BA%A7%E7%89%A9" class="rp-link">更小的构建产物</a></li>
<li><a href="#%E9%BB%98%E8%AE%A4%E5%90%AF%E7%94%A8%E5%A2%9E%E9%87%8F%E6%9E%84%E5%BB%BA" class="rp-link">默认启用增量构建</a></li>
<li><a href="#%E6%96%B0%E5%A2%9E-csschunkingplugin" class="rp-link">新增 CssChunkingPlugin</a></li>
<li><a href="#%E5%A2%9E%E5%BC%BA-lazy-compilation" class="rp-link">增强 lazy compilation</a></li>
<li><a href="#%E8%87%AA%E5%AE%9A%E4%B9%89%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F" class="rp-link">自定义文件系统</a></li>
<li><a href="#%E6%80%A7%E8%83%BD%E5%88%86%E6%9E%90%E5%B7%A5%E5%85%B7" class="rp-link">性能分析工具</a></li>
</ul>
</li>
<li>Rstack 进展<!-- -->
<ul>
<li><a href="#rsbuild-14" class="rp-link">Rsbuild 1.4</a></li>
<li><a href="#rslib-010" class="rp-link">Rslib 0.10</a></li>
<li><a href="#rspress-20-beta" class="rp-link">Rspress 2.0 beta</a></li>
<li><a href="#rsdoctor-mcp" class="rp-link">Rsdoctor MCP</a></li>
<li><a href="#rstest-%E5%8F%91%E5%B8%83" class="rp-link">Rstest 发布</a></li>
</ul>
</li>
<li>生态系统<!-- -->
<ul>
<li><a href="#next-rspack" class="rp-link">next-rspack</a></li>
<li><a href="#kmi" class="rp-link">Kmi</a></li>
</ul>
</li>
<li>升级指南</li>
</ul>
<h2 class="rp-toc-include" id="新功能"><a href="#新功能" class="rp-header-anchor rp-link" aria-hidden="true">#</a>新功能</h2>
<h3 class="rp-toc-include" id="在浏览器中运行"><a href="#在浏览器中运行" class="rp-header-anchor rp-link" aria-hidden="true">#</a>在浏览器中运行</h3>
<p>从 Rspack 1.4 开始，我们正式引入了 Wasm target 支持，这意味着 Rspack 现在可以在浏览器环境中运行，包括 <a href="https://stackblitz.com/" target="_blank" rel="noopener noreferrer" class="rp-link">StackBlitz</a>（<a href="https://blog.stackblitz.com/posts/introducing-webcontainers/" target="_blank" rel="noopener noreferrer" class="rp-link">WebContainers</a>）等在线平台。这使得开发者无需配置本地环境，即可快速创建原型、分享代码示例。</p>
<p>你可以直接体验我们提供的 <a href="https://stackblitz.com/~/github.com/rstackjs/rsbuild-stackblitz-example" target="_blank" rel="noopener noreferrer" class="rp-link">在线示例</a>，也可以在 <a href="/zh/guide/start/quick-start#使用-stackblitz-在线预览" class="rp-link">这篇文档</a> 中了解 StackBlitz 的使用指南。</p>
<video src="https://assets.rspack.rs/rspack/assets/rspack-v1-4-wasm-target.mp4" autoPlay="" muted="" loop=""></video>
<p>在后续版本中，我们将继续优化 Wasm 版本的使用流程和包体积。</p>
<p>同时我们也在开发 <code>@rspack/browser</code> 包，它是专为浏览器环境设计的版本，允许你直接在任何现代浏览器中使用 Rspack，而无需依赖 WebContainers 或是特定平台。</p>
<h3 class="rp-toc-include" id="更快的-swc"><a href="#更快的-swc" class="rp-header-anchor rp-link" aria-hidden="true">#</a>更快的 SWC</h3>
<p>在过去几个月中，我们与 SWC 团队持续合作，共同优化 JavaScript 工具链的性能和可靠性。经过一段时间的优化，我们很高兴地看到，SWC 的性能取得了显著提升，使 Rspack 用户和所有基于 SWC 的工具都从中受益：</p>
<ul>
<li>JavaScript parser（解析器）的性能提升了 <strong>30%～35%</strong></li>
<li>JavaScript minifier（压缩器）的性能提升了 <strong>10%</strong></li>
</ul>
<img src="https://assets.rspack.rs/rspack/assets/rspack-v1-4-swc-benchmark.png" alt="SWC benchmark"/>
<blockquote>
<p>以上数据来自：<a href="https://codspeed.io/swc-project/swc" target="_blank" rel="noopener noreferrer" class="rp-link">CodSpeed - SWC</a>，对比的基准为 Rspack 1.3 所使用的 SWC 16。</p>
</blockquote>
<h3 class="rp-toc-include" id="更小的构建产物"><a href="#更小的构建产物" class="rp-header-anchor rp-link" aria-hidden="true">#</a>更小的构建产物</h3>
<p>在当前版本中，SWC 加强了死代码消除（DCE）能力，结合 Rspack 强大的 <a href="/zh/guide/optimization/tree-shaking" class="rp-link">tree shaking</a> 功能，使 Rspack 1.4 能够生成体积更小的构建产物。</p>
<p>我们以 <code>react-router</code> 为例进行测试：在源代码中仅引入它的一部分导出，然后对比不同打包工具的构建结果，可以看到 Rspack 生成的包体积最小。</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">src/index.js</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="src/index.js"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { BrowserRouter</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> Routes</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> Route } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;react-router&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-constant)">console</span><span style="color:var(--shiki-token-function)">.log</span><span style="color:var(--shiki-foreground)">(BrowserRouter</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> Routes</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> Route);</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>各个打包工具输出的包体积如下：</p>
<div class="rp-table-scroll-container rp-scrollbar"><table><thead><tr><th>打包工具</th><th>压缩后体积</th><th>Gzipped 后体积</th></tr></thead><tbody><tr><td>Rspack (Rsbuild)</td><td><strong>36.35 kB</strong></td><td><strong>13.26 kB</strong></td></tr><tr><td>webpack</td><td>36.96 kB</td><td>13.37 kB</td></tr><tr><td>Vite</td><td>42.67 kB</td><td>15.67 kB</td></tr><tr><td>Rolldown</td><td>42.74 kB</td><td>15.17 kB</td></tr><tr><td>Rolldown Vite</td><td>43.42 kB</td><td>15.46 kB</td></tr><tr><td>Farm</td><td>43.42 kB</td><td>15.63 kB</td></tr><tr><td>Parcel</td><td>44.62 kB</td><td>16.07 kB</td></tr><tr><td>esbuild</td><td>46.12 kB</td><td>16.63 kB</td></tr><tr><td>Bun</td><td>57.73 kB</td><td>20.8 kB</td></tr></tbody></table></div>
<blockquote>
<p>以上数据来自：<a href="https://github.com/chenjiahan/react-router-tree-shaking-compare" target="_blank" rel="noopener noreferrer" class="rp-link">react-router-tree-shaking-compare</a>。</p>
</blockquote>
<h3 class="rp-toc-include" id="默认启用增量构建"><a href="#默认启用增量构建" class="rp-header-anchor rp-link" aria-hidden="true">#</a>默认启用增量构建</h3>
<p>通过不断的优化迭代，Rspack 的增量构建功能已趋于稳定，在 Rspack 1.4 中，我们将所有阶段的增量优化设为默认开启，这能够显著加快重新构建的速度，HMR 性能通常可提升 <strong>30%-40%</strong>，具体提升幅度因项目而异。</p>
<p>下面是一位用户开启增量构建后的性能对比：</p>
<img src="https://assets.rspack.rs/rspack/assets/rspack-v1-4-incremental-data.png" alt="incremental benchmark" width="760"/>
<p>如果你需要降级到之前的行为，可以设置 <a href="/zh/config/experiments#experimentsincremental" class="rp-link">experiments.incremental</a> 为 <code>&#x27;safe&#x27;</code> ，但我们推荐大部分项目直接使用新的默认配置，以获得最佳性能。</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  experiments</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-token-comment)">    // 降级到之前的行为</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    incremental</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;safe&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h3 class="rp-toc-include" id="新增-csschunkingplugin"><a href="#新增-csschunkingplugin" class="rp-header-anchor rp-link" aria-hidden="true">#</a>新增 CssChunkingPlugin</h3>
<p>Rspack 1.4 新增了实验性的 <a href="/zh/plugins/rspack/css-chunking-plugin" class="rp-link">CssChunkingPlugin</a> 插件，专门用于处理 CSS 代码分割。该插件能够确保样式的加载顺序与源代码中的导入顺序保持一致，避免因 CSS 加载顺序错误而导致的 UI 问题。</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { rspack } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;@rspack/core&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  plugins</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">    new</span><span style="color:var(--shiki-token-constant)"> rspack</span><span style="color:var(--shiki-token-function)">.</span><span style="color:var(--shiki-token-constant)">experiments</span><span style="color:var(--shiki-token-function)">.CssChunkingPlugin</span><span style="color:var(--shiki-foreground)">({</span></span>
<span class="line"><span style="color:var(--shiki-token-comment)">      // ...options</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    })</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  ]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>启用 <code>CssChunkingPlugin</code> 后，CSS 模块的代码分割将完全由该插件处理，<code>optimization.splitChunks</code> 配置将不再对 CSS 模块生效，你可以查看 <a href="/zh/plugins/rspack/css-chunking-plugin" class="rp-link">使用文档</a> 了解更多。</p>
<blockquote>
<p>该插件由 Next.js 的 <a href="https://nextjs.org/docs/app/api-reference/config/next-config-js/cssChunking" target="_blank" rel="noopener noreferrer" class="rp-link">CSS Chunking</a> 功能启发而来，感谢 Next.js 团队在这一领域的创新。</p>
</blockquote>
<h3 class="rp-toc-include" id="增强-lazy-compilation"><a href="#增强-lazy-compilation" class="rp-header-anchor rp-link" aria-hidden="true">#</a>增强 lazy compilation</h3>
<p>Rspack 现已支持在 <code>MultiCompiler</code> 中启用 lazy compilation，这意味着当你在单次构建中使用多份 Rspack 配置时，可以为不同的 compiler 实例独立设置各自的 <a href="/zh/config/experiments#experimentslazycompilation" class="rp-link">lazyCompilation 选项</a>。</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> [</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    target</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;web&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    experiments</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-token-comment)">      // enable lazy compilation for client</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      lazyCompilation</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> true</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    target</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;node&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    experiments</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-token-comment)">      // disable lazy compilation for server</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      lazyCompilation</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> false</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">];</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h3 class="rp-toc-include" id="自定义文件读取系统"><a href="#自定义文件读取系统" class="rp-header-anchor rp-link" aria-hidden="true">#</a>自定义文件读取系统</h3>
<p>Rspack 现在允许你自定义 <code>compiler.inputFileSystem</code>（编译器的文件读取系统），该功能可以通过配置 <a href="/zh/config/experiments#experimentsuseinputfilesystem" class="rp-link">experiments.useInputFileSystem</a> 开启，典型的使用场景包括：</p>
<ul>
<li>在浏览器中使用 <a href="https://github.com/streamich/memfs" target="_blank" rel="noopener noreferrer" class="rp-link">memfs</a> 代替默认的文件读取系统。</li>
<li>搭配 <a href="https://www.npmjs.com/package/webpack-virtual-modules" target="_blank" rel="noopener noreferrer" class="rp-link">webpack-virtual-modules 插件</a> 来支持虚拟模块。</li>
</ul>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> VirtualModulesPlugin </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;webpack-virtual-modules&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  entry</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;./virtualEntry.js&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  plugins</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">    new</span><span style="color:var(--shiki-token-function)"> VirtualModulesPlugin</span><span style="color:var(--shiki-foreground)">({</span></span>
<span class="line"><span style="color:var(--shiki-token-string-expression)">      &#x27;virtualEntry.js&#x27;</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> `console.log(&#x27;virtual entry&#x27;)`</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    })</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  ]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  experiments</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    useInputFileSystem</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span><span style="color:var(--shiki-token-string-expression)">/virtualEntry\.js</span><span style="color:var(--shiki-token-keyword)">$</span><span style="color:var(--shiki-token-string-expression)">/</span><span style="color:var(--shiki-foreground)">]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>由于自定义的 <code>inputFileSystem</code> 是通过 JavaScript 实现的，可能导致性能下降。为了缓解这个问题，<code>useInputFileSystem</code> 允许你传入一个正则表达式数组，过滤哪些文件需要从自定义的 <code>inputFileSystem</code> 读取，避免因替换原生文件系统而导致的性能开销。</p>
<p>未来我们还计划在 Rspack 中内置虚拟模块支持，从而提供更好的性能和使用体验。</p>
<blockquote>
<p>详细用法请参考 <a href="/zh/config/experiments#experimentsuseinputfilesystem" class="rp-link">文档</a>。</p>
</blockquote>
<h3 class="rp-toc-include" id="性能分析工具"><a href="#性能分析工具" class="rp-header-anchor rp-link" aria-hidden="true">#</a>性能分析工具</h3>
<p>Rspack 1.4 引入了更精确的 tracing 能力，它可以基于 <a href="https://perfetto.dev/" target="_blank" rel="noopener noreferrer" class="rp-link">perfetto</a> 进行性能分析，用于快速定位构建性能的瓶颈。</p>
<p>你可以通过 <code>RSPACK_PROFILE</code> 环境变量开启 tracing：</p>
<div class="rp-codeblock language-sh"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="sh"><code><span class="line"><span style="color:var(--shiki-foreground)">RSPACK_PROFILE</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-token-string)">OVERVIEW</span><span style="color:var(--shiki-token-function)"> rspack</span><span style="color:var(--shiki-token-string)"> build</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>生成的 <code>rspack.pftrace</code> 文件可在 <a href="https://ui.perfetto.dev/" target="_blank" rel="noopener noreferrer" class="rp-link">ui.perfetto.dev</a> 中进行可视化分析：</p>
<img src="https://assets.rspack.rs/rspack/assets/rspack-v1-4-tracing.png" alt="tracing"/>
<blockquote>
<p>详细的用法请参考 <a href="/zh/contribute/development/tracing" class="rp-link">Tracing 文档</a>。</p>
</blockquote>
<h3 class="rp-toc-include" id="依赖升级"><a href="#依赖升级" class="rp-header-anchor rp-link" aria-hidden="true">#</a>依赖升级</h3>
<p>在 Rspack 1.4 中，我们升级了一些主要依赖的版本，包括：</p>
<ul>
<li>Rspack 现在使用 <a href="https://zod.dev/v4" target="_blank" rel="noopener noreferrer" class="rp-link">Zod v4</a> 来校验配置的正确性。</li>
<li><code>create-rspack</code> 现在提供 <a href="https://biomejs.dev/blog/biome-v2/" target="_blank" rel="noopener noreferrer" class="rp-link">Biome v2</a> 作为可选的代码校验和格式化的工具。</li>
</ul>
<h2 class="rp-toc-include" id="rstack-进展"><a href="#rstack-进展" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rstack 进展</h2>
<p><a href="/zh/guide/start/ecosystem#rstack" class="rp-link">Rstack</a> 是一个以 Rspack 为核心的 JavaScript 统一工具链，具有优秀的性能和一致的架构。</p>
<h3 class="rp-toc-include" id="rsbuild-14"><a href="#rsbuild-14" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rsbuild 1.4</h3>
<p>Rsbuild 1.4 已与 Rspack 1.4 同步发布，值得关注的特性有：</p>
<h4 class="rp-toc-include" id="chrome-devtools-集成"><a href="#chrome-devtools-集成" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Chrome DevTools 集成</h4>
<p>我们引入了全新的 <a href="https://github.com/rstackjs/rsbuild-plugin-devtools-json" target="_blank" rel="noopener noreferrer" class="rp-link">rsbuild-plugin-devtools-json</a> 插件，通过该插件，你可以无缝集成 Chrome DevTools 的 <a href="https://chromium.googlesource.com/devtools/devtools-frontend/+/main/docs/ecosystem/automatic_workspace_folders.md" target="_blank" rel="noopener noreferrer" class="rp-link">自动工作区文件夹</a> (Automatic Workspace Folders) 新特性。这意味着你可以在 DevTools 中直接修改和调试源代码，并将改动保存到本地文件系统。</p>
<img src="https://assets.rspack.rs/rspack/assets/rspack-v1-4-rsbuild-plugin-dev-tools-json.png" alt="rsbuild plugin devtools json" width="760"/>
<h4 class="rp-toc-include" id="改进查询参数"><a href="#改进查询参数" class="rp-header-anchor rp-link" aria-hidden="true">#</a>改进查询参数</h4>
<p>Rsbuild 现在内置支持 <code>.js?raw</code> 查询参数，允许你将 JavaScript、TypeScript 和 JSX 文件的原始内容作为文本导入。这在需要将代码作为字符串进行处理的场景下非常有用（例如展示代码示例）。</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> rawJs </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;./script1.js?raw&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> rawTs </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;./script2.ts?raw&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> rawJsx </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;./script3.jsx?raw&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-constant)">console</span><span style="color:var(--shiki-token-function)">.log</span><span style="color:var(--shiki-foreground)">(rawJs); </span><span style="color:var(--shiki-token-comment)">// JS 文件的原始内容</span></span>
<span class="line"><span style="color:var(--shiki-token-constant)">console</span><span style="color:var(--shiki-token-function)">.log</span><span style="color:var(--shiki-foreground)">(rawTs); </span><span style="color:var(--shiki-token-comment)">// TS 文件的原始内容</span></span>
<span class="line"><span style="color:var(--shiki-token-constant)">console</span><span style="color:var(--shiki-token-function)">.log</span><span style="color:var(--shiki-foreground)">(rawJsx); </span><span style="color:var(--shiki-token-comment)">// JSX 文件的原始内容</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h4 class="rp-toc-include" id="改进浏览器兼容性"><a href="#改进浏览器兼容性" class="rp-header-anchor rp-link" aria-hidden="true">#</a>改进浏览器兼容性</h4>
<p>当你在 monorepo 中引用其他包的 JS 文件时，Rsbuild 现在默认会使用 SWC 编译它们，这有助于避免外部依赖引入的浏览器兼容性问题。</p>
<p>以下图为例，假设 app 的构建目标为 ES2016，utils 的构建目标为 ES2021，当 <code>app/src/index.js</code> 引用 <code>utils/dist/index.js</code> 时，SWC 现在会将它降级到 ES2016。</p>
<img src="https://assets.rspack.rs/rspack/assets/rspack-v1-4-rsbuild-monorepo-compile-scope.png" alt="rsbuild monorepo compile scope" width="600"/>
<h3 class="rp-toc-include" id="rslib-010"><a href="#rslib-010" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rslib 0.10</h3>
<p>Rslib 0.10 版本已发布，主要新增了以下功能：</p>
<h4 class="rp-toc-include" id="esm-产物优化"><a href="#esm-产物优化" class="rp-header-anchor rp-link" aria-hidden="true">#</a>ESM 产物优化</h4>
<p>Rslib 现在默认生成更简洁清晰、体积更小的 ESM 产物。</p>
<img src="https://assets.rspack.rs/rspack/assets/rspack-v1-4-rslib-esm.png" alt="rslib esm" width="700"/>
<h4 class="rp-toc-include" id="构建-vue-组件库"><a href="#构建-vue-组件库" class="rp-header-anchor rp-link" aria-hidden="true">#</a>构建 Vue 组件库</h4>
<p>通过引入 <a href="https://github.com/rstackjs/rsbuild-plugin-unplugin-vue" target="_blank" rel="noopener noreferrer" class="rp-link">rsbuild-plugin-unplugin-vue</a> 插件，你可以使用 Rslib 生成 Vue 组件库的 bundleless 产物。</p>
<div class="rp-codeblock language-ts"><div class="rp-codeblock__title">rslib.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="ts" data-title="rslib.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { defineConfig } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;@rslib/core&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { pluginUnpluginVue } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;rsbuild-plugin-unplugin-vue&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-token-function)"> defineConfig</span><span style="color:var(--shiki-foreground)">({</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  plugins</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span><span style="color:var(--shiki-token-function)">pluginUnpluginVue</span><span style="color:var(--shiki-foreground)">()]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  lib</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      format</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;esm&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      bundle</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> false</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      output</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        target</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;web&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  ]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">});</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h4 class="rp-toc-include" id="输出-iife-格式"><a href="#输出-iife-格式" class="rp-header-anchor rp-link" aria-hidden="true">#</a>输出 IIFE 格式</h4>
<p>Rslib 现在可以生成 <a href="https://rslib.rs/zh/guide/basic/output-format#iife" target="_blank" rel="noopener noreferrer" class="rp-link">IIFE 格式</a> 的产物，将代码包裹在函数表达式中。</p>
<img src="https://assets.rspack.rs/rspack/assets/rspack-v1-4-rslib-iife.png" alt="rslib iife" width="700"/>
<blockquote>
<p>阅读 <a href="https://rslib.rs/blog/introducing-rslib" target="_blank" rel="noopener noreferrer" class="rp-link">博客</a> 进一步了解 Rslib。</p>
</blockquote>
<h3 class="rp-toc-include" id="rspress-20-beta"><a href="#rspress-20-beta" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rspress 2.0 beta</h3>
<p>我们正在积极开发 <a href="https://github.com/web-infra-dev/rspress" target="_blank" rel="noopener noreferrer" class="rp-link">Rspress 2.0</a>，并发布了多个 beta 版本。目前，我们已完成大部分代码重构工作，并在 Rspress 2.0 中默认集成 <a href="https://shiki.style/" target="_blank" rel="noopener noreferrer" class="rp-link">Shiki</a> 来提供更强大的代码高亮功能。</p>
<p>同时，我们正在开发全新的主题，预览效果如下：</p>
<img src="https://assets.rspack.rs/rspack/assets/rspack-v1-4-rspress-preview.png" alt="rspress theme preview" width="800"/>
<h3 class="rp-toc-include" id="rsdoctor-mcp"><a href="#rsdoctor-mcp" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rsdoctor MCP</h3>
<p>Rsdoctor 推出了 <a href="https://rsdoctor.rs/zh/guide/start/mcp" target="_blank" rel="noopener noreferrer" class="rp-link">@rsdoctor/mcp-server</a>，结合大模型来帮助你更好地分析构建数据。它能调用 Rsdoctor 的本地构建分析数据，提供智能的分析和优化建议。</p>
<p>Rsdoctor MCP 提供产物分析、依赖分析、产物优化建议和构建优化建议，能够分析产物的体积构成、依赖关系、重复依赖，并针对产物体积优化、代码分割以及构建性能提供相应的优化建议。</p>
<video src="https://assets.rspack.rs/rspack/assets/rspack-v1-4-rsdoctor-mcp.mp4" autoPlay="" muted="" loop=""></video>
<h3 class="rp-toc-include" id="rstest-发布"><a href="#rstest-发布" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rstest 发布</h3>
<p><a href="https://github.com/web-infra-dev/rstest" target="_blank" rel="noopener noreferrer" class="rp-link">Rstest</a> 是一个全新的基于 Rspack 的测试框架，它为 Rspack 生态提供了全面、一流的支持，能够轻松集成到现有的 Rspack 项目中，提供与 Jest 兼容的 API。</p>
<p>在这个月，我们发布了 Rstest 的 v0.0.3 版本，初步支持了 Node.js 和 UI 组件的测试，并在我们的 Rsbuild 等多个仓库中接入使用。</p>
<img src="https://assets.rspack.rs/rspack/assets/rspack-v1-4-rstest.png" alt="rstest" width="600"/>
<blockquote>
<p>Rstest 目前仍处于早期阶段，我们建议你再关注一段时间，以确保它能够提供更完整的测试能力。</p>
</blockquote>
<h2 class="rp-toc-include" id="生态系统"><a href="#生态系统" class="rp-header-anchor rp-link" aria-hidden="true">#</a>生态系统</h2>
<h3 class="rp-toc-include" id="next-rspack"><a href="#next-rspack" class="rp-header-anchor rp-link" aria-hidden="true">#</a>next-rspack</h3>
<p>自从 <a href="/zh/blog/rspack-next-partner" class="rp-link">Rspack 加入 Next.js 生态</a> 以来，我们的首要目标是提升 next-rspack 的稳定性和测试覆盖率。</p>
<p>在最新版本中，next-rspack 的功能已基本完善，测试覆盖率达到：</p>
<ul>
<li>生产构建 <strong>99.4%</strong></li>
<li>开发构建 <strong>98.4%</strong></li>
</ul>
<p>接下来，我们计划继续推进测试覆盖率至 100%，并进一步优化 next-rspack 的性能表现。</p>
<img src="https://assets.rspack.rs/rspack/assets/rspack-v1-4-next-rspack.png" alt="next-rspack" width="760"/>
<h3 class="rp-toc-include" id="kmi"><a href="#kmi" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Kmi</h3>
<p><a href="https://github.com/kmijs/kmi" target="_blank" rel="noopener noreferrer" class="rp-link">Kmi</a> 是一个基于 Umi 和 Rspack 的框架，通过集成 Rspack 作为打包工具，Kmi 带来了数倍于 webpack 版本的性能提升。</p>
<p>对于正在使用 Umi 框架的开发者而言，Kmi 提供了一种渐进式的迁移路径，让他们能够在保持项目稳定性的同时，享受 Rspack 带来的性能优势。</p>
<p>更多信息请参考 <a href="https://github.com/kmijs/kmi" target="_blank" rel="noopener noreferrer" class="rp-link">Kmi 仓库</a>。</p>
<h2 class="rp-toc-include" id="升级指南"><a href="#升级指南" class="rp-header-anchor rp-link" aria-hidden="true">#</a>升级指南</h2>
<h3 class="rp-toc-include" id="升级-swc-插件"><a href="#升级-swc-插件" class="rp-header-anchor rp-link" aria-hidden="true">#</a>升级 SWC 插件</h3>
<p>如果你的项目中使用了 SWC Wasm 插件（如 <code>@swc/plugin-emotion</code> 等），需要将插件升级至兼容 <code>swc_core@29</code> 的版本，否则可能因版本不兼容导致构建报错。</p>
<blockquote>
<p>详情请查阅：<a href="/zh/errors/swc-plugin-version" class="rp-link">常见问题 - SWC 插件版本不匹配</a>。</p>
</blockquote>
<h3 class="rp-toc-include" id="lazy-compilation-中间件"><a href="#lazy-compilation-中间件" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Lazy compilation 中间件</h3>
<p>Lazy compilation 中间件的接入方式有所变化，该中间件现在可以从 compiler 实例中自动读取 <a href="/zh/config/experiments#experimentslazycompilation" class="rp-link">lazyCompilation</a> 选项，因此你不再需要手动传入 <code>lazyCompilation</code> 选项。</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { experiments</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> rspack } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;@rspack/core&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { RspackDevServer } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;@rspack/dev-server&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">const</span><span style="color:var(--shiki-token-constant)"> compiler</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-function)"> rspack</span><span style="color:var(--shiki-foreground)">([</span></span>
<span class="line"><span style="color:var(--shiki-token-comment)">  // ...multiple configs</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">]);</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-comment)">// no longer need to pass options to the middleware</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">const</span><span style="color:var(--shiki-token-constant)"> middleware</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-constant)"> experiments</span><span style="color:var(--shiki-token-function)">.lazyCompilationMiddleware</span><span style="color:var(--shiki-foreground)">(compiler);</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">const</span><span style="color:var(--shiki-token-constant)"> server</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-keyword)"> new</span><span style="color:var(--shiki-token-function)"> RspackDevServer</span><span style="color:var(--shiki-foreground)">(</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  {</span></span>
<span class="line"><span style="color:var(--shiki-token-function)">    setupMiddlewares</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> (other) </span><span style="color:var(--shiki-token-keyword)">=&gt;</span><span style="color:var(--shiki-foreground)"> [middleware</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-keyword)"> ...</span><span style="color:var(--shiki-foreground)">other]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  compiler</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">);</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div><!--/$-->]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Rspack 加入 Next.js 生态]]></title>
            <link>https://rspack.rs/zh/blog/rspack-next-partner</link>
            <guid isPermaLink="false">/zh/blog/rspack-next-partner</guid>
            <pubDate>Thu, 10 Apr 2025 10:00:00 GMT</pubDate>
            <description><![CDATA[今天，我们很高兴地推出 next-rspack，这是一个社区驱动的插件，让 Next.js 能够直接使用 Rspack 作为打包工具。]]></description>
            <content:encoded><![CDATA[<!--$--><p><em>2025 年 4 月 10 日</em></p>
<h1 class="rp-toc-include" id="rspack-加入-nextjs-生态"><a href="#rspack-加入-nextjs-生态" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rspack 加入 Next.js 生态<!-- --> </h1><div class="rp-not-doc rp-llms-container"><button class="rp-not-doc rp-llms-button rp-llms-copy-button"><div class="rp-llms-copy-button__icon-wrapper"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-llms-copy-button__icon-success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-llms-copy-button__icon-copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg></div><span>复制 Markdown</span></button><button class="rp-llms-button rp-llms-view-options__trigger "><svg width="1em" height="1em" viewBox="0 0 32 32" class="rp-llms-view-options__arrow "><path fill="currentColor" d="M16 22 6 12l1.4-1.4 8.6 8.6 8.6-8.6L26 12z"></path></svg></button></div>
<p>Rspack 的核心目标之一，是提供卓越的开发体验，并且能够与基于 webpack 的项目实现无缝集成，将迁移成本降至最低。</p>
<p>在 JavaScript 生态中，<a href="https://nextjs.org/" target="_blank" rel="noopener noreferrer" class="rp-link">Next.js</a> 拥有深度定制的 webpack 配置和丰富的插件生态，这使它成为验证 Rspack 兼容性和健壮性的理想选择。通过将 Rspack 集成到 Next.js 中，不仅展示了 Rspack 在复杂项目中的适用性，还为 Next.js 用户提供了一个改善开发体验的替代方案。</p>
<h2 class="rp-toc-include" id="rspack-携手-nextjs"><a href="#rspack-携手-nextjs" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rspack 携手 Next.js</h2>
<p>今天，我们很高兴地推出 <a href="https://www.npmjs.com/package/next-rspack" target="_blank" rel="noopener noreferrer" class="rp-link">next-rspack</a>，这是一个社区驱动的插件，让 Next.js 能够直接使用 Rspack 作为打包工具。对于尚未准备好采用 Turbopack 的团队，这个插件提供了一种高性能、且与 webpack 兼容的替代方案。</p>
<blockquote>
<p>访问我们的 <a href="/zh/guide/tech/next" class="rp-link">文档</a> 或查看官方 <a href="https://github.com/vercel/next.js/tree/canary/examples/with-rspack" target="_blank" rel="noopener noreferrer" class="rp-link">Next.js 示例</a> 开始使用。</p>
</blockquote>
<p>在开发 next-rspack 之前，我们通过创建 <a href="https://github.com/ScriptedAlchemy/rsnext/tree/rspack" target="_blank" rel="noopener noreferrer" class="rp-link">rsnext</a>（一个 Next.js 的分支）探索了集成的可能性，开发出了解决方案的原型。这一早期分支帮助我们验证了可行性，发现了许多边界 case，也让我们意识到，虽然 Rspack 与 webpack 的高度兼容性为我们提供了良好的起点，但实现稳定的集成仍然需要大量的努力和协作。</p>
<h2 class="rp-toc-include" id="与-vercel-的合作"><a href="#与-vercel-的合作" class="rp-header-anchor rp-link" aria-hidden="true">#</a>与 Vercel 的合作</h2>
<p>next-rspack 的推出只是我们与 Vercel 广泛合作的一个方面。这种合作关系不仅限于 Next.js 集成，双方团队还致力于共同改进基础技术，如 <a href="https://swc.rs/" target="_blank" rel="noopener noreferrer" class="rp-link">SWC</a> 和 <a href="https://lightningcss.dev/" target="_blank" rel="noopener noreferrer" class="rp-link">Lightning CSS</a> —— 这些工具在 JavaScript 生态中被广泛采用。</p>
<p>我们共同改进这些核心组件，为开发者创造更好的使用体验、性能和可靠性。这些努力不仅使 Rspack 和 Next.js 受益，也有助于提升整个 JavaScript 生态，让所有参与者都能受益。</p>
<p>为了保证长期可靠，next-rspack 已经集成到 Next.js 的持续集成流程中，这有助于主动发现问题并保持兼容性。尽管仍处于实验阶段，它目前通过了约 96% 的集成测试，这使我们有信心正式发布这一插件。你可以通过 <a href="https://www.arewerspackyet.com/" target="_blank" rel="noopener noreferrer" class="rp-link">arewerspackyet</a> 跟踪最新状态，也可以关注 <a href="https://x.com/rspack_dev" target="_blank" rel="noopener noreferrer" class="rp-link">我们的 Twitter</a> 了解 next-rspack 的最新进展。</p>
<p>对于尚未准备好采用 Turbopack 的团队，next-rspack 提供了一个稳定、高性能的替代方案，具有出色的兼容性和简单的接入过程。</p>
<p>我们由衷感谢 Vercel 的深度合作，以及双方对改进开发者工具体验的共同承诺。我们将持续协作，完善这一插件，共同推动现代 JavaScript 开发的未来。</p>
<h2 class="rp-toc-include" id="当前性能"><a href="#当前性能" class="rp-header-anchor rp-link" aria-hidden="true">#</a>当前性能</h2>
<h3 class="rp-toc-include" id="app-router-用户"><a href="#app-router-用户" class="rp-header-anchor rp-link" aria-hidden="true">#</a>App Router 用户</h3>
<p>目前，使用 <code>next-rspack</code> 的 App Router 实现<strong>比 Turbopack 慢</strong>，甚至可能比 webpack 还慢。这主要是因为某些 <strong>JavaScript 插件</strong> 在 Rust-JavaScript 的跨语言通信中产生了较大的性能开销。</p>
<p>我们已经<strong>实验性地将这些插件移植到 Rust 中</strong>，这极大地提高了性能 —— 大致与 Turbopack 相当。此外，我们正在研究如何解决深度集成带来的长期维护挑战。</p>
<h3 class="rp-toc-include" id="page-router-用户"><a href="#page-router-用户" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Page Router 用户</h3>
<p>Page Router 的情况要乐观得多：</p>
<ul>
<li><strong>开发模式</strong>：比 webpack 快 2 倍</li>
<li><strong>生产模式</strong>：比 webpack 快 1.5 倍</li>
</ul>
<p>高度依赖 webpack 生态的项目在迁移时将更加容易。</p>
<p>我们已经定位出一些限制性能提升的瓶颈，包括显著的 Rust-JavaScript 通信开销、较慢的 <a href="https://nextjs.org/docs/pages/api-reference/config/next-config-js/output#how-it-works" target="_blank" rel="noopener noreferrer" class="rp-link">输出文件追踪</a> 实现，这些问题将在未来得到解决。随着这些预期内的改进，我们预见：</p>
<ul>
<li><strong>开发环境中构建和 HMR 速度提升 5 倍</strong></li>
<li><strong>生产构建速度提升 3 倍</strong></li>
</ul>
<h2 class="rp-toc-include" id="常见问题"><a href="#常见问题" class="rp-header-anchor rp-link" aria-hidden="true">#</a>常见问题</h2>
<h3 class="rp-toc-include" id="它将如何保持支持"><a href="#它将如何保持支持" class="rp-header-anchor rp-link" aria-hidden="true">#</a>它将如何保持支持？</h3>
<p>next-rspack 已集成至 Next.js 的 CI 流程中，这使我们能够及早发现潜在问题并确保高度兼容性。随着 Next.js 与 Rspack 的共同发展，相关支持将不断得到完善。Rspack 团队、Vercel 团队以及开源社区将通力合作，共同支持这一插件。</p>
<h3 class="rp-toc-include" id="谁在维护它"><a href="#谁在维护它" class="rp-header-anchor rp-link" aria-hidden="true">#</a>谁在维护它？</h3>
<p>next-rspack 是一个社区插件，但其开发和集成依赖于 Rspack 团队和 Vercel 团队之间的密切合作，以确保持续的支持和进展。</p>
<h3 class="rp-toc-include" id="这对-turbopack-有影响吗vercel-是否采用了-rspack"><a href="#这对-turbopack-有影响吗vercel-是否采用了-rspack" class="rp-header-anchor rp-link" aria-hidden="true">#</a>这对 Turbopack 有影响吗？Vercel 是否采用了 Rspack？</h3>
<p>Rspack 不会替代 Turbopack。它是为那些拥有大量 webpack 配置、且尚未准备好迁移到 Turbopack 的用户提供的替代解决方案。</p>
<h3 class="rp-toc-include" id="已知的问题有哪些"><a href="#已知的问题有哪些" class="rp-header-anchor rp-link" aria-hidden="true">#</a>已知的问题有哪些？</h3>
<p>截至目前，next-rspack 通过了约 96% 的集成测试，进展可在 <a href="https://www.arewerspackyet.com/" target="_blank" rel="noopener noreferrer" class="rp-link">arewerspackyet</a> 上查看。</p>
<ul>
<li>一些特殊情况和进阶功能可能仍需要临时解决方案或额外支持。即使你没有遇到问题，也欢迎在 <a href="https://github.com/vercel/next.js/discussions/77800" target="_blank" rel="noopener noreferrer" class="rp-link">反馈讨论</a> 中告诉我们你的使用体验。</li>
<li>受当前插件实现方式的限制，App Router 的性能表现不够理想，这方面仍有很大的改进空间。</li>
<li>由于 Rspack 不是 100% 兼容 webpack 的 API，你的一些 webpack 插件可能无法在 Rspack 上顺畅工作，如果你遇到兼容性问题，欢迎向我们反馈。</li>
</ul>
<h3 class="rp-toc-include" id="如何参与贡献"><a href="#如何参与贡献" class="rp-header-anchor rp-link" aria-hidden="true">#</a>如何参与贡献？</h3>
<p>欢迎尝试 next-rspack，报告问题、贡献代码或文档、加入社区讨论。你的任何反馈和贡献都很宝贵。</p>
<h2 class="rp-toc-include" id="未来计划"><a href="#未来计划" class="rp-header-anchor rp-link" aria-hidden="true">#</a>未来计划</h2>
<ul>
<li><strong>提高测试覆盖率</strong>：在下一季度，我们计划将测试覆盖率从当前的 96% 提高到接近 100%。</li>
<li><strong>增强性能</strong>：我们将通过原生插件，探索与 Next.js 的更深层次集成，以提升构建性能。</li>
<li><strong>基于用户反馈迭代</strong>：继续支持来自 Next.js 生态系统的更多社区插件。</li>
<li><strong>完善集成工作流</strong>：建立 Rspack 和 Next.js 之间更加健全的 CI/CD 流程，确保 next-rspack 支持的稳定性和可靠性。</li>
<li><strong>更好的 RSC 支持</strong>：Turbopack 的统一模块图解锁了更快、更简单的 RSC 实现。Rspack 将提供类似的 API，为生态带来一流、高性能的 RSC 支持。</li>
<li><strong>模块联邦支持</strong>：我们正在与 Next.js 团队讨论改进对模块联邦的支持。</li>
</ul>
<p>在 2024 年，稳定性和构建产物完整性是 Rspack 的主要关注点。2025 年，我们将更加关注性能提升和广泛的生态系统。</p>
<p>敬请期待 —— 我们的旅程才刚刚开始。</p><!--/$-->]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Rspack 1.3 发布公告]]></title>
            <link>https://rspack.rs/zh/blog/announcing-1-3</link>
            <guid isPermaLink="false">/zh/blog/announcing-1-3</guid>
            <pubDate>Fri, 28 Mar 2025 16:00:00 GMT</pubDate>
            <description><![CDATA[Rspack 1.3 版本发布，支持检测循环引用、构建 HTTP 模块和引用 AMD 模块，引入全新的 lazy compilation 中间件，以及优化了代码分割性能、产物体积和内存占用。]]></description>
            <content:encoded><![CDATA[<!--$--><p><em>2025 年 3 月 28 日</em></p>
<h1 class="rp-toc-include" id="rspack-13-发布公告"><a href="#rspack-13-发布公告" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rspack 1.3 发布公告<!-- --> </h1><div class="rp-not-doc rp-llms-container"><button class="rp-not-doc rp-llms-button rp-llms-copy-button"><div class="rp-llms-copy-button__icon-wrapper"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-llms-copy-button__icon-success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-llms-copy-button__icon-copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg></div><span>复制 Markdown</span></button><button class="rp-llms-button rp-llms-view-options__trigger "><svg width="1em" height="1em" viewBox="0 0 32 32" class="rp-llms-view-options__arrow "><path fill="currentColor" d="M16 22 6 12l1.4-1.4 8.6 8.6 8.6-8.6L26 12z"></path></svg></button></div>
<p><img src="https://assets.rspack.rs/rspack/rspack-banner-v1-3.png" alt="Rspack 1.3"/></p>
<hr/>
<p>Rspack 1.3 已经正式发布！</p>
<p>值得关注的变更如下：</p>
<ul>
<li>新功能<!-- -->
<ul>
<li><a href="#%E5%BE%AA%E7%8E%AF%E5%BC%95%E7%94%A8%E6%A3%80%E6%B5%8B" class="rp-link">循环引用检测</a></li>
<li><a href="#%E6%9E%84%E5%BB%BA-http-imports" class="rp-link">构建 HTTP imports</a></li>
<li><a href="#lazy-compilation-%E6%94%B9%E8%BF%9B" class="rp-link">Lazy compilation 改进</a></li>
<li><a href="#%E6%94%AF%E6%8C%81-amd-%E6%A8%A1%E5%9D%97" class="rp-link">支持 AMD 模块</a></li>
</ul>
</li>
<li>性能优化<!-- -->
<ul>
<li><a href="#%E4%BB%A3%E7%A0%81%E5%88%86%E5%89%B2%E6%8F%90%E9%80%9F-25" class="rp-link">代码分割提速 25%</a></li>
<li><a href="#%E4%BA%A7%E7%89%A9%E4%BD%93%E7%A7%AF%E4%BC%98%E5%8C%96" class="rp-link">产物体积优化</a></li>
<li><a href="#%E5%86%85%E5%AD%98%E4%BC%98%E5%8C%96" class="rp-link">内存优化</a></li>
</ul>
</li>
<li>Rstack 进展<!-- -->
<ul>
<li><a href="#rsdoctor-10" class="rp-link">Rsdoctor 1.0</a></li>
<li><a href="#rsbuild-13" class="rp-link">Rsbuild 1.3</a></li>
<li><a href="#rslib-06" class="rp-link">Rslib 0.6</a></li>
<li><a href="#rspress-%E5%92%8C-rstest" class="rp-link">Rspress 和 Rstest</a></li>
</ul>
</li>
<li>生态系统<!-- -->
<ul>
<li><a href="#rspeedy-for-lynx" class="rp-link">Rspeedy for Lynx</a></li>
<li><a href="#repack-5" class="rp-link">Re.Pack 5</a></li>
<li><a href="#react-router-v7-%E6%94%AF%E6%8C%81" class="rp-link">React Router v7 支持</a></li>
</ul>
</li>
<li>升级指南<!-- -->
<ul>
<li><a href="#%E6%A8%A1%E5%9D%97%E5%AD%90%E7%B1%BB%E5%9E%8B%E5%8F%98%E6%9B%B4" class="rp-link">模块子类型变更</a></li>
<li><a href="#%E5%8D%87%E7%BA%A7-swc-%E6%8F%92%E4%BB%B6" class="rp-link">升级 SWC 插件</a></li>
</ul>
</li>
</ul>
<h2 class="rp-toc-include" id="新功能"><a href="#新功能" class="rp-header-anchor rp-link" aria-hidden="true">#</a>新功能</h2>
<h3 class="rp-toc-include" id="循环引用检测"><a href="#循环引用检测" class="rp-header-anchor rp-link" aria-hidden="true">#</a>循环引用检测</h3>
<p>Rspack 1.3 新增了一个内置插件 <a href="/zh/plugins/rspack/circular-dependency-rspack-plugin" class="rp-link">CircularDependencyRspackPlugin</a>，用于检测运行时模块之间的循环依赖。</p>
<p>该插件采用 Rust 实现，并与 Rspack 的模块图深度集成，避免了昂贵的数据复制和序列化开销。它通过对每个入口点的模块图执行单次遍历，来检测所有循环依赖，而非独立检查每个模块，因此性能开销更小。</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { rspack } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;@rspack/core&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  plugins</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span><span style="color:var(--shiki-token-keyword)">new</span><span style="color:var(--shiki-token-constant)"> rspack</span><span style="color:var(--shiki-token-function)">.CircularDependencyRspackPlugin</span><span style="color:var(--shiki-foreground)">()]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<blockquote>
<p>特别感谢 <a href="https://github.com/faultyserver" target="_blank" rel="noopener noreferrer" class="rp-link">@faultyserver</a> 贡献了该插件 ❤️</p>
</blockquote>
<h3 class="rp-toc-include" id="构建-http-imports"><a href="#构建-http-imports" class="rp-header-anchor rp-link" aria-hidden="true">#</a>构建 HTTP imports</h3>
<p>在过去的版本中，你可以通过 <a href="/zh/config/externals#externalspresetsweb" class="rp-link">externalsPresets.web</a> 或 <a href="/zh/config/externals#externalspresetswebasync" class="rp-link">externalsPresets.webAsync</a> 选项来导入 HTTP/HTTPS 资源，这种方式仅是将这些资源设置为外部资源，然后让浏览器（或其他平台）在运行时获取它们。</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> pMap </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;https://esm.sh/p-map&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>而全新的 <a href="/zh/config/experiments#experimentsbuildhttp" class="rp-link">experiments.buildHttp</a> 选项提供了一种导入 HTTP/HTTPS 资源的新方式，不是在运行时获取资源，而是在构建时将它们下载到本地缓存中，然后将其打包到输出文件中。</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  experiments</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    buildHttp</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      allowedUris</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span><span style="color:var(--shiki-token-string-expression)">&#x27;https://esm.sh/&#x27;</span><span style="color:var(--shiki-foreground)">]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<blockquote>
<p>查看 <a href="/zh/config/experiments#experimentsbuildhttp" class="rp-link">使用文档</a> 了解更多。</p>
</blockquote>
<h3 class="rp-toc-include" id="lazy-compilation-改进"><a href="#lazy-compilation-改进" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Lazy compilation 改进</h3>
<p>在过去的版本中，当 <a href="/zh/guide/features/lazy-compilation" class="rp-link">lazy compilation</a> 被开启时，Rspack 会启动一个单独的服务器来处理 lazy compilation 相关的请求。这导致了一些问题，例如，开发阶段需要启动两个服务器，并且 lazy compilation 服务器无法与默认的开发服务器共享代理配置和 CORS 配置。</p>
<p>Rspack 1.3 提供了一个全新的 Express 风格的中间件来集成 lazy compilation，以解决上述问题。</p>
<ul>
<li>如果你在使用 <code>@rspack/cli</code> 或 Rsbuild，只需要升级依赖版本即可自动切换到新版中间件。</li>
<li>如果你使用了自定义的开发服务器，则需要集成该中间件来支持 lazy compilation。</li>
</ul>
<p>下面是一个使用 lazy compilation 中间件的示例：</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { rspack } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;@rspack/core&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> config </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;./rspack.config.mjs&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> DevServer </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;webpack-dev-server&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">const</span><span style="color:var(--shiki-token-constant)"> compiler</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-function)"> rspack</span><span style="color:var(--shiki-foreground)">(config);</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">const</span><span style="color:var(--shiki-token-constant)"> middleware</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-constant)"> rspack</span><span style="color:var(--shiki-token-function)">.</span><span style="color:var(--shiki-token-constant)">experiments</span><span style="color:var(--shiki-token-function)">.lazyCompilationMiddleware</span><span style="color:var(--shiki-foreground)">(</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  compiler</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-token-constant)">  config</span><span style="color:var(--shiki-foreground)">.</span><span style="color:var(--shiki-token-constant)">experiments</span><span style="color:var(--shiki-foreground)">.lazyCompilation</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">);</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">const</span><span style="color:var(--shiki-token-constant)"> server</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-keyword)"> new</span><span style="color:var(--shiki-token-function)"> DevServer</span><span style="color:var(--shiki-foreground)">(</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  {</span></span>
<span class="line"><span style="color:var(--shiki-token-function)">    setupMiddlewares</span><span style="color:var(--shiki-foreground)">(other) {</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">      return</span><span style="color:var(--shiki-foreground)"> [middleware</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-keyword)"> ...</span><span style="color:var(--shiki-foreground)">other];</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  compiler</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">);</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h3 class="rp-toc-include" id="支持-amd-模块"><a href="#支持-amd-模块" class="rp-header-anchor rp-link" aria-hidden="true">#</a>支持 AMD 模块</h3>
<p>Rspack 现在允许你通过 <a href="/zh/config/other-options#amd" class="rp-link">amd</a> 选项来开启对 AMD 模块的支持。</p>
<p>与 webpack 默认启用 AMD 模块支持不同，Rspack 选择默认禁用该特性。此功能旨在兼容仍需使用 AMD 格式的 npm 依赖，我们强烈建议开发者优先选用 ES Module 规范的依赖，以便 Rspack 能基于静态模块分析进行更高效的产物体积优化。</p>
<p>添加 <code>amd</code> 选项来开启支持：</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  amd</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-token-comment)">    // ...</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<blockquote>
<p>特别感谢 <a href="https://github.com/nilptr" target="_blank" rel="noopener noreferrer" class="rp-link">@nilptr</a> 贡献了该功能 ❤️</p>
</blockquote>
<h2 class="rp-toc-include" id="性能优化"><a href="#性能优化" class="rp-header-anchor rp-link" aria-hidden="true">#</a>性能优化</h2>
<h3 class="rp-toc-include" id="代码分割提速-25"><a href="#代码分割提速-25" class="rp-header-anchor rp-link" aria-hidden="true">#</a>代码分割提速 25%</h3>
<p>在 Rspack 1.2 中，我们引入了 <a href="/zh/config/experiments#experimentsparallelcodesplitting" class="rp-link">experiments.parallelCodeSplitting</a> 选项来开启新版的代码分割算法。</p>
<p>从 Rspack 1.3 开始，该选项已经默认开启，并使代码分割的速度提升 <strong>25%</strong>。</p>
<h3 class="rp-toc-include" id="产物体积优化"><a href="#产物体积优化" class="rp-header-anchor rp-link" aria-hidden="true">#</a>产物体积优化</h3>
<p>Rspack 1.3 版本引入了对 <a href="/zh/config/output#outputenvironment" class="rp-link">output.environment</a> 选项的完整支持，这允许你指定在 Rspack 生成的运行时代码中可使用的 ECMAScript 特性，能够生成更简短和现代的运行时代码。</p>
<p>默认情况下，Rspack 会解析 <a href="/zh/config/target" class="rp-link">target</a> 配置项，并基于 <code>browserslist</code> 来判断目标环境所支持的 ECMAScript 特性，自动设置 <code>output.environment</code> 子选项的值，从而输出优化后的代码。</p>
<p>例如，当检测到目标环境支持箭头函数时，Rspack 会将 <code>output.environment.arrowFunction</code> 设置为 <code>true</code>，并在生成的代码中使用箭头函数语法。</p>
<div class="rp-codeblock language-diff"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="diff"><code><span class="line"><span style="color:var(--shiki-foreground)">// before</span></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">- __webpack_require__.d = function(exports, definition) {</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-foreground)">// after</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+ __webpack_require__.d = (exports, definition) =&gt; {</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>通过使用目标环境支持的现代 JavaScript 特性，Rspack 能够输出更小的运行时代码。在我们对一个真实大型项目的性能测试中，该优化减少了约 500KB 的产物体积（未经 gzip 压缩）。</p>
<h3 class="rp-toc-include" id="内存优化"><a href="#内存优化" class="rp-header-anchor rp-link" aria-hidden="true">#</a>内存优化</h3>
<p>Rspack 现在在 macOS 上默认使用 <a href="https://github.com/microsoft/mimalloc" target="_blank" rel="noopener noreferrer" class="rp-link">mimalloc</a> v3。这缓解了 macOS 在 rebuild 过程中的一些内存消耗问题。根据一些社区和内部项目的反馈，这将减少 rebuild 时的 RSS 使用量，具体减少的比例因项目大小而异，根据我们的测试，减少的比例<strong>从 10% 到 85% 不等</strong>。</p>
<p>Rspack 1.3 还实现了清理过期缓存的内部机制 <code>maxGenerations</code>。这个参数控制了缓存的存活时间，Rspack 默认将这个值设置为 1，意味着如果特定缓存在下一轮编译中没有被使用，该缓存将会被清除。</p>
<img src="https://assets.rspack.rs/rspack/assets/rspack-v1-3-memory-improve-max-generations.png" width="760" alt="Max generations"/>
<h2 class="rp-toc-include" id="rstack-进展"><a href="#rstack-进展" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rstack 进展</h2>
<img src="https://assets.rspack.rs/rstack/rstack-overview.png" width="760" alt="Rstack"/>
<h3 class="rp-toc-include" id="rsdoctor-10"><a href="#rsdoctor-10" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rsdoctor 1.0</h3>
<p>在经过一年的迭代与验证后，我们正式推出 <a href="https://github.com/web-infra-dev/rsdoctor" target="_blank" rel="noopener noreferrer" class="rp-link">Rsdoctor 1.0</a> —— 一款为 Rspack 生态量身打造的构建分析工具，同时也完全兼容 webpack 生态。</p>
<p>Rsdoctor 致力于成为一站式、智能化的构建分析工具，通过可视化与智能分析，使整个构建流程变得透明、可预测和可优化，从而帮助开发团队精准定位瓶颈、优化性能并提升工程质量。</p>
<p>Rsdoctor 1.0 版本带来了诸多的新特性：</p>
<ul>
<li>全面优化的 UI 界面，使信息展示更直观高效；</li>
<li>通过 Rust 重写耗时较长的数据处理逻辑，分析性能提升超过 20%；</li>
<li>新增模块搜索功能，用于快速分析模块引用关系和模块大小。</li>
</ul>
<blockquote>
<p>参考 <a href="https://rsdoctor.rs/zh/blog/release/release-note-1_0" target="_blank" rel="noopener noreferrer" class="rp-link">Rsdoctor 1.0 发布博客</a> 了解更多。</p>
</blockquote>
<h3 class="rp-toc-include" id="rsbuild-13"><a href="#rsbuild-13" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rsbuild 1.3</h3>
<p>Rsbuild 1.3 已经与 Rspack 1.3 同步发布，值得关注的特性有：</p>
<ul>
<li>支持通过 <a href="https://rsbuild.rs/zh/guide/basic/css-usage#inline" target="_blank" rel="noopener noreferrer" class="rp-link">?inline</a> 查询参数引用 CSS 文件编译后的内容，并将其作为字符串导入：</li>
</ul>
<div class="rp-codeblock language-js"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> inlineCss </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;./style.css?inline&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-constant)">console</span><span style="color:var(--shiki-token-function)">.log</span><span style="color:var(--shiki-foreground)">(inlineCss); </span><span style="color:var(--shiki-token-comment)">// 输出编译后的 CSS 文件内容</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<ul>
<li>支持通过 <a href="https://rsbuild.rs/zh/guide/basic/css-usage#raw" target="_blank" rel="noopener noreferrer" class="rp-link">?raw</a> 查询参数引用 CSS 文件和静态资源的原始内容，并将其作为字符串导入：</li>
</ul>
<div class="rp-codeblock language-js"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> rawSvg </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;./logo.svg?raw&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> rawCss </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;./style.css?raw&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-constant)">console</span><span style="color:var(--shiki-token-function)">.log</span><span style="color:var(--shiki-foreground)">(rawSvg); </span><span style="color:var(--shiki-token-comment)">// 输出 SVG 文件的原始内容</span></span>
<span class="line"><span style="color:var(--shiki-token-constant)">console</span><span style="color:var(--shiki-token-function)">.log</span><span style="color:var(--shiki-foreground)">(rawCss); </span><span style="color:var(--shiki-token-comment)">// 输出 CSS 文件的原始内容</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h3 class="rp-toc-include" id="rslib-06"><a href="#rslib-06" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rslib 0.6</h3>
<p>Rslib 0.6 主要带来以下更新：</p>
<ul>
<li><strong>改进 CJS 产物</strong>：现在 Rslib 的 CJS 产物可以被静态分析，这使得 Node.js 的 ESM 模块可以使用 named import 来引用 CJS 产物的导出。</li>
<li><strong>类型错误优化</strong>：在遇到类型错误时，Rslib 现在会在终端中显示完整的上下文和 code frame，这使得修复类型问题变得更容易。</li>
</ul>
<p>此外，该版本还包含对 YAML 和 TOML 的支持，详见 <a href="https://github.com/web-infra-dev/rslib/releases/tag/v0.6.0" target="_blank" rel="noopener noreferrer" class="rp-link">Rslib 0.6</a>。</p>
<h3 class="rp-toc-include" id="rspress-和-rstest"><a href="#rspress-和-rstest" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rspress 和 Rstest</h3>
<p>我们正在开发：</p>
<ul>
<li><strong>Rspress 2.0</strong>：一个全面升级的静态站点生成器，带来了更丰富的功能和更好的性能。</li>
<li><strong>Rstest</strong>：一个由 Rspack 提供支持的测试框架。它将为 Rspack 生态系统提供全面、一流的支持，可无缝集成到现有的基于 Rspack 的项目中。</li>
</ul>
<p>更多信息将陆续发布，敬请期待 🌟</p>
<h2 class="rp-toc-include" id="生态系统"><a href="#生态系统" class="rp-header-anchor rp-link" aria-hidden="true">#</a>生态系统</h2>
<h3 class="rp-toc-include" id="rspeedy-for-lynx"><a href="#rspeedy-for-lynx" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rspeedy for Lynx</h3>
<p><a href="https://lynxjs.org/" target="_blank" rel="noopener noreferrer" class="rp-link">Lynx</a> 是一套帮助 Web 开发者复用现有经验，通过一份代码同时构建移动端原生界面与 Web 端界面的技术方案。它最初由字节跳动的工程团队开发，并将由该团队继续推进其演进。</p>
<p>Lynx 基于 Rspack、Rsbuild 和 Rsdoctor 打造了现代化的工具链 <a href="https://lynxjs.org/zh/rspeedy/" target="_blank" rel="noopener noreferrer" class="rp-link">Rspeedy</a>，用于支持 Lynx 的快速开发。此外，Lynx 还有着高性能、多功能的渲染引擎、性能优先的双线程 UI 编程范式等诸多特性。</p>
<p><img src="https://lf-lynx.tiktok-cdns.com/obj/lynx-artifacts-oss-sg/lynx-website/assets/blog/lynx-unlock-native-for-more.png" alt=""/></p>
<blockquote>
<p>参考 <a href="https://lynxjs.org/zh/blog/lynx-unlock-native-for-more.html" target="_blank" rel="noopener noreferrer" class="rp-link">Lynx 发布博客</a> 了解更多。</p>
</blockquote>
<h3 class="rp-toc-include" id="repack-5"><a href="#repack-5" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Re.Pack 5</h3>
<p><a href="https://github.com/callstack/repack" target="_blank" rel="noopener noreferrer" class="rp-link">Re.Pack</a> 是一个用于开发 React Native 应用的构建工具。</p>
<p>Re.Pack 5 已正式发布，通过接入 Rspack 带来了显著的性能改进，通过 Module Federation 2 带来了适当的微前端支持，简化了配置等。</p>
<blockquote>
<p>参考 <a href="https://re-pack.dev/blog/repack-5-release" target="_blank" rel="noopener noreferrer" class="rp-link">Re.Pack 5 发布博客</a> 了解更多。</p>
</blockquote>
<h3 class="rp-toc-include" id="react-router-v7-支持"><a href="#react-router-v7-支持" class="rp-header-anchor rp-link" aria-hidden="true">#</a>React Router v7 支持</h3>
<p><a href="https://github.com/rstackjs/rsbuild-plugin-react-router" target="_blank" rel="noopener noreferrer" class="rp-link">rsbuild-plugin-react-router</a> 发布了首个版本，这是一个提供与 React Router v7 无缝集成的 Rsbuild 插件，并支持以下特性：</p>
<ul>
<li>文件系统路由</li>
<li>服务端渲染</li>
<li>实验性的 Module Federation 支持</li>
</ul>
<blockquote>
<p>查看 <a href="https://github.com/rstackjs/rsbuild-plugin-react-router" target="_blank" rel="noopener noreferrer" class="rp-link">rsbuild-plugin-react-router 仓库</a> 来开始尝试。</p>
</blockquote>
<h2 class="rp-toc-include" id="升级指南"><a href="#升级指南" class="rp-header-anchor rp-link" aria-hidden="true">#</a>升级指南</h2>
<h3 class="rp-toc-include" id="模块类型变更"><a href="#模块类型变更" class="rp-header-anchor rp-link" aria-hidden="true">#</a>模块类型变更</h3>
<p>Rspack 导出的模块类型已得到改进，提供更准确的类型定义，这有助于与 webpack 保持一致。目前已支持的模块子类型包括：</p>
<ul>
<li>NormalModule</li>
<li>ContextModule</li>
<li>ExternalModule</li>
<li>ConcatenatedModule</li>
</ul>
<p>现在你可通过两种方式来识别模块的具体类型：</p>
<div class="rp-codeblock language-ts"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="ts"><code><span class="line"><span style="color:var(--shiki-token-comment)">// 方法一：实例类型校验</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">module</span><span style="color:var(--shiki-token-function)"> instanceof</span><span style="color:var(--shiki-token-function)"> NormalModule</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-comment)">// 方法二：构造器特征检测</span></span>
<span class="line"><span style="color:var(--shiki-token-constant)">module</span><span style="color:var(--shiki-foreground)">.</span><span style="color:var(--shiki-token-constant)">constructor</span><span style="color:var(--shiki-foreground)">.name </span><span style="color:var(--shiki-token-keyword)">===</span><span style="color:var(--shiki-token-string-expression)"> &#x27;NormalModule&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>新的类型定义可能会让你原有使用 JavaScript API 的代码遇到类型报错，例如：</p>
<div class="rp-codeblock language-ts"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="ts"><code><span class="line"><span style="color:var(--shiki-token-constant)">module</span><span style="color:var(--shiki-foreground)">.resource; </span><span style="color:var(--shiki-token-comment)">// TypeScript Error: Property &#x27;resource&#x27; does not exist on type &#x27;Module&#x27;</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>现在当你访问 <code>resource</code> 属性时，需要使用以下方法断言具体的模块类型：</p>
<div class="rp-codeblock language-ts"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="ts"><code><span class="line"><span style="color:var(--shiki-token-comment)">// 模式一：in操作符守卫</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">if</span><span style="color:var(--shiki-foreground)"> (</span><span style="color:var(--shiki-token-string-expression)">&#x27;resource&#x27;</span><span style="color:var(--shiki-token-keyword)"> in</span><span style="color:var(--shiki-token-constant)"> module</span><span style="color:var(--shiki-foreground)">) {</span></span>
<span class="line"><span style="color:var(--shiki-token-constant)">  console</span><span style="color:var(--shiki-token-function)">.log</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-constant)">module</span><span style="color:var(--shiki-foreground)">.resource);</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-comment)">// 模式二：类型实例断言</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">if</span><span style="color:var(--shiki-foreground)"> (</span><span style="color:var(--shiki-token-constant)">module</span><span style="color:var(--shiki-token-keyword)"> instanceof</span><span style="color:var(--shiki-token-function)"> NormalModule</span><span style="color:var(--shiki-foreground)">) {</span></span>
<span class="line"><span style="color:var(--shiki-token-constant)">  module</span><span style="color:var(--shiki-foreground)">.resource;</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">}</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h3 class="rp-toc-include" id="升级-swc-插件"><a href="#升级-swc-插件" class="rp-header-anchor rp-link" aria-hidden="true">#</a>升级 SWC 插件</h3>
<p>在 Rspack 1.3 中，<code>swc_core</code> crate 已经升级到 v16。SWC Wasm 插件的用户需要确保与正在使用的 <code>swc_core</code> 版本一致，否则可能会导致意外问题。</p>
<blockquote>
<p>详情请参考 <a href="/zh/errors/swc-plugin-version" class="rp-link">常见问题 - SWC 插件版本不匹配</a>。</p>
</blockquote><!--/$-->]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Rspack 1.2 发布公告]]></title>
            <link>https://rspack.rs/zh/blog/announcing-1-2</link>
            <guid isPermaLink="false">/zh/blog/announcing-1-2</guid>
            <pubDate>Tue, 21 Jan 2025 16:00:00 GMT</pubDate>
            <description><![CDATA[Rspack 1.2 版本发布，引入实验性的持久化缓存、更快的代码分割算法以及 Yarn PnP 支持等功能。]]></description>
            <content:encoded><![CDATA[<!--$--><p><em>2025 年 1 月 21 日</em></p>
<h1 class="rp-toc-include" id="rspack-12-发布公告"><a href="#rspack-12-发布公告" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rspack 1.2 发布公告<!-- --> </h1><div class="rp-not-doc rp-llms-container"><button class="rp-not-doc rp-llms-button rp-llms-copy-button"><div class="rp-llms-copy-button__icon-wrapper"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-llms-copy-button__icon-success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-llms-copy-button__icon-copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg></div><span>复制 Markdown</span></button><button class="rp-llms-button rp-llms-view-options__trigger "><svg width="1em" height="1em" viewBox="0 0 32 32" class="rp-llms-view-options__arrow "><path fill="currentColor" d="M16 22 6 12l1.4-1.4 8.6 8.6 8.6-8.6L26 12z"></path></svg></button></div>
<p><img src="https://assets.rspack.rs/rspack/rspack-banner-v1-2.png" alt="Rspack 1.2"/></p>
<blockquote>
<p>由 <a href="https://github.com/jerrykingxyz" target="_blank" rel="noopener noreferrer" class="rp-link">@jerrykingxyz</a>，<a href="https://github.com/chenjiahan" target="_blank" rel="noopener noreferrer" class="rp-link">@chenjiahan</a>，<a href="https://github.com/JSerFeng" target="_blank" rel="noopener noreferrer" class="rp-link">@JSerFeng</a>， <a href="https://github.com/ahabhgk" target="_blank" rel="noopener noreferrer" class="rp-link">@ahabhgk</a> 发布</p>
</blockquote>
<hr/>
<p>Rspack v1.2 已经正式发布！</p>
<p>值得关注的变更如下：</p>
<ul>
<li>新功能<!-- -->
<ul>
<li><a href="#%E6%94%AF%E6%8C%81%E6%8C%81%E4%B9%85%E5%8C%96%E7%BC%93%E5%AD%98" class="rp-link">支持持久化缓存</a>：实验性功能，让热启动性能提升高达 <strong>250%</strong></li>
<li><a href="#%E6%94%AF%E6%8C%81-yarn-pnp" class="rp-link">支持 Yarn PnP</a></li>
</ul>
</li>
<li>性能优化<!-- -->
<ul>
<li><a href="#%E6%9B%B4%E5%BF%AB%E7%9A%84-code-splitting" class="rp-link">更快的 code splitting</a>：实验性开关，显著提升 code splitting 性能</li>
<li><a href="#watch-%E8%8C%83%E5%9B%B4%E5%8F%98%E5%8C%96" class="rp-link">Watch 范围变化</a></li>
<li><a href="#%E5%87%8F%E5%B0%91%E5%86%85%E5%AD%98%E4%BD%BF%E7%94%A8" class="rp-link">减少内存使用</a></li>
<li><a href="#%E6%9B%B4%E5%B0%8F%E7%9A%84%E5%8E%8B%E7%BC%A9%E4%BD%93%E7%A7%AF" class="rp-link">更小的压缩体积</a></li>
<li><a href="#%E6%9B%B4%E5%BF%AB%E7%9A%84%E5%89%AF%E4%BD%9C%E7%94%A8%E4%BC%98%E5%8C%96" class="rp-link">更快的副作用优化</a></li>
</ul>
</li>
<li>生态系统<!-- -->
<ul>
<li><a href="#angular-%E6%94%AF%E6%8C%81" class="rp-link">Angular 支持</a></li>
<li><a href="#rsbuild-v1-2" class="rp-link">Rsbuild v1.2</a></li>
</ul>
</li>
</ul>
<h2 class="rp-toc-include" id="新功能"><a href="#新功能" class="rp-header-anchor rp-link" aria-hidden="true">#</a>新功能</h2>
<h3 class="rp-toc-include" id="支持持久化缓存"><a href="#支持持久化缓存" class="rp-header-anchor rp-link" aria-hidden="true">#</a>支持持久化缓存</h3>
<p>在 Rspack v1.2 中，我们实验性的支持了持久化缓存，其会将构建中的缓存信息写入到存储介质中，加速下次 Rspack 的启动速度。</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  cache</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> true</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  experiments</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    cache</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      type</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;persistent&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>当构建命中缓存时，它可以在真实项目中带来高达 250% 的性能提升。</p>
<div class="rp-table-scroll-container rp-scrollbar"><table><thead><tr><th>项目类型</th><th>模块数量</th><th>Normal dev</th><th>Cold dev</th><th>Hot dev</th></tr></thead><tbody><tr><td>初始项目</td><td>26</td><td>146 ms</td><td>149 ms (+2%)</td><td>134 ms (-8%)</td></tr><tr><td>包含 10000 个模块的项目</td><td>10040</td><td>2.43 s</td><td>2.43 s (+0%)</td><td>1.16 s (-52%)</td></tr><tr><td>包含 Less 文件的中型项目</td><td>1898</td><td>3.47 s</td><td>3.55 s (+2%)</td><td>0.92 s (-73%)</td></tr><tr><td>大型真实项目</td><td>45968</td><td>93.3 s</td><td>91.9 s (-1%)</td><td>26 s (-72%)</td></tr></tbody></table></div>
<p>需要注意的是，持久化缓存目前仍处于实验阶段，当前仅支持构建过程中的 make 阶段（包括模块解析、转换等流程）。未来我们将持续优化，进一步提升缓存的性能和覆盖范围。</p>
<p>如果你在使用持久化缓存时遇到任何问题，欢迎通过 GitHub Issues 反馈。</p>
<blockquote>
<p>详情请参考 <a href="/zh/config/cache" class="rp-link">cache</a>。</p>
</blockquote>
<h3 class="rp-toc-include" id="支持-yarn-pnp"><a href="#支持-yarn-pnp" class="rp-header-anchor rp-link" aria-hidden="true">#</a>支持 Yarn PnP</h3>
<p>Rspack 迎来了对 <a href="https://yarnpkg.com/features/pnp" target="_blank" rel="noopener noreferrer" class="rp-link">Yarn PnP</a> 的支持，其默认根据 <code>process.versions.pnp</code>（即应用在 Yarn PnP 环境中运行时）来进行开启，也可以将 <code>resolve.pnp</code> 配置为 <code>true</code> 来强制开启。</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  resolve</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    pnp</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> true</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>在此特别感谢 <a href="https://x.com/arcanis" target="_blank" rel="noopener noreferrer" class="rp-link">@arcanis</a>（Yarn 的维护者），为 Rspack 的 resolver 实现了 PnP 解析。</p>
<blockquote>
<p>详情请参考 <a href="/zh/config/resolve#resolvepnp" class="rp-link">resolve.pnp</a>。</p>
</blockquote>
<h2 class="rp-toc-include" id="性能优化"><a href="#性能优化" class="rp-header-anchor rp-link" aria-hidden="true">#</a>性能优化</h2>
<h3 class="rp-toc-include" id="更快的-code-splitting"><a href="#更快的-code-splitting" class="rp-header-anchor rp-link" aria-hidden="true">#</a>更快的 code splitting</h3>
<p>在之前的 Rspack 版本中，code splitting 算法在 HMR 下会占用大量的耗时，在 Rspack v1.2 中，我们实现了全新的 code splitting 算法，它支持多线程，增量构建效率更高。如果你的代码库包含大量动态导入，code splitting 可能会花费大量时间，开启这项新功能可以显著提高 code splitting 的性能。</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  experiments</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    parallelCodeSplitting</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> true</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<blockquote>
<p>详情请参考 <a href="/zh/config/experiments#experimentsparallelcodesplitting" class="rp-link">experiments.parallelCodeSplitting</a>。</p>
</blockquote>
<h3 class="rp-toc-include" id="watch-范围变化"><a href="#watch-范围变化" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Watch 范围变化</h3>
<p>Rspack v1.2 将不再监听 <code>node_modules</code> 和 <code>.git</code> 目录下的文件变动，这将显著减少监听的文件数目并带来性能提升。</p>
<p>通过 <a href="https://github.com/rstackjs/build-tools-performance" target="_blank" rel="noopener noreferrer" class="rp-link">benchmark 仓库</a> 中的数据，这项调整将：</p>
<ul>
<li>减少内存占用 120MB</li>
<li>提升 Dev 启动速度 40%</li>
<li>提升 HMR 速度 20~30%</li>
</ul>
<p>这个变更不会影响 monorepo 中的符号链接资源，因为 Rspack 默认将符号链接资源解析为它的真实路径。</p>
<p>如果你倾向于保持之前的行为，可以设置 ：</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  watchOptions</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    ignored</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> []</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<blockquote>
<p>详情请参考 <a href="/zh/config/watch#watchoptionsignored" class="rp-link">watchOptions.ignored</a>。</p>
</blockquote>
<h3 class="rp-toc-include" id="减少内存使用"><a href="#减少内存使用" class="rp-header-anchor rp-link" aria-hidden="true">#</a>减少内存使用</h3>
<p>我们优化了在 <a href="https://github.com/rstackjs/rspack-sources" target="_blank" rel="noopener noreferrer" class="rp-link">rspack-sources</a> 计算过程中用于存储字符串的数据结构。在整个计算过程中，所有字符串数据都指向根节点的字符串堆内存，有效避免了计算过程中产生新的字符串分配。</p>
<blockquote>
<p>详见：<a href="https://github.com/web-infra-dev/rspack/pull/8666" target="_blank" rel="noopener noreferrer" class="rp-link">perf: reduce memory consumption of CachedSource</a>。</p>
</blockquote>
<h3 class="rp-toc-include" id="更小的压缩体积"><a href="#更小的压缩体积" class="rp-header-anchor rp-link" aria-hidden="true">#</a>更小的压缩体积</h3>
<p>Rspack v1.2 将 SWC 压缩器的默认 <code>passes</code> 设置为 <code>2</code>，以减少 1%-7% 的打包体积。</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js"><code><span class="line"><span style="color:var(--shiki-token-keyword)">new</span><span style="color:var(--shiki-token-constant)"> rspack</span><span style="color:var(--shiki-token-function)">.SwcJsMinimizerRspackPlugin</span><span style="color:var(--shiki-foreground)">({</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  minimizerOptions</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    compress</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-token-comment)">      // 在之前的版本中默认为 1</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      passes</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> 2</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">});</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p><a href="https://swc.rs/docs/configuration/minification#jscminifycompress" target="_blank" rel="noopener noreferrer" class="rp-link">passes</a> 是运行压缩的最大次数。在某些情况下，多次压缩可以产生更小的代码。考虑到 Rspack 本身的性能优势，我们将默认值设为 <code>2</code> 以在构建性能和打包体积之间取得最佳平衡。</p>
<blockquote>
<p>详见：<a href="https://github.com/web-infra-dev/rspack/pull/8853" target="_blank" rel="noopener noreferrer" class="rp-link">feat: set default SWC minimizer passes to 2 to reduce bundle size</a>。</p>
</blockquote>
<h3 class="rp-toc-include" id="更快的副作用优化"><a href="#更快的副作用优化" class="rp-header-anchor rp-link" aria-hidden="true">#</a>更快的副作用优化</h3>
<p>我们对副作用优化的实现进行了重构，采用了更简洁且更易并行化的方案。通过充分利用多线程并行处理能力，在测试项目中，这个阶段的性能获得了 2-3 倍的提升。</p>
<blockquote>
<p>详见：<a href="https://github.com/web-infra-dev/rspack/pull/8781" target="_blank" rel="noopener noreferrer" class="rp-link">perf: parallelize side effects optimization</a>。</p>
</blockquote>
<h2 class="rp-toc-include" id="生态系统"><a href="#生态系统" class="rp-header-anchor rp-link" aria-hidden="true">#</a>生态系统</h2>
<h3 class="rp-toc-include" id="angular-支持"><a href="#angular-支持" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Angular 支持</h3>
<p>Nx 团队的核心成员 <a href="https://github.com/Coly010" target="_blank" rel="noopener noreferrer" class="rp-link">Colum Ferry</a> 为 Rspack 生态带来了完整的 Angular 支持。</p>
<p>通过新发布的 <code>@ng-rsbuild/plugin-angular</code> 和 <code>@ng-rspack/build</code> 包，开发者现在可以使用 Rspack 或 Rsbuild 来构建 Angular 应用，获得更快的构建性能和模块联邦等特性。</p>
<p>欢迎访问 <a href="https://nx.dev/docs/technologies/angular/angular-rspack" target="_blank" rel="noopener noreferrer" class="rp-link">Angular Rspack</a> 了解详细信息。</p>
<h3 class="rp-toc-include" id="rsbuild-v12"><a href="#rsbuild-v12" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rsbuild v1.2</h3>
<p>Rsbuild v1.2 已经与 Rspack v1.2 同步发布，并带来了多项新特性：</p>
<ul>
<li>通过 <a href="https://rsbuild.rs/config/output/manifest#generate" target="_blank" rel="noopener noreferrer" class="rp-link">output.manifest.generate</a> 来自定义 manifest 文件的生成。</li>
<li>通过 <a href="https://rsbuild.rs/config/output/clean-dist-path#keep" target="_blank" rel="noopener noreferrer" class="rp-link">cleanDistPath.keep</a> 来指定在产物目录下保留的文件。</li>
<li><a href="https://rsbuild.rs/plugins/list/plugin-assets-retry" target="_blank" rel="noopener noreferrer" class="rp-link">@rsbuild/plugin-assets-retry</a> 现在会生成更小的运行时代码。</li>
</ul>
<blockquote>
<p>详情请参考 <a href="https://github.com/web-infra-dev/rsbuild/releases/tag/v1.2.0" target="_blank" rel="noopener noreferrer" class="rp-link">Rsbuild v1.2.0</a>。</p>
</blockquote>
<h2 class="rp-toc-include" id="升级指南"><a href="#升级指南" class="rp-header-anchor rp-link" aria-hidden="true">#</a>升级指南</h2>
<h3 class="rp-toc-include" id="升级-swc-插件"><a href="#升级-swc-插件" class="rp-header-anchor rp-link" aria-hidden="true">#</a>升级 SWC 插件</h3>
<p>在 Rspack v1.2 中，Rust 依赖包 <code>swc_core</code> 的版本已升级到 <code>10.1.0</code>。SWC Wasm 插件的用户需要确保与正在使用的 <code>swc_core</code> 版本一致，否则可能会导致意外问题。</p>
<blockquote>
<p>详情请参考 <a href="/zh/errors/swc-plugin-version" class="rp-link">常见问题 - SWC 插件版本不匹配</a>。</p>
</blockquote>
<h3 class="rp-toc-include" id="warncasesensitivemodules-默认关闭"><a href="#warncasesensitivemodules-默认关闭" class="rp-header-anchor rp-link" aria-hidden="true">#</a>WarnCaseSensitiveModules 默认关闭</h3>
<p><a href="/zh/plugins/webpack/case-sensitive-plugin" class="rp-link">WarnCaseSensitiveModulesPlugin</a> 插件用于检查模块的路径，并对路径全部为小写的冲突模块发出警告。Rspack 过去默认启用它，但由于它只是一个 linter 插件，并且它在开发模式下会产生额外的性能开销。所以现在 Rspack 默认禁用了这项功能。</p>
<p>如果你倾向于保持之前的行为，可以设置：</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { rspack } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;@rspack/core&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  plugins</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span><span style="color:var(--shiki-token-keyword)">new</span><span style="color:var(--shiki-token-constant)"> rspack</span><span style="color:var(--shiki-token-function)">.WarnCaseSensitiveModulesPlugin</span><span style="color:var(--shiki-foreground)">()]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div><!--/$-->]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Rspack 1.1 发布公告]]></title>
            <link>https://rspack.rs/zh/blog/announcing-1-1</link>
            <guid isPermaLink="false">/zh/blog/announcing-1-1</guid>
            <pubDate>Thu, 07 Nov 2024 16:00:00 GMT</pubDate>
            <description><![CDATA[Rspack 和 Rsbuild 1.1 版本发布，显著提升了冷启动和增量构建的性能，同时改进了内置的 HTML 插件和配置选项的类型提示。]]></description>
            <content:encoded><![CDATA[<!--$--><p><em>2024 年 11 月 07 日</em></p>
<h1 class="rp-toc-include" id="rspack-11-发布公告"><a href="#rspack-11-发布公告" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rspack 1.1 发布公告<!-- --> </h1><div class="rp-not-doc rp-llms-container"><button class="rp-not-doc rp-llms-button rp-llms-copy-button"><div class="rp-llms-copy-button__icon-wrapper"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-llms-copy-button__icon-success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-llms-copy-button__icon-copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg></div><span>复制 Markdown</span></button><button class="rp-llms-button rp-llms-view-options__trigger "><svg width="1em" height="1em" viewBox="0 0 32 32" class="rp-llms-view-options__arrow "><path fill="currentColor" d="M16 22 6 12l1.4-1.4 8.6 8.6 8.6-8.6L26 12z"></path></svg></button></div>
<p><img src="https://assets.rspack.rs/rspack/rspack-banner-v1-1.png" alt="Rspack 1.1"/></p>
<blockquote>
<p>由 <a href="https://github.com/LingyuCoder" target="_blank" rel="noopener noreferrer" class="rp-link">@LingyuCoder</a>，<a href="https://github.com/ahabhgk" target="_blank" rel="noopener noreferrer" class="rp-link">@ahabhgk</a>，<a href="https://github.com/GiveMe-A-Name" target="_blank" rel="noopener noreferrer" class="rp-link">@GiveMe-A-Name</a>，<a href="https://github.com/9aoy" target="_blank" rel="noopener noreferrer" class="rp-link">@9aoy</a>，<a href="https://github.com/chenjiahan" target="_blank" rel="noopener noreferrer" class="rp-link">@chenjiahan</a> 发布</p>
</blockquote>
<hr/>
<p>Rspack v1.1 和 Rsbuild v1.1 已经正式发布！</p>
<p>值得关注的变更如下：</p>
<ul>
<li>性能优化<!-- -->
<ul>
<li><a href="#%E4%BC%98%E5%8C%96%E8%B0%83%E5%BA%A6%E7%AD%96%E7%95%A5" class="rp-link">优化调度策略</a>：相较于 1.0 版本性能提升达 <strong>10%</strong>。</li>
<li><a href="#%E6%96%B0%E7%9A%84%E5%A2%9E%E9%87%8F%E6%9E%84%E5%BB%BA" class="rp-link">新的增量构建</a>：实验性功能，开启后可使 HMR 性能提升高达 <strong>38%</strong>。</li>
</ul>
</li>
<li>新功能<!-- -->
<ul>
<li><a href="#%E4%BC%98%E5%8C%96-html-%E6%8F%92%E4%BB%B6" class="rp-link">优化 HTML 插件</a>：用新功能重构内置的 HTML 插件。</li>
<li><a href="#%E4%BC%98%E5%8C%96-jsdoc" class="rp-link">优化 JSDoc</a>：为所有配置项添加了 JSDoc。</li>
</ul>
</li>
<li>生态系统<!-- -->
<ul>
<li><a href="#docusaurus-%E6%9E%84%E5%BB%BA%E6%8F%90%E9%80%9F" class="rp-link">Docusaurus 构建提速</a>：使用 Rspack 打包 Docusaurus 站点。</li>
<li><a href="#nuxt-rspack-%E6%9E%84%E5%BB%BA%E5%99%A8" class="rp-link">Nuxt Rspack 构建器</a>：Nuxt 添加实验性的 Rspack 构建器。</li>
</ul>
</li>
<li><a href="#rsbuild-v11" class="rp-link">Rsbuild v1.1</a>：添加 CLI 快捷方式和新配置。</li>
</ul>
<h2 class="rp-toc-include" id="性能优化"><a href="#性能优化" class="rp-header-anchor rp-link" aria-hidden="true">#</a>性能优化</h2>
<h3 class="rp-toc-include" id="优化调度策略"><a href="#优化调度策略" class="rp-header-anchor rp-link" aria-hidden="true">#</a>优化调度策略</h3>
<p>根据我们的性能测试，Rspack v1.1 相较于 v1.0 性能提升达<strong>10%</strong>。</p>
<img width="850" src="https://assets.rspack.rs/rspack/assets/rspack-1-1-perf-comparison.png" alt="Rspack v1.1 与 v1.0 的性能对比"/>
<p>优化主要源于 Rspack v1.1 采用了更佳的线程调度策略，其灵感来自于<a href="https://thenewstack.io/using-rustlangs-async-tokio-runtime-for-cpu-bound-tasks/" target="_blank" rel="noopener noreferrer" class="rp-link">《使用 Rust 语言的 Async Tokio 运行时处理 CPU 密集型任务》</a>，同时 SWC 也优化了其并发支持，从而能够更高效地调度异步任务。</p>
<h3 class="rp-toc-include" id="新的增量构建"><a href="#新的增量构建" class="rp-header-anchor rp-link" aria-hidden="true">#</a>新的增量构建</h3>
<p>在 Rspack 0.x 的早期版本中，我们实现了<a href="https://v0.rspack.rs/config/experiments#experimentsincrementalrebuild" target="_blank" rel="noopener noreferrer" class="rp-link">experiments.incrementalRebuild</a>。随着这个功能逐渐稳定，我们移除了实验性配置并默认启用。</p>
<p>然而，此功能仅在重新构建时的 <code>make</code> 和 <code>emitAssets</code> 阶段做到了增量。许多项目在 <code>make</code> 阶段运行 loader 会花费大量时间。当时对于这些项目，此功能在重新构建时有相对明显的性能提升。但仍有一些项目在 <code>make</code> 之外的其他阶段花费大量时间。因此，我们对这个功能进行了优化和扩展，逐渐将增量引入到其他阶段，如 <code>buildChunkGraph</code>、<code>providedExports</code>、<code>moduleCodegen</code> 等。</p>
<p>在 Rspack v1.1 中，我们引入了 <a href="/zh/config/experiments#experimentsincremental" class="rp-link">experiments.incremental</a> 作为 <code>experiments.incrementalRebuild</code> 的后继者和超集，旨在为开发者带来进一步的重新构建时的性能提升和更快的 HMR。</p>
<p>在一个有 10000 个 React 组件的案例中，HMR 速度提升了 <strong>38%</strong>：</p>
<img width="850" src="https://assets.rspack.rs/rspack/assets/rspack-v1-1-new-incremental-compare.png" alt="启用新增量的 10000 个 React 组件"/>
<p>在 Rspack v1.1 中，你可以在 <code>dev</code> 模式下通过以下方式启用此功能：</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">const</span><span style="color:var(--shiki-token-constant)"> isDev</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-constant)"> process</span><span style="color:var(--shiki-foreground)">.</span><span style="color:var(--shiki-token-constant)">env</span><span style="color:var(--shiki-foreground)">.</span><span style="color:var(--shiki-token-constant)">NODE_ENV</span><span style="color:var(--shiki-token-keyword)"> ===</span><span style="color:var(--shiki-token-string-expression)"> &#x27;development&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  mode</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> isDev </span><span style="color:var(--shiki-token-keyword)">?</span><span style="color:var(--shiki-token-string-expression)"> &#x27;development&#x27;</span><span style="color:var(--shiki-token-keyword)"> :</span><span style="color:var(--shiki-token-string-expression)"> &#x27;production&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  experiments</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    incremental</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> isDev</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<blockquote>
<p>更多详细信息请参考 <a href="/zh/config/experiments#experimentsincremental" class="rp-link">experiments.incremental</a>。</p>
</blockquote>
<p>目前这是一个实验性功能，还需更多的验证以保证其稳定。如果你感兴趣可以尝试一下，并将错误报告和反馈提交至<a href="https://github.com/web-infra-dev/rspack/issues/8106" target="_blank" rel="noopener noreferrer" class="rp-link">#8106</a>。</p>
<h2 class="rp-toc-include" id="新功能"><a href="#新功能" class="rp-header-anchor rp-link" aria-hidden="true">#</a>新功能</h2>
<h3 class="rp-toc-include" id="优化-html-插件"><a href="#优化-html-插件" class="rp-header-anchor rp-link" aria-hidden="true">#</a>优化 HTML 插件</h3>
<p>在早前的 Rspack 版本中已实现了内置的 <code>HtmlRspackPlugin</code>，但它的能力缺失严重，缺少了部分配置项的同时，也不支持 <code>hooks</code>。这使得那些基于 <code>HtmlWebpackPlugin</code> 的 <code>hooks</code> 实现的插件无法在 <code>HtmlRspackPlugin</code> 中得到兼容。</p>
<p>因此，我们大幅重构了 <code>HtmlRspackPlugin</code>，在对齐了更多 <code>HtmlWebpackPlugin</code> 配置项的同时，也完成了 <code>hooks</code> 对齐。现在你可以通过 <code>HtmlRspackPlugin.getCompilationHooks</code> 来获取它们，并使用其修改 HTML 产物的内容：</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">const</span><span style="color:var(--shiki-token-constant)"> AddAttributePlugin</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-token-function)">  apply</span><span style="color:var(--shiki-foreground)">(compiler) {</span></span>
<span class="line"><span style="color:var(--shiki-token-constant)">    compiler</span><span style="color:var(--shiki-token-function)">.</span><span style="color:var(--shiki-token-constant)">hooks</span><span style="color:var(--shiki-token-function)">.</span><span style="color:var(--shiki-token-constant)">compilation</span><span style="color:var(--shiki-token-function)">.tap</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">&#x27;AddAttributePlugin&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> (compilation) </span><span style="color:var(--shiki-token-keyword)">=&gt;</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-token-constant)">      HtmlRspackPlugin</span><span style="color:var(--shiki-token-function)">.getCompilationHooks</span><span style="color:var(--shiki-foreground)">(</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        compilation</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      ).</span><span style="color:var(--shiki-token-constant)">alterAssetTags</span><span style="color:var(--shiki-token-function)">.tapPromise</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">&#x27;AddAttributePlugin&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-keyword)"> async</span><span style="color:var(--shiki-foreground)"> (data) </span><span style="color:var(--shiki-token-keyword)">=&gt;</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-token-constant)">        data</span><span style="color:var(--shiki-foreground)">.</span><span style="color:var(--shiki-token-constant)">assetTags</span><span style="color:var(--shiki-foreground)">.scripts </span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-token-constant)"> data</span><span style="color:var(--shiki-token-function)">.</span><span style="color:var(--shiki-token-constant)">assetTags</span><span style="color:var(--shiki-token-function)">.</span><span style="color:var(--shiki-token-constant)">scripts</span><span style="color:var(--shiki-token-function)">.map</span><span style="color:var(--shiki-foreground)">((tag) </span><span style="color:var(--shiki-token-keyword)">=&gt;</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">          if</span><span style="color:var(--shiki-foreground)"> (</span><span style="color:var(--shiki-token-constant)">tag</span><span style="color:var(--shiki-foreground)">.tagName </span><span style="color:var(--shiki-token-keyword)">===</span><span style="color:var(--shiki-token-string-expression)"> &#x27;script&#x27;</span><span style="color:var(--shiki-foreground)">) {</span></span>
<span class="line"><span style="color:var(--shiki-token-constant)">            tag</span><span style="color:var(--shiki-foreground)">.</span><span style="color:var(--shiki-token-constant)">attributes</span><span style="color:var(--shiki-foreground)">.specialAttribute </span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-token-constant)"> true</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          }</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">          return</span><span style="color:var(--shiki-foreground)"> tag;</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        });</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      });</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    });</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  plugins</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span><span style="color:var(--shiki-token-keyword)">new</span><span style="color:var(--shiki-token-function)"> HtmlRspackPlugin</span><span style="color:var(--shiki-foreground)">()</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> AddAttributePlugin]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<blockquote>
<p>更多详细信息请参考 <a href="/zh/plugins/rspack/html-rspack-plugin" class="rp-link">HtmlRspackPlugin</a></p>
</blockquote>
<h3 class="rp-toc-include" id="优化-jsdoc"><a href="#优化-jsdoc" class="rp-header-anchor rp-link" aria-hidden="true">#</a>优化 JSDoc</h3>
<p>Rspack 使用 <a href="https://github.com/colinhacks/zod" target="_blank" rel="noopener noreferrer" class="rp-link">zod</a> 验证用户配置并推断配置类型。然而推断出的类型缺少 JSDoc 注释，使得生成的类型相当复杂且难以理解。</p>
<p>为了解决这个问题，我们重构了配置的类型，并为所有类型都添加了 JSDoc 注释以提高可读性。</p>
<img width="850" src="https://assets.rspack.rs/rspack/assets/rspack-v1-1-config-intellisense.png" alt="IDE 中的配置智能感知"/>
<blockquote>
<p>我们仍在寻求改进 JSDoc。如果你感兴趣，请随时提交 PR。❤️</p>
</blockquote>
<h2 class="rp-toc-include" id="生态系统"><a href="#生态系统" class="rp-header-anchor rp-link" aria-hidden="true">#</a>生态系统</h2>
<h3 class="rp-toc-include" id="docusaurus-构建提速"><a href="#docusaurus-构建提速" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Docusaurus 构建提速</h3>
<p><a href="https://docusaurus.io/zh-CN/blog/releases/3.6" target="_blank" rel="noopener noreferrer" class="rp-link">Docusaurus v3.6</a> 带来了<code>Docusaurus Faster</code> 选项，允许用户将 Rspack 用作 Docusaurus 站点的打包工具。</p>
<p><a href="https://docusaurus.io/zh-CN/blog/releases/3.6#docusaurus-faster" target="_blank" rel="noopener noreferrer" class="rp-link">Docusaurus Faster</a> 的目标是减少 Docusaurus 的构建耗时和内存占用。Docusaurus 团队致力于多项优化，并使用像 Rspack 和 SWC 这样基于 Rust 的高性能工具对其基础设施进行了现代化改造。</p>
<p>在对其社区站点的性能测试中，生产模式下的站点的构建速度可以提速 2 到 4 倍。</p>
<h3 class="rp-toc-include" id="nuxt-rspack-构建器"><a href="#nuxt-rspack-构建器" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Nuxt Rspack 构建器</h3>
<p><a href="https://nuxt.com/blog/v3-14" target="_blank" rel="noopener noreferrer" class="rp-link">Nuxt v3.14</a> 将 Rspack 作为 Nuxt 官方支持的构建器。</p>
<p>它仍然处于实验阶段，Nuxt 团队重构了内部的虚拟文件系统来支持 <code>unplugin</code> 以使得它成功运行。</p>
<p>你可以尝试 <a href="https://github.com/danielroe/nuxt-rspack-starter" target="_blank" rel="noopener noreferrer" class="rp-link">nuxt-rspack-starter</a> 作为初始项目，或者安装 <a href="https://www.npmjs.com/package/@nuxt/rspack-builder" target="_blank" rel="noopener noreferrer" class="rp-link">@nuxt/rspack-builder</a> 并在 Nuxt 配置文件中设置 <code>builder: &#x27;rspack&#x27;</code>。</p>
<h2 class="rp-toc-include" id="rsbuild-v11"><a href="#rsbuild-v11" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rsbuild v1.1</h2>
<p>Rsbuild v1.1 在升级到 Rspack v1.1 的同时引入了几个新功能。</p>
<h3 class="rp-toc-include" id="cli-快捷方式"><a href="#cli-快捷方式" class="rp-header-anchor rp-link" aria-hidden="true">#</a>CLI 快捷方式</h3>
<p>Rsbuild 现在可通过 <a href="https://rsbuild.rs/config/dev/cli-shortcuts" target="_blank" rel="noopener noreferrer" class="rp-link">dev.cliShortcuts</a> 启用 CLI 快捷方式。如果你已在使用 Rsbuild CLI，则该功能默认开启。</p>
<p>CLI 快捷方式允许你清空控制台、打开浏览器、重启服务器或自定义任何你想要的快捷键。</p>
<img width="650" src="https://assets.rspack.rs/rsbuild/assets/rsbuild-cli-shortcuts.png" alt="Rsbuild CLI 快捷方式"/>
<h3 class="rp-toc-include" id="查看静态资源"><a href="#查看静态资源" class="rp-header-anchor rp-link" aria-hidden="true">#</a>查看静态资源</h3>
<p>Rsbuild 开发服务器现在会在 <code>/rsbuild-dev-server</code> 路径下提供了一个报告页面，允许你查看当前构建期间生成的所有静态资源。</p>
<img src="https://assets.rspack.rs/rsbuild/assets/assets-report-page.png" alt="rsbuild-dev-server" width="600"/>
<h3 class="rp-toc-include" id="新配置"><a href="#新配置" class="rp-header-anchor rp-link" aria-hidden="true">#</a>新配置</h3>
<p>Rsbuild 1.1 引入了一些新配置：</p>
<ul>
<li><a href="https://rsbuild.rs/config/server/base" target="_blank" rel="noopener noreferrer" class="rp-link">server.base</a>：设置服务器的基础路径。</li>
<li><a href="https://rsbuild.rs/config/source/assets-include" target="_blank" rel="noopener noreferrer" class="rp-link">source.assetsInclude</a>：设置额外被作为静态资源处理的文件。</li>
<li><a href="https://rsbuild.rs/config/output/filename" target="_blank" rel="noopener noreferrer" class="rp-link">output.filename.assets</a>：设置额外静态资源的名称。</li>
<li><a href="https://rsbuild.rs/config/output/dist-path" target="_blank" rel="noopener noreferrer" class="rp-link">output.distPath.assets</a>：设置额外静态资源的输出目录。</li>
</ul>
<h2 class="rp-toc-include" id="升级指南"><a href="#升级指南" class="rp-header-anchor rp-link" aria-hidden="true">#</a>升级指南</h2>
<h3 class="rp-toc-include" id="升级-swc-插件"><a href="#升级-swc-插件" class="rp-header-anchor rp-link" aria-hidden="true">#</a>升级 SWC 插件</h3>
<p>在 Rspack v1.1 中，Rust 包中 <code>swc_core</code> 已升级到 <code>5.0.1</code>。SWC Wasm 插件的用户需要确保与正在使用的 <code>swc_core</code> 版本一致，否则可能会导致意外问题。</p>
<p>更多详细信息请参阅 <a href="https://swc.rs/docs/plugin/selecting-swc-core" target="_blank" rel="noopener noreferrer" class="rp-link">SWC 文档</a>。</p>
<h3 class="rp-toc-include" id="哈希函数"><a href="#哈希函数" class="rp-header-anchor rp-link" aria-hidden="true">#</a>哈希函数</h3>
<p>Rspack 的 <a href="/zh/config/output#outputhashfunction" class="rp-link">output.hashFunction</a> 现在默认为更快的 <code>xxhash64</code>，并且 <a href="/zh/config/output#outputhashdigestlength" class="rp-link">output.hashDigestLength</a> 现在默认为 <code>16</code>（之前为 <code>20</code> ）。对于大型项目，此更改将带来显著的性能提升。</p>
<p>如果你倾向于使用之前的哈希函数，可以设置：</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  output</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    hashFunction</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;md5&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    hashDigestLength</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> 20</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<blockquote>
<p>相关 PR：<a href="https://github.com/web-infra-dev/rspack/pull/8249" target="_blank" rel="noopener noreferrer" class="rp-link">#8249</a>。</p>
</blockquote><!--/$-->]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Rspack 1.0 发布公告]]></title>
            <link>https://rspack.rs/zh/blog/announcing-1-0</link>
            <guid isPermaLink="false">/zh/blog/announcing-1-0</guid>
            <pubDate>Wed, 28 Aug 2024 16:00:01 GMT</pubDate>
            <description><![CDATA[今天，Rspack 终于到达了一个崭新的阶段 —— 1.0。这意味着 Rspack 已经达到生产稳定，覆盖了 webpack 绝大多数的 API 和功能，并已经做好支持更多用户的准备。]]></description>
            <content:encoded><![CDATA[<!--$--><p><em>2024 年 8 月 28 日</em></p>
<h1 class="rp-toc-include" id="rspack-10-发布公告"><a href="#rspack-10-发布公告" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rspack 1.0 发布公告<!-- --> </h1><div class="rp-not-doc rp-llms-container"><button class="rp-not-doc rp-llms-button rp-llms-copy-button"><div class="rp-llms-copy-button__icon-wrapper"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-llms-copy-button__icon-success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-llms-copy-button__icon-copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg></div><span>复制 Markdown</span></button><button class="rp-llms-button rp-llms-view-options__trigger "><svg width="1em" height="1em" viewBox="0 0 32 32" class="rp-llms-view-options__arrow "><path fill="currentColor" d="M16 22 6 12l1.4-1.4 8.6 8.6 8.6-8.6L26 12z"></path></svg></button></div>
<p><img src="https://assets.rspack.rs/rspack/rspack-banner-v1-0.png" alt=""/></p>
<hr/>
<p><strong>Rspack 1.0 版本现已发布</strong>！</p>
<p>Rspack 是基于 Rust 编写的下一代 JavaScript 打包工具， 兼容 webpack 的 API 和生态，并提供 10 倍于 webpack 的构建性能。</p>
<p>在 18 个月前，我们开源了 Rspack 0.1，并收到了大量来自社区的反馈和贡献。在这期间，170 位贡献者参与了 Rspack 开发，提交了超过 5000 个 pull request 和超过 2000 个 issues，帮助 Rspack 快速迭代了 80 个版本。同时，Rspack 的 npm 周下载量也突破了 10 万 🎉</p>
<p><img src="https://assets.rspack.rs/rspack/assets/rspack-v1-0-stats.png" alt="Rspack Stats"/></p>
<p>今天，Rspack 终于到达了一个崭新的阶段 —— 1.0。这意味着 Rspack 已经达到生产稳定，覆盖了 webpack 绝大多数的 API 和功能，并已经做好支持更多用户的准备。</p>
<h2 class="rp-toc-include" id="谁在使用-rspack"><a href="#谁在使用-rspack" class="rp-header-anchor rp-link" aria-hidden="true">#</a>谁在使用 Rspack</h2>
<p>自 Rspack 开源以来，已经有众多企业和开发者在生产环境使用 Rspack，Rspack 每周的 npm 下载量也突破了 10 万。</p>
<p><img src="https://assets.rspack.rs/rspack/assets/rspack-v1-0-downloads.png" alt="Rspack downloads"/></p>
<p>在字节跳动内部，Rspack 的周下载量超过 40 万，有超过 1000 个 Web 应用在使用 Rspack，包括 TikTok、抖音、飞书、Coze 等。这些项目接入 Rspack 后，显著改进了构建耗时和迭代效率。这也帮助我们发现了 Rspack 早期的一些设计问题，促使我们改进架构，在迁移成本、性能和灵活性等方面做好权衡。</p>
<p>我们也看到更多的企业级用户开始使用 Rspack，包括微软、Amazon、阿里巴巴、Intuit、Bit.dev、Discord 等等。我们很高兴 Rspack 能够帮助这些企业用户实现渐进式迁移，也期望未来与更多的企业和开发者建立合作和交流。</p>
<p><img src="https://assets.rspack.rs/rspack/assets/rspack-v1-0-who-is-using.png" alt="Who is using"/></p>
<h2 class="rp-toc-include" id="新特性"><a href="#新特性" class="rp-header-anchor rp-link" aria-hidden="true">#</a>新特性</h2>
<p>自 0.1 发布以来，Rspack 推出了诸多重要的功能和优化，包括：</p>
<h3 class="rp-toc-include" id="更极致的性能"><a href="#更极致的性能" class="rp-header-anchor rp-link" aria-hidden="true">#</a>更极致的性能</h3>
<p>作为基于 Rust 实现的 Bundler，性能始终是 Rspack 的一个核心指标。从 Rspack 0.1 发布以来，我们对 Rspack 做了大量的性能改进，优化各个场景下的性能表现，并支持了 <a href="/zh/config/experiments#experimentslazycompilation" class="rp-link">lazy compilation</a> 等核心功能，以保障 Rspack 在大型项目中有更佳的性能。</p>
<p>下图是 Rspack 0.1 与 Rspack 1.0 在 <a href="https://github.com/rstackjs/build-tools-performance" target="_blank" rel="noopener noreferrer" class="rp-link">benchmark</a> 中的 build 性能对比。可以看到，Rspack 在实现大量新特性的同时，也显著提升了构建性能：</p>
<p><img src="https://assets.rspack.rs/rspack/assets/rspack-v1-0-benchmark.png" alt="Rspack benchmark"/></p>
<p>值得注意的是，Rspack 当前的架构和代码实现仍有许多优化空间。在 1.0 发布后，我们计划继续将 Rspack 的性能提升数倍 🚀，从而更好地支持大型应用开发。</p>
<h3 class="rp-toc-include" id="更好的兼容性"><a href="#更好的兼容性" class="rp-header-anchor rp-link" aria-hidden="true">#</a>更好的兼容性</h3>
<p>在 0.1 刚发布的时候，Rspack 尚未实现许多的 webpack API 和 Hooks，只能兼容有限的 webpack 插件和 loaders，这使我们需要 fork 一些社区库来适配 Rspack，例如早期的 <a href="https://www.npmjs.com/package/@rspack/plugin-html" target="_blank" rel="noopener noreferrer" class="rp-link">@rspack/plugin-html</a>、<a href="https://www.npmjs.com/package/@rspack/plugin-minify" target="_blank" rel="noopener noreferrer" class="rp-link">@rspack/plugin-minify</a> 和 <a href="https://www.npmjs.com/package/@rspack/plugin-node-polyfill" target="_blank" rel="noopener noreferrer" class="rp-link">@rspack/plugin-node-polyfill</a>。</p>
<p>随着 API 支持的日益完善，Rspack 适配了越来越多的 webpack 插件和 loaders。目前，Rspack 已经兼容了社区几乎所有的 loader。在下载量最高的 50 个 <a href="/zh/guide/compatibility/plugin" class="rp-link">webpack 插件</a> 中，80% 以上都可以在 Rspack 中使用，或是找到替代方案。</p>
<p>在此基础上，Rspack 支持了更多的库和框架，包括 React、Preact、Vue、Solid、Svelte、NestJS 等。我们也感谢社区众多插件的维护者主动适配 Rspack，如 <a href="https://github.com/unjs/unplugin" target="_blank" rel="noopener noreferrer" class="rp-link">unplugin</a> 和 <a href="https://www.npmjs.com/package/node-polyfill-webpack-plugin" target="_blank" rel="noopener noreferrer" class="rp-link">node-polyfill-webpack-plugin</a> 等。这里尤其要感谢 <a href="https://github.com/alexander-akait" target="_blank" rel="noopener noreferrer" class="rp-link">Alexander Akait</a>，他作为 webpack 的主要维护者之一，帮助我们支持了许多 webpack loaders 和插件。</p>
<p>我们也期望未来能够支持和创造更多的社区插件，使 webpack 和 Rspack 的生态更加繁荣。</p>
<h3 class="rp-toc-include" id="更小的包体积"><a href="#更小的包体积" class="rp-header-anchor rp-link" aria-hidden="true">#</a>更小的包体积</h3>
<p>生产构建的包体积一直是 Rspack 最为关注的核心指标。自 0.1 发布以来，Rspack 逐步对齐了 webpack 的各个产物优化能力，实现了完整的 <a href="/zh/plugins/webpack/split-chunks-plugin#splitchunksplugin" class="rp-link">split chunks</a>、<a href="/zh/guide/optimization/tree-shaking" class="rp-link">tree shaking</a>、<a href="/zh/config/optimization#optimizationconcatenatemodules" class="rp-link">scope hoisting</a>、<a href="/zh/config/optimization#optimizationmangleexports" class="rp-link">mangle exports</a> 等重要特性。</p>
<p>当一个项目从 webpack 迁移到 Rspack 后，这些优化能够保障，在提升开发体验的同时，产物的包体积仍与 webpack 处于同一水平。在部分场景下，Rspack 的产物体积已经略优于 webpack。</p>
<p>例如，我们在一个真实的中型 web 应用中进行验证，与 Rspack 0.1 相比，Rspack 1.0 的产物体积从 6600KB 优化至 5900KB，与 webpack 持平。未来，Rspack 也会继续探索更先进的包体积优化方案。</p>
<h3 class="rp-toc-include" id="支持模块联邦-20"><a href="#支持模块联邦-20" class="rp-header-anchor rp-link" aria-hidden="true">#</a>支持模块联邦 2.0</h3>
<p><a href="https://module-federation.io/" target="_blank" rel="noopener noreferrer" class="rp-link">Module Federation</a> 是一种 Micro-Frontend 架构模式，在前端生态中得到广泛应用。Rspack 团队和 Module Federation 团队一起合作开发了 Module Federation 2.0。新版本提供了动态 TS 类型提示、Runtime 插件机制、devtools、平台部署协议等功能，使得 Module Federation 可以更好地支持基于微前端架构的大型应用。</p>
<p>此外，Rspack 也保留着对 Module Federation 1.0 的兼容和支持，使 webpack 项目能够更轻松地迁移。</p>
<h3 class="rp-toc-include" id="稳定的-api-和新官网"><a href="#稳定的-api-和新官网" class="rp-header-anchor rp-link" aria-hidden="true">#</a>稳定的 API 和新官网</h3>
<p>在 1.0 中，我们改进了 configuration、JavaScript API、plugin API 的稳定性，这保证了上层的工具和框架能够更加轻松地与 Rspack 集成。同时，我们还完善了官网的指南和 API 文档。</p>
<p>Rspack 1.0 还包含一个<a href="/zh/" class="rp-link">全新的文档首页</a>，感谢设计师 Emily Jackson 和团队成员 <a href="https://github.com/ScriptedAlchemy" target="_blank" rel="noopener noreferrer" class="rp-link">Zack Jackson</a> 为此付出的努力。</p>
<p><img src="https://assets.rspack.rs/rspack/assets/rspack-v1-0-homepage.png" alt="Rspack Homepage"/></p>
<h2 class="rp-toc-include" id="为什么是-rspack"><a href="#为什么是-rspack" class="rp-header-anchor rp-link" aria-hidden="true">#</a>为什么是 Rspack</h2>
<p>近两年，社区中涌现出多个基于 Rust 的 bundler，它们的性能表现都相当优异。Rspack 在确保卓越性能的同时，也在灵活度、兼容性等方面做到了社区领先。</p>
<p>Rspack 当前的目标是：</p>
<ul>
<li>帮助现有的 webpack 项目渐进地迁移到高性能的 bundler 上，使构建性能不再成为项目迭代的瓶颈；</li>
<li>Rspack 不仅仅适用于浏览器和 Node.js 这种我们熟悉的环境中，它的目标是覆盖所有运行 JavaScript 的场景，这意味着 Rspack 也可以很方便地支持 Deno、Electron、跨平台、小程序等一切 JavaScript 可以运行的环境。</li>
<li>我们发现在单一的工具上兼顾「灵活性」和「开箱即用」是非常困难的事情。因此，在开源 Rspack 之后，我们开发了一套完整的 Rstack 工具链，包含 Rsbuild、Rspress、Rsdoctor 和 Rslib，它们分别面向不同的使用场景。例如，为了解决 Rspack 配置复杂、上手成本高的问题，我们通过 Rsbuild 来提供开箱即用的开发体验。</li>
</ul>
<h3 class="rp-toc-include" id="rstack"><a href="#rstack" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rstack</h3>
<p><img src="https://assets.rspack.rs/rspack/assets/rspack-v1-0-rstack.png" alt="Rstack"/></p>
<p>Rstack 是 &quot;Rspack Stack&quot; 的缩写，代表以 Rspack 为核心的一整套技术栈，包含以下工具：</p>
<ul>
<li><a href="https://github.com/web-infra-dev/rspack" target="_blank" rel="noopener noreferrer" class="rp-link">Rspack</a> 专注于实现底层的高性能 bundler，兼顾性能和灵活的配置。</li>
<li><a href="https://github.com/web-infra-dev/rsbuild" target="_blank" rel="noopener noreferrer" class="rp-link">Rsbuild</a> 专注于构建 Web 应用，提供开箱即用的开发体验。</li>
<li><a href="https://github.com/web-infra-dev/rslib" target="_blank" rel="noopener noreferrer" class="rp-link">Rslib</a> 专注于构建 library，提供高质量的 ESM 和 CJS 产物。</li>
<li><a href="https://github.com/web-infra-dev/rspress" target="_blank" rel="noopener noreferrer" class="rp-link">Rspress</a> 专注于生成静态站点，支持 MDX 来搭建文档站和博客。</li>
<li><a href="https://github.com/web-infra-dev/rsdoctor" target="_blank" rel="noopener noreferrer" class="rp-link">Rsdoctor</a> 专注于构建分析，帮助开发者解决构建相关的问题。</li>
</ul>
<p>这些工具共同构成了 Rstack 技术栈。我们希望通过提供统一的 web 开发工具，为开发者和用户带来一流的体验。</p>
<h3 class="rp-toc-include" id="兼容-webpack"><a href="#兼容-webpack" class="rp-header-anchor rp-link" aria-hidden="true">#</a>兼容 webpack</h3>
<p>Rspack 1.0 是对标 webpack v5 设计的，这帮助了大量使用 webpack 的项目平滑地迁移到 Rspack。在兼容 webpack 的同时，Rspack 1.0 也在拥抱现代 Web 标准、追求极致的构建性能：</p>
<ul>
<li>对于 Web 标准，Rspack 持续在积极拥抱现代 Web 标准的演进，跟进最新的 TC39 和 Web 标准。例如， Rspack 已经支持了通过 <a href="https://developer.mozilla.org/en-US/docs/Web/API/Worker/Worker" target="_blank" rel="noopener noreferrer" class="rp-link">new Worker()</a> 引入 Web Worker、支持通过 <a href="https://github.com/tc39/proposal-import-attributes" target="_blank" rel="noopener noreferrer" class="rp-link">Import Attributes</a> 引入 JSON modules， 支持按照 <a href="https://web.dev/articles/css-module-scripts" target="_blank" rel="noopener noreferrer" class="rp-link">CSS Module Scripts</a> 规范引入 CSS 等。</li>
<li>对于性能，我们在 1.0 引入了许多的优化方式。例如，当 JavaScript 侧未使用某个 hook 时，Rust 侧就不会触发到 JavaScript 侧的相关通信；再比如，Rspack 对许多通信对象做了懒加载优化，即使通信的对象很大，如果 JavaScript 只消费其中的部分属性，Rspack 也只会传输被消费的数据，将 Rust 和 JavaScript 的通信开销降低到最低。此外，未来 Rspack 会考虑提供更加轻量的 hooks，以实现更加高效的 Rust 和 JavaScript 的通信。</li>
</ul>
<p>在 Rspack 未来的 major 版本中，将基于 webpack API 进行演进，使其更符合现代 web 开发的需求。</p>
<h2 class="rp-toc-include" id="如何使用-10"><a href="#如何使用-10" class="rp-header-anchor rp-link" aria-hidden="true">#</a>如何使用 1.0</h2>
<p>如果你正在使用 Rspack 0.7 或更早的版本，请留意 1.0 版本包含一些不兼容更新，为此我们准备了详细的文档来帮助升级，请参考：<a href="/zh/guide/migration/rspack_0.x" class="rp-link">从 Rspack 0.x 迁移</a>。</p>
<p>如果你还未使用过 Rspack，请参考 <a href="/zh/guide/start/quick-start" class="rp-link">快速上手</a> 来接入 Rspack，也欢迎为 <a href="https://github.com/web-infra-dev/rspack" target="_blank" rel="noopener noreferrer" class="rp-link">Rspack GitHub 仓库</a> 点亮一颗 Star 🌟。</p>
<h2 class="rp-toc-include" id="下一步"><a href="#下一步" class="rp-header-anchor rp-link" aria-hidden="true">#</a>下一步</h2>
<p>Rspack 1.0 是一个全新的起点，在本次发布后，Rspack 团队将聚焦于以下目标：</p>
<ul>
<li><strong>开发 Rspack 1.x。</strong> Rspack 将在 1.x 版本迭代 12～18 个月，并带来更多的新特性和改进。</li>
<li><strong>发布 Rsbuild 1.0。</strong> 它基于 Rspack 1.0，并支持<a href="https://rsbuild.rs/guide/advanced/environments" target="_blank" rel="noopener noreferrer" class="rp-link">多环境构建</a>。目前 Rsbuild 已发布 1.0 RC，预计在 9 月发布正式版。</li>
<li><strong>发布 Rsdoctor 1.0。</strong> 该版本将改进对 Vue 项目的支持，并提供适用于 CI / CD 环境的<a href="https://github.com/web-infra-dev/rsdoctor/issues/408" target="_blank" rel="noopener noreferrer" class="rp-link">报告模式</a>。</li>
<li><strong>开发 Rslib 0.x。</strong> Rslib 是基于 Rsbuild 的 library 构建工具，详见 <a href="https://github.com/web-infra-dev/rslib" target="_blank" rel="noopener noreferrer" class="rp-link">Rslib 仓库</a>。</li>
<li><strong>开发 Rspress 2.0。</strong> 它将基于 React 19 实现，并改进一些过去不合理的设计，详见 <a href="https://github.com/web-infra-dev/rspress/discussions/1105" target="_blank" rel="noopener noreferrer" class="rp-link">Rspress v2.0 planning</a>。</li>
</ul>
<p>下面是一些我们计划在 Rspack 1.x 支持的关键能力：</p>
<h3 class="rp-toc-include" id="更快的-hmr"><a href="#更快的-hmr" class="rp-header-anchor rp-link" aria-hidden="true">#</a>更快的 HMR</h3>
<p>Rspack 目前能够满足大部分项目的性能诉求，但是仍然存在较大的性能优化空间。在开发环境，Rspack 内部的 make 阶段已经实现了接近常量级别的增量构建，在 seal 阶段仍然有一些计算会随着项目规模的增加而变慢。未来 Rspack 会对 seal 阶段的各个计算进行增量化改造，从而将 HMR 耗时控制在常量级别。</p>
<h3 class="rp-toc-include" id="可移植的缓存"><a href="#可移植的缓存" class="rp-header-anchor rp-link" aria-hidden="true">#</a>可移植的缓存</h3>
<p>Rspack 缓存能力的演进路线，是依次实现 memory cache、persistent cache 和 portable cache。目前 Rspack 已经实现了 memory cache，它带来了出色的 HMR 性能。下一步，我们将在此基础上实现 persistent cache ，这将解决大型项目冷启动耗时较长的问题，功能上对齐 webpack。</p>
<p>在这之后，我们计划进一步实现 <strong>portable cache</strong>，这意味着 Rspack 的构建缓存不仅是持久化的，同时也可以被移植到任何不同的环境和机器，这将帮助团队更好地利用缓存，并为分布式构建奠定基础。</p>
<h3 class="rp-toc-include" id="基于-typescript-的优化"><a href="#基于-typescript-的优化" class="rp-header-anchor rp-link" aria-hidden="true">#</a>基于 TypeScript 的优化</h3>
<p>目前 Rspack 在处理 TypeScript 模块时，会先通过 loader 将其转换为 JavaScript 再处理。这虽然提供了充足的灵活性，但是也阻碍了进一步的产物优化。 例如，开发者需要使用 <code>enum</code> 替代 <code>const enum</code>，但是 <code>enum</code> 本身难以进行常量优化，未来我们考虑重新将 TypeScript 作为 Rspack 的一等公民，充分利用 TypeScript 的静态信息，提供更高级的编译产物优化（如 <a href="https://github.com/google/closure-compiler/wiki/Type-Based-Property-Renaming" target="_blank" rel="noopener noreferrer" class="rp-link">基于 type 的 property renaming</a>）。</p>
<h3 class="rp-toc-include" id="稳定的-rust-api"><a href="#稳定的-rust-api" class="rp-header-anchor rp-link" aria-hidden="true">#</a>稳定的 Rust API</h3>
<p>目前，上层工具可以使用 JS API 来集成 Rspack，这提供了良好的扩展性。但是 Rust 和 JavaScript 存在通信开销，这在一定程度上限制了 Rspack 的性能。我们也提供了 <a href="/zh/guide/features/builtin-swc-loader#jscexperimentalplugins" class="rp-link">SWC Wasm plugin</a> 以支持扩展，但是 Wasm 的性能相比 native 语言仍然有一定差距，为了给上层工具提供更灵活的接入方式和更好的性能，我们计划开放 Rspack 的 Rust API 用于集成。</p>
<h3 class="rp-toc-include" id="react-server-components-支持"><a href="#react-server-components-支持" class="rp-header-anchor rp-link" aria-hidden="true">#</a>React Server Components 支持</h3>
<p>在字节跳动内部，我们已经基于 Rspack 实验性地支持了 RSC（React Server Components），并在一个大型 web 项目中得到验证。未来 Rspack 将会为 RSC 提供一等公民的支持，提供更多的核心能力来帮助实现 RSC。例如，目前 Rspack 已经支持 <a href="/zh/config/experiments#experimentslayers" class="rp-link">layer</a> 特性，能够在单次打包时构建出多种环境的产物。</p>
<h3 class="rp-toc-include" id="改进-esm-产物"><a href="#改进-esm-产物" class="rp-header-anchor rp-link" aria-hidden="true">#</a>改进 ESM 产物</h3>
<p>ESM 是 JavaScript 模块的标准，目前，我们正在改进 Rspack 和 webpack 对 ESM 产物的支持，并实现基于 Rspack 的 library 构建工具—— Rslib。这将帮助开发者更好地使用 Rspack 来构建 npm 包，并享受 ESM 带来的静态分析能力和 tree shaking 支持。</p>
<h2 class="rp-toc-include" id="致谢"><a href="#致谢" class="rp-header-anchor rp-link" aria-hidden="true">#</a>致谢</h2>
<p>Rspack 的发展离不开广大的社区贡献者和社区伙伴，这里特别要感谢：</p>
<ul>
<li><a href="https://nx.dev/" target="_blank" rel="noopener noreferrer" class="rp-link">NX team</a> 对于 Rspack 的信任，在 Rspack 开源初期就集成了 Rspack。</li>
<li><a href="https://github.com/zackarychapple" target="_blank" rel="noopener noreferrer" class="rp-link">Zack Chapple</a> 和 <a href="https://www.zephyr-cloud.io/" target="_blank" rel="noopener noreferrer" class="rp-link">Zephyr team</a> 帮助 Rspack 进行项目推广。</li>
<li><a href="https://github.com/unjs/unplugin" target="_blank" rel="noopener noreferrer" class="rp-link">Unplugin team</a> 积极地帮助 Rspack 进行集成，丰富了 Rspack 的插件生态。</li>
<li><a href="https://github.com/aweary" target="_blank" rel="noopener noreferrer" class="rp-link">Brandon Dail</a> 在 Discord 里使用了 Rspack，并帮助我们进行宣传。</li>
<li><a href="https://github.com/xc2" target="_blank" rel="noopener noreferrer" class="rp-link">Kaffi Y</a> 孜孜不倦地在 GitHub 和 Discord 里帮助用户、解答 Rspack 相关的问题。</li>
<li>所有参加字节跳动 Rspack Innovator project 的开发者，如 <a href="https://x.com/Dominus_Kelvin" target="_blank" rel="noopener noreferrer" class="rp-link">Dominus Kelvin</a>，<a href="https://x.com/_yanpes" target="_blank" rel="noopener noreferrer" class="rp-link">Yannik Peschke</a>，<a href="https://x.com/RussellCanfield" target="_blank" rel="noopener noreferrer" class="rp-link">Russell Canfield</a>，<a href="https://x.com/KyryloBashtenko" target="_blank" rel="noopener noreferrer" class="rp-link">Kyrylo</a> 提供了早期的反馈和建议。</li>
<li>所有从 0.x 版本开始使用 Rspack 的企业和用户，他们宝贵的意见帮助了 Rspack 更好地进步。</li>
</ul>
<p>在开源社区上，Rspack 获得了 2024 年度 <a href="https://osawards.com/javascript/" target="_blank" rel="noopener noreferrer" class="rp-link">Breakthrough of the Year 奖项</a>，这对于 Rspack 团队是一个很大的鼓舞，感谢所有投票支持 Rspack 的开发者：</p>
<p><img src="https://assets.rspack.rs/rspack/assets/rspack-v1-0-osawards.png" alt="Rspack OSS Awards"/></p>
<p>自 0.1 发布后，我们和社区的多个团队建立了深入的合作关系。例如：</p>
<ul>
<li>在对齐 webpack 的过程中，我们和 webpack team 合作，优化 webpack 对于原生 CSS 和 ESM 产物的支持。在这个期间，Rspack 团队向 webpack 提交了超过 100 个 commits，再次感谢 <a href="https://github.com/alexander-akait" target="_blank" rel="noopener noreferrer" class="rp-link">Alexander Akait</a> 给予的 review 意见。</li>
<li>我们也与 SWC 团队合作，贡献了 Preact Refresh SWC 插件，并修复了若干个 SWC 的 transform 和 minify 的 bug，感谢 <a href="https://github.com/kdy1" target="_blank" rel="noopener noreferrer" class="rp-link">kdy</a> 给予的 review 意见。</li>
<li>Rspack 积极拥抱 <a href="https://github.com/unjs/unplugin" target="_blank" rel="noopener noreferrer" class="rp-link">unplugin</a> 的生态，完整支持了 unplugin API，感谢 <a href="https://github.com/sxzz" target="_blank" rel="noopener noreferrer" class="rp-link">sxzz</a> 的 review 意见和 <a href="https://github.com/antfu" target="_blank" rel="noopener noreferrer" class="rp-link">antfu</a> 的非凡创造力。</li>
</ul>
<p>同时我们也很欣喜地看到，Rspack 正在被应用或集成到更广泛的生态上，包括 <a href="https://medium.com/@yanirmanor/why-moving-to-rspack-and-how-to-use-it-with-bazel-9f66139fe493" target="_blank" rel="noopener noreferrer" class="rp-link">Bazel</a>、<a href="https://github.com/rstackjs/storybook-rsbuild" target="_blank" rel="noopener noreferrer" class="rp-link">Storybook</a>、<a href="https://github.com/noshower/electron-forge-plugin-rspack" target="_blank" rel="noopener noreferrer" class="rp-link">Electron</a> 等。</p>
<p>最后，再次感谢所有为 Rspack 生态贡献过的开发者 ❤️：</p>
<p><img src="https://assets.rspack.rs/rspack/assets/rspack-v1-0-contributors.png" alt="Rspack Contributors"/></p>
<h2 class="rp-toc-include" id="常见问题"><a href="#常见问题" class="rp-header-anchor rp-link" aria-hidden="true">#</a>常见问题</h2>
<h3 class="rp-toc-include" id="发布-10-意味着什么"><a href="#发布-10-意味着什么" class="rp-header-anchor rp-link" aria-hidden="true">#</a>发布 1.0 意味着什么？</h3>
<p>1.0 的发布，意味着 Rspack 实现了 webpack 的核心功能，API 达到稳定。在未来 12～18 个月内，我们会保证 Rspack 1.x API 的稳定性，开发者可以放心地基于 Rspack API 开发上层的框架和工具。在 1.x 的迭代期间，我们仍然可能会发现一些 Rspack 不合理的设计，我们将通过 <a href="/zh/config/experiments#experimentsrspackfuture" class="rp-link">future flags</a> 的方式，实现渐进式地升级。</p>
<h3 class="rp-toc-include" id="什么时候发布-rsbuild-10"><a href="#什么时候发布-rsbuild-10" class="rp-header-anchor rp-link" aria-hidden="true">#</a>什么时候发布 Rsbuild 1.0？</h3>
<p>我们正在进行 Rsbuild 1.0 发布的准备工作，并计划于 9 月上旬正式发布。</p>
<p>在发布 Rspack 1.0 的同时，我们也已经发布了 Rsbuild 1.0 RC 版本，后续 Rsbuild 将不再引入不兼容更新。请参考 <a href="https://rsbuild.rs/zh/guide/migration/rsbuild-0-x" target="_blank" rel="noopener noreferrer" class="rp-link">从 Rsbuild 0.x 迁移</a> 升级到 Rsbuild 1.0 RC。</p>
<h3 class="rp-toc-include" id="rspack-遵循语义化版本吗"><a href="#rspack-遵循语义化版本吗" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rspack 遵循语义化版本吗？</h3>
<p>Rspack 遵循语义化版本（semver），不会在 minor 或 patch release 中引入 public API 的不兼容变更，注意有以下一些特例：</p>
<blockquote>
<p>如果你的项目对语义化版本有着严格的要求，可以将 Rspack 固定到 minor 版本。</p>
</blockquote>
<h4 class="rp-toc-include" id="实验性特性"><a href="#实验性特性" class="rp-header-anchor rp-link" aria-hidden="true">#</a>实验性特性</h4>
<p>Rspack 提供了一些实验性特性，这些特性可以通过 <a href="/zh/config/experiments" class="rp-link">experiments</a> 配置项使用。在 minor release 中，Rspack 可能对这些实验性特性的 public API 做一些调整，并在更新日志中对这些变动进行详细的说明。因此，如果你使用了实验性特性，请留意 minor 版本的更新日志。</p>
<h4 class="rp-toc-include" id="swc-相关特性"><a href="#swc-相关特性" class="rp-header-anchor rp-link" aria-hidden="true">#</a>SWC 相关特性</h4>
<p>Rspack 基于 SWC 实现，而 SWC 目前处于 pre-1.0 阶段。为了及时地跟进 SWC 的修复和优化，我们会定期升级 SWC 版本，这可能会包含 SWC 的一些不兼容变更，或是导致低版本的 SWC Wasm 插件不可用。在这种情况下，如果 SWC 升级包含 breaking change，我们会发布 Rspack 的 minor 版本，并在更新日志中说明,；如果 SWC 升级不包含 breaking change，我们可能会发布在 Rspack 的 patch 或者 minor 版本。</p>
<h4 class="rp-toc-include" id="ts-类型"><a href="#ts-类型" class="rp-header-anchor rp-link" aria-hidden="true">#</a>TS 类型</h4>
<p>在 minor 版本中，Rspack 导出的类型可能会发生变化，这是因为：</p>
<ul>
<li>TypeScript 自身不遵循 semver，它可能在 minor 版本引入一些不兼容变更，使得 Rspack 需要调整类型。</li>
<li>Rspack 可能会利用一些高版本 TypeScript 引入的特性，对一些使用低版本 TypeScript 的项目造成影响。</li>
</ul>
<h4 class="rp-toc-include" id="修复兼容-webpack-的-bug"><a href="#修复兼容-webpack-的-bug" class="rp-header-anchor rp-link" aria-hidden="true">#</a>修复兼容 webpack 的 bug</h4>
<p>如果在 Rspack 之前版本中错误地实现了 webpack 的 API，那么我们可能在非 major 版本进行修复，并对齐 webpack API 的行为。</p><!--/$-->]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Rspack 1.0 alpha 发布公告]]></title>
            <link>https://rspack.rs/zh/blog/announcing-1-0-alpha</link>
            <guid isPermaLink="false">/zh/blog/announcing-1-0-alpha</guid>
            <pubDate>Fri, 28 Jun 2024 16:00:00 GMT</pubDate>
            <description><![CDATA[Rspack 1.0 alpha 现已发布至 npm！在发布 Rspack 1.0 稳定版之前，我们将进行 1～2 个月的测试，以改进 1.0 版本的 API 稳定性和可靠性，并验证对下游项目的影响。]]></description>
            <content:encoded><![CDATA[<!--$--><p><em>2024 年 6 月 28 日</em></p>
<h1 class="rp-toc-include" id="rspack-10-alpha-发布公告"><a href="#rspack-10-alpha-发布公告" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rspack 1.0 alpha 发布公告<!-- --> </h1><div class="rp-not-doc rp-llms-container"><button class="rp-not-doc rp-llms-button rp-llms-copy-button"><div class="rp-llms-copy-button__icon-wrapper"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-llms-copy-button__icon-success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-llms-copy-button__icon-copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg></div><span>复制 Markdown</span></button><button class="rp-llms-button rp-llms-view-options__trigger "><svg width="1em" height="1em" viewBox="0 0 32 32" class="rp-llms-view-options__arrow "><path fill="currentColor" d="M16 22 6 12l1.4-1.4 8.6 8.6 8.6-8.6L26 12z"></path></svg></button></div>
<p><img src="https://assets.rspack.rs/rspack/rspack-banner-v1-0-alpha.png" alt=""/></p>
<p>Rspack 1.0 alpha 现已发布至 npm！</p>
<p>在发布 Rspack 1.0 稳定版之前，我们将进行 1 ～ 2 个月的测试，以改进 1.0 版本的 API 稳定性和可靠性，并验证对下游项目的影响。</p>
<p>Rspack 1.0 稳定版预计于今年 8 月推出。这将是一个重要的里程碑，意味着 Rspack 已经实现了 webpack 主要的功能和 API，能够帮助成千上万的 webpack 项目平滑地迁移，并获得显著的构建性能提升。</p>
<h2 class="rp-toc-include" id="产物优化"><a href="#产物优化" class="rp-header-anchor rp-link" aria-hidden="true">#</a>产物优化</h2>
<p>Rspack 1.0 默认在 production 构建时开启 <code>optimization.concatenateModules</code>，这个选项用于启用 module concatenation 优化，也被称为作用域提升（Scope Hoisting）。</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  optimization</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-token-comment)">    // 现在在生产中默认启用</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    concatenateModules</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> mode </span><span style="color:var(--shiki-token-keyword)">===</span><span style="color:var(--shiki-token-string-expression)"> &#x27;production&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>Module concatenation 的作用是将多个模块合并到一个函数中，从而减少浏览器解析和执行 JavaScript 代码的开销。合并模块后，可以减少一些冗余的代码，比如模块间的导入和导出语句，这样可以进一步减小打包后的产物体积。</p>
<p>开启 module concatenation 后，Rspack 的产物体积可以减少约 <strong>4% ～ 10%</strong>（before Gzip）。</p>
<p>当前 Rspack 已经对标 webpack 实现了绝大多数的优化策略，在未来的版本中，Rspack 将在 webpack 的基础上进行探索和改进，以提供更深度的优化和更小的产物体积。</p>
<h2 class="rp-toc-include" id="内置-lightning-css"><a href="#内置-lightning-css" class="rp-header-anchor rp-link" aria-hidden="true">#</a>内置 Lightning CSS</h2>
<p>Rspack 1.0 内置支持了 <a href="https://github.com/parcel-bundler/lightningcss" target="_blank" rel="noopener noreferrer" class="rp-link">Lightning CSS</a>。Lightning CSS 是一个用 Rust 编写的高性能 CSS 解析器、转换器、打包器和压缩器。</p>
<p>Rspack 新版本实现了基于 Lightning CSS 的 CSS 压缩插件，并将其作为 Rspack 的默认 CSS 压缩器。与之前使用的 SWC CSS 压缩插件相比，它进行了更多的优化，能够使 CSS 产物更小。</p>
<div class="rp-codeblock language-diff"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="diff" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-foreground)">export default {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  optimization: {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    minimizer: [</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      // 默认的 CSS 压缩器已更改：</span></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">-     new rspack.SwcCssMinimizerRspackPlugin()</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+     new rspack.LightningCssMinimizerRspackPlugin()</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    ],</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  },</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>你也可以通过如下方式切换回 <code>SwcCssMinimizerRspackPlugin</code></p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  optimization</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    minimizer</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">      new</span><span style="color:var(--shiki-token-constant)"> rspack</span><span style="color:var(--shiki-token-function)">.SwcJsMinimizerRspackPlugin</span><span style="color:var(--shiki-foreground)">()</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">      new</span><span style="color:var(--shiki-token-constant)"> rspack</span><span style="color:var(--shiki-token-function)">.SwcCssMinimizerRspackPlugin</span><span style="color:var(--shiki-foreground)">()</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    ]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>例如，Rspack 已经能够对 CSS 模块进行 tree shaking 优化，但这仅能删除 JS 文件未引用的 CSS Modules 类名。使用 Lightning CSS 的 <a href="https://lightningcss.dev/minification.html#unused-symbols" target="_blank" rel="noopener noreferrer" class="rp-link">unusedSymbols</a> 选项后，Rspack 现在可以消除 CSS Modules 文件中未使用的声明，包括 ID、keyframes、CSS variables 或其他 CSS identifiers。</p>
<p>我们相信 Lightning CSS 将成为下一代构建工具的基石，Rspack 将基于 Lightning CSS 支持更多 CSS 编译能力。感谢 <a href="https://github.com/devongovett" target="_blank" rel="noopener noreferrer" class="rp-link">@devongovett</a> 创造了这样优秀的工具。</p>
<h2 class="rp-toc-include" id="精简核心"><a href="#精简核心" class="rp-header-anchor rp-link" aria-hidden="true">#</a>精简核心</h2>
<p>为了使 Rspack v1 能够保持长期稳定，我们移除了一些 Rspack core 内置的非核心功能，使 core 保持精简，并专注于提供 bundler 层面的通用能力。</p>
<p>在 0.x 版本中，Rspack core 内置了部分 SWC 插件，用于支持 Emotion、Styled Components 和 Relay，这是因为 Rspack 早期尚未支持使用 SWC Wasm 插件，只能在 core 中集成它们。</p>
<p>目前 Rspack 已支持通过 <code>builtin:swc-loader</code> 的 <a href="/zh/guide/features/builtin-swc-loader#jscexperimentalplugins" class="rp-link">experimental.plugins</a> 来使用 SWC 插件，因此我们移除了 Rspack core 内置的插件，包括：</p>
<ul>
<li><a href="https://www.npmjs.com/package/@swc/plugin-emotion" target="_blank" rel="noopener noreferrer" class="rp-link">@swc/plugin-emotion</a></li>
<li><a href="https://www.npmjs.com/package/@swc/plugin-relay" target="_blank" rel="noopener noreferrer" class="rp-link">@swc/plugin-relay</a></li>
<li><a href="https://www.npmjs.com/package/@swc/plugin-styled-components" target="_blank" rel="noopener noreferrer" class="rp-link">@swc/plugin-styled-components</a></li>
</ul>
<p>以 <code>@swc/plugin-styled-components</code> 为例，在 v1.0 中可以通过如下方式使用。</p>
<ul>
<li>安装：</li>
</ul>
<div class="rp-codeblock language-bash"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="bash"><code><span class="line"><span style="color:var(--shiki-token-function)">npm</span><span style="color:var(--shiki-token-string)"> i</span><span style="color:var(--shiki-token-string)"> @swc/plugin-styled-components</span><span style="color:var(--shiki-token-string)"> -D</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<ul>
<li>配置：</li>
</ul>
<div class="rp-codeblock language-diff"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="diff" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-foreground)">export default {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  module: {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    rules: [</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        test: /\.jsx?$/,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        loader: &quot;builtin:swc-loader&quot;,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        options: {</span></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">-         rspackExperiments: {</span></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">-           styledComponents: {},</span></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">-         },</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          jsc: {</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+           experimental: {</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+             plugins: [[&quot;@swc/plugin-styled-components&quot;, {}]],</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+           },</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          },</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        },</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      },</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    ],</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  },</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h2 class="rp-toc-include" id="css-打包"><a href="#css-打包" class="rp-header-anchor rp-link" aria-hidden="true">#</a>CSS 打包</h2>
<p>Rspack 1.0 对齐了 webpack 的 <a href="/zh/config/experiments#experimentscss" class="rp-link">experiment.css</a> 默认值，这使得从 webpack 迁移到 Rspack 更加容易。</p>
<p>在 webpack 生态中，有三种常用的方式来打包 CSS 文件：</p>
<ol>
<li>使用 <a href="https://github.com/webpack/css-loader" target="_blank" rel="noopener noreferrer" class="rp-link">css-loader</a> 和 <a href="https://github.com/webpack/mini-css-extract-plugin" target="_blank" rel="noopener noreferrer" class="rp-link">mini-css-extract-plugin</a>，生成独立的 CSS 文件。</li>
<li>使用 <a href="https://github.com/webpack/css-loader" target="_blank" rel="noopener noreferrer" class="rp-link">css-loader</a> 和 <a href="https://github.com/webpack/style-loader" target="_blank" rel="noopener noreferrer" class="rp-link">style-loader</a>，将 CSS 通过 <code>&lt;style&gt;</code> 标签注入。</li>
<li>使用 <a href="/zh/config/experiments#experimentscss" class="rp-link">experiment.css</a>，这是 webpack 5 引入的实验性功能，提供 CSS 原生支持。</li>
</ol>
<p>在 0.x 版本中，Rspack 默认启用了 <code>experiment.css</code>，这会与 css-loader 产生冲突。用户需要手动关闭 <code>experiment.css</code> 才能使用 css-loader。</p>
<p>从 Rspack 1.0 开始，<code>experiment.css</code> 的默认值变更为 <code>false</code>，与 webpack 保持一致，并允许用户使用以上任意一种方法。</p>
<p>你可以添加以下配置来继续使用 <code>experiment.css</code>：</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  experiments</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    css</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> true</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h2 class="rp-toc-include" id="如何升级"><a href="#如何升级" class="rp-header-anchor rp-link" aria-hidden="true">#</a>如何升级</h2>
<p>安装 Rspack 和 Rspack CLI 的 alpha 版本：</p>
<div class="rp-codeblock language-bash"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="bash"><code><span class="line"><span style="color:var(--shiki-token-comment)"># npm</span></span>
<span class="line"><span style="color:var(--shiki-token-function)">npm</span><span style="color:var(--shiki-token-string)"> add</span><span style="color:var(--shiki-token-string)"> -D</span><span style="color:var(--shiki-token-string)"> --save-exact</span><span style="color:var(--shiki-token-string)"> @rspack/core@alpha</span><span style="color:var(--shiki-token-string)"> @rspack/cli@alpha</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-comment)"># yarn</span></span>
<span class="line"><span style="color:var(--shiki-token-function)">yarn</span><span style="color:var(--shiki-token-string)"> add</span><span style="color:var(--shiki-token-string)"> -D</span><span style="color:var(--shiki-token-string)"> --save-exact</span><span style="color:var(--shiki-token-string)"> @rspack/core@alpha</span><span style="color:var(--shiki-token-string)"> @rspack/cli@alpha</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-comment)"># pnpm</span></span>
<span class="line"><span style="color:var(--shiki-token-function)">pnpm</span><span style="color:var(--shiki-token-string)"> add</span><span style="color:var(--shiki-token-string)"> -D</span><span style="color:var(--shiki-token-string)"> --save-exact</span><span style="color:var(--shiki-token-string)"> @rspack/core@alpha</span><span style="color:var(--shiki-token-string)"> @rspack/cli@alpha</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>在 Rspack alpha 测试的过程中，新版本仍会引入少量不兼容更新。我们会在更新日志中标注这些变更。因此，在升级版本之前，请阅读更新日志以了解具体差异。</p>
<p>对于使用 Rsbuild 的用户，请等待 Rsbuild 1.0 Alpha 版本发布（预计在 1 ～ 2 周以后）。</p>
<h2 class="rp-toc-include" id="不兼容更新"><a href="#不兼容更新" class="rp-header-anchor rp-link" aria-hidden="true">#</a>不兼容更新</h2>
<h3 class="rp-toc-include" id="resolvetsconfigpath"><a href="#resolvetsconfigpath" class="rp-header-anchor rp-link" aria-hidden="true">#</a>resolve.tsConfigPath</h3>
<p><code>resolve.tsConfigPath</code> 配置已被移除，请使用 <a href="/zh/config/resolve#resolvetsconfig" class="rp-link">resolve.tsConfig</a> 代替。</p>
<div class="rp-codeblock language-diff"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="diff" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-foreground)">export default {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  resolve: {</span></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">-   tsConfigPath: path.resolve(__dirname, &#x27;./tsconfig.json&#x27;),</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+   tsConfig: path.resolve(__dirname, &#x27;./tsconfig.json&#x27;),</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  },</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h3 class="rp-toc-include" id="rspackexperimentsstyledcomponents"><a href="#rspackexperimentsstyledcomponents" class="rp-header-anchor rp-link" aria-hidden="true">#</a>rspackExperiments.styledComponents</h3>
<p><code>builtin:swc-loader</code> 的 <code>rspackExperiments.styledComponents</code> 配置已被移除，请使用 <a href="https://www.npmjs.com/package/@swc/plugin-styled-components" target="_blank" rel="noopener noreferrer" class="rp-link">@swc/plugin-styled-components</a> 代替。</p>
<div class="rp-codeblock language-diff"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="diff"><code><span class="line"><span style="color:var(--shiki-foreground)">export default {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  module: {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    rules: [</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        test: /\.jsx$/,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        loader: &quot;builtin:swc-loader&quot;,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        options: {</span></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">-         rspackExperiments: {</span></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">-           styledComponents: true,</span></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">-         },</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          jsc: {</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+           experimental: {</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+             plugins: [[&quot;@swc/plugin-styled-components&quot;, {}]],</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+           },</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          },</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        },</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      },</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    ],</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  },</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h3 class="rp-toc-include" id="rspackexperimentsemotion"><a href="#rspackexperimentsemotion" class="rp-header-anchor rp-link" aria-hidden="true">#</a>rspackExperiments.emotion</h3>
<p><code>builtin:swc-loader</code> 的 <code>rspackExperiments.emotion</code> 配置已被移除，请使用 <a href="https://www.npmjs.com/package/@swc/plugin-emotion" target="_blank" rel="noopener noreferrer" class="rp-link">@swc/plugin-emotion</a> 代替。</p>
<div class="rp-codeblock language-diff"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="diff"><code><span class="line"><span style="color:var(--shiki-foreground)">export default {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  module: {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    rules: [</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        test: /\.jsx$/,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        loader: &quot;builtin:swc-loader&quot;,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        options: {</span></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">-         rspackExperiments: {</span></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">-           emotion: true,</span></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">-         },</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          jsc: {</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+           experimental: {</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+             plugins: [[&quot;@swc/plugin-emotion&quot;, {}]],</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+           },</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          },</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        },</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      },</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    ],</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  },</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h3 class="rp-toc-include" id="rspackexperimentsrelay"><a href="#rspackexperimentsrelay" class="rp-header-anchor rp-link" aria-hidden="true">#</a>rspackExperiments.relay</h3>
<p><code>builtin:swc-loader</code> 的 <code>rspackExperiments.relay</code> 配置已被移除，请使用 <a href="https://www.npmjs.com/package/@swc/plugin-relay" target="_blank" rel="noopener noreferrer" class="rp-link">@swc/plugin-relay</a> 代替。</p>
<div class="rp-codeblock language-diff"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="diff"><code><span class="line"><span style="color:var(--shiki-foreground)">export default {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  module: {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    rules: [</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        test: /\.jsx$/,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        loader: &quot;builtin:swc-loader&quot;,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        options: {</span></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">-         rspackExperiments: {</span></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">-           relay: true,</span></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">-         },</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          jsc: {</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+           experimental: {</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+             plugins: [[&quot;@swc/plugin-relay&quot;, {}]],</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+           },</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          },</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        },</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      },</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    ],</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  },</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h3 class="rp-toc-include" id="其他"><a href="#其他" class="rp-header-anchor rp-link" aria-hidden="true">#</a>其他</h3>
<p>其他不兼容更新如下：</p>
<ul>
<li>当 <code>mode === &#x27;none&#x27;</code> 时，<code>optimization.chunkIds</code> 默认值变更为 <code>&#x27;natural&#x27;</code>，详见 <a href="https://github.com/web-infra-dev/rspack/pull/6956" target="_blank" rel="noopener noreferrer" class="rp-link">#6956</a>。</li>
<li>当 <code>mode === &#x27;none&#x27;</code> 时，<code>optimization.moduleIds</code> 默认值变更为 <code>&#x27;natural&#x27;</code>，详见 <a href="https://github.com/web-infra-dev/rspack/pull/6956" target="_blank" rel="noopener noreferrer" class="rp-link">#6956</a>。</li>
<li>Rust crate <code>swc_core</code> 已升级到 <code>0.95.x</code>，请升级你的 SWC Wasm 插件，详见 <a href="https://github.com/web-infra-dev/rspack/pull/6887" target="_blank" rel="noopener noreferrer" class="rp-link">#6887</a>。</li>
<li>移除了 <code>output.amdContainer</code>，使用 <code>output.library.amdContainer</code> 代替，详见 <a href="https://github.com/web-infra-dev/rspack/pull/6958" target="_blank" rel="noopener noreferrer" class="rp-link">#6958</a>。</li>
<li>移除了 <code>Compilation.currentNormalModuleHooks</code>，详见 <a href="https://github.com/web-infra-dev/rspack/pull/6859" target="_blank" rel="noopener noreferrer" class="rp-link">#6859</a>。</li>
<li>移除了 <code>stats.modules[].profile.integration</code>，详见 <a href="https://github.com/web-infra-dev/rspack/pull/6947" target="_blank" rel="noopener noreferrer" class="rp-link">#6947</a>。</li>
<li>移除了一些 <code>SwcJsMinimizerRspackPluginOptions</code> 的选项，详见 <a href="https://github.com/web-infra-dev/rspack/pull/6950" target="_blank" rel="noopener noreferrer" class="rp-link">#6950</a>。</li>
</ul><!--/$-->]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Rspack 0.7 发布公告]]></title>
            <link>https://rspack.rs/zh/blog/announcing-0-7</link>
            <guid isPermaLink="false">/zh/blog/announcing-0-7</guid>
            <pubDate>Tue, 28 May 2024 16:00:00 GMT</pubDate>
            <description><![CDATA[Rspack 0.7 版本发布，支持 lazy compilation，能够显著提升大型应用的 dev startup 性能。同时引入了全新的 css-module-lexer，使 CSS 打包速度提升 4 倍。]]></description>
            <content:encoded><![CDATA[<!--$--><p><em>2024 年 5 月 28 日</em></p>
<h1 class="rp-toc-include" id="rspack-07-发布公告"><a href="#rspack-07-发布公告" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rspack 0.7 发布公告<!-- --> </h1><div class="rp-not-doc rp-llms-container"><button class="rp-not-doc rp-llms-button rp-llms-copy-button"><div class="rp-llms-copy-button__icon-wrapper"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-llms-copy-button__icon-success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-llms-copy-button__icon-copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg></div><span>复制 Markdown</span></button><button class="rp-llms-button rp-llms-view-options__trigger "><svg width="1em" height="1em" viewBox="0 0 32 32" class="rp-llms-view-options__arrow "><path fill="currentColor" d="M16 22 6 12l1.4-1.4 8.6 8.6 8.6-8.6L26 12z"></path></svg></button></div>
<p><img src="https://assets.rspack.rs/rspack/rspack-banner-v0-7.png" alt=""/></p>
<p>Rspack v0.7 版本已经正式发布！</p>
<p>这是 Rspack v1.0 版本发布前的最后一个 minor 版本，此后 Rspack 团队将投入到 v1.0 版本的开发中，并致力于尽快推出 Rspack v1.0 alpha 版本。</p>
<p>在 Rspack v0.7 中，值得关注的变更如下：</p>
<ul>
<li><a href="#%E6%94%AF%E6%8C%81-lazy-compilation" class="rp-link">支持 Lazy Compilation</a>：通过按需编译，显著提升大型应用的 dev startup 性能。</li>
<li><a href="#%E6%9B%B4%E5%BF%AB%E7%9A%84-css-%E6%9E%84%E5%BB%BA" class="rp-link">更快的 CSS 构建</a>：引入全新的 css-module-lexer，使 CSS 打包速度提升 4 倍。</li>
<li><a href="#%E4%B8%8D%E5%85%BC%E5%AE%B9%E6%9B%B4%E6%96%B0" class="rp-link">不兼容更新</a>：移除一些不稳定的 API，使默认行为与 webpack 更加一致。</li>
</ul>
<h2 class="rp-toc-include" id="支持-lazy-compilation"><a href="#支持-lazy-compilation" class="rp-header-anchor rp-link" aria-hidden="true">#</a>支持 Lazy compilation</h2>
<p>Rspack v0.7 支持了 lazy compilation（懒编译），它对于提高多入口应用（MPA）或大型单页面应用（SPA）的 dev 启动性能非常有帮助。</p>
<h3 class="rp-toc-include" id="什么是-lazy-compilation"><a href="#什么是-lazy-compilation" class="rp-header-anchor rp-link" aria-hidden="true">#</a>什么是 Lazy compilation</h3>
<p>Lazy compilation 是一个提升启动性能的良好手段，它可以按需编译模块，而不是在启动时就编译所有模块。这意味着开发者在启动 dev server 时，可以很快看到应用运行，并分次构建所需的模块。</p>
<h3 class="rp-toc-include" id="为什么需要-lazy-compilation"><a href="#为什么需要-lazy-compilation" class="rp-header-anchor rp-link" aria-hidden="true">#</a>为什么需要 Lazy compilation</h3>
<p>尽管 Rspack 本身具备良好的性能，但是面对具有大量模块的应用，其整体构建时间仍然可能不够理想。这是因为应用中的模块需要经过不同 loader 的编译，包括 <code>postcss-loader</code>、<code>sass-loader</code>、<code>vue-loader</code> 等，它们都会产生额外的编译开销。</p>
<p>在启用 lazy compilation 的情况下，Rspack 仅会编译被请求的「页面入口」和「动态 import 模块」，这可以显著减少开发启动时编译的模块数量，从而提升启动时间。</p>
<p>想象下面的场景：</p>
<p>你的团队在开发一个包含几十个页面的 MPA 应用，大部分时候，你只参与开发其中的某几个页面，并不需要构建其他页面的代码。此时，你可以启用 lazy compilation，使 Rspack 仅编译你访问的页面所引用的模块。</p>
<p>在开启 lazy compilation 后，Rspack 会将「页面入口」和「dynamic import」作为分割点，例如：</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">src/a.js</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="src/a.js"><code><span class="line"><span style="color:var(--shiki-token-keyword)">if</span><span style="color:var(--shiki-foreground)"> (someCondition) {</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">  import</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">&#x27;./b.js&#x27;</span><span style="color:var(--shiki-foreground)">);</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">}</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>当我们编译 a.js 时，Rspack 会将 b.js 当成一个空模块，假装用户从未在其中编写过任何代码。一旦我们需要访问 b.js，Rspack 就用其原始内容填充 b.js 模块，有点类似于用户瞬间编写了这部分代码。</p>
<p>以 Rspack 文档站为例，它包含多个页面，当开启 lazy compilation 后，只有访问到的入口及其依赖的模块会被构建，这极大的提升了启动速度，启动时间从 2.1s 降至 0.05s。</p>
<p>当开发者访问网站的某一个页面时，会触发该页面的构建，且这次构建的时间依然会明显小于完整的构建时间。</p>
<p><img src="https://assets.rspack.rs/rspack/assets/lazy-compilation-compare.png" alt="lazy-compilation-compare"/></p>
<h3 class="rp-toc-include" id="如何使用"><a href="#如何使用" class="rp-header-anchor rp-link" aria-hidden="true">#</a>如何使用</h3>
<p>现在，你可以通过 <a href="/zh/config/experiments#experimentslazycompilation" class="rp-link">experiments.lazyCompilation</a> 配置项来开启懒编译功能：</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">const</span><span style="color:var(--shiki-token-constant)"> isDev</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-constant)"> process</span><span style="color:var(--shiki-foreground)">.</span><span style="color:var(--shiki-token-constant)">env</span><span style="color:var(--shiki-foreground)">.</span><span style="color:var(--shiki-token-constant)">NODE_ENV</span><span style="color:var(--shiki-token-keyword)"> ===</span><span style="color:var(--shiki-token-string-expression)"> &#x27;development&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  experiments</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    lazyCompilation</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> isDev</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>注意，当前 lazy compilation 是对齐 webpack 实现的，<strong>并且仍处于实验性阶段</strong>。在部分场景下，lazy compilation 可能无法按照预期工作，或是性能提升不明显。</p>
<p>我们将持续完善 lazy compilation 在不同场景下的可用性，使之达到更稳定的状态。如果你在使用过程中遇到任何问题，欢迎通过 <a href="https://github.com/web-infra-dev/rspack/issues" target="_blank" rel="noopener noreferrer" class="rp-link">GitHub Issues</a> 向我们反馈。</p>
<h2 class="rp-toc-include" id="更快的-css-构建"><a href="#更快的-css-构建" class="rp-header-anchor rp-link" aria-hidden="true">#</a>更快的 CSS 构建</h2>
<p>在 v0.7 版本中，我们对 <a href="/zh/config/experiments#experimentscss" class="rp-link">experiments.css</a> 的内部实现进行了重构。</p>
<p>针对 CSS 依赖分析，我们使用 Rust 开发了 <a href="https://github.com/ahabhgk/css-module-lexer" target="_blank" rel="noopener noreferrer" class="rp-link">css-module-lexer</a>，这是一个针对 CSS Modules 的高性能 lexer，能够解析 CSS 或 CSS Modules 并返回其依赖元信息。</p>
<p>在接入 css-module-lexer 后，Rspack 能够支持更复杂的 CSS Modules 语法，对齐了 webpack 的 <code>css-loader</code> 的行为。比如能够支持以下 CSS Modules 语法：</p>
<div class="rp-codeblock language-css"><div class="rp-codeblock__title">style.module.css</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="css" data-title="style.module.css"><code><span class="line"><span style="color:var(--shiki-foreground)">:local(</span><span style="color:var(--shiki-token-function)">.parent</span><span style="color:var(--shiki-foreground)">):global(</span><span style="color:var(--shiki-token-function)">.child</span><span style="color:var(--shiki-foreground)">) </span><span style="color:var(--shiki-token-keyword)">&gt;</span><span style="color:var(--shiki-token-string-expression)"> ul</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-token-constant)">  color</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> red</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">}</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>下图是重构前后的 CSS 解析流程示意：</p>
<p><img src="https://assets.rspack.rs/rspack/assets/rspack-css-lexer.png" alt="rspack-css-lexer"/></p>
<p>同时，<code>css-module-lexer</code> 也给 Rspack 的 <code>experiments.css</code> 带来了显著的性能提升。经过性能测试，<code>bootstrap.css</code> 打包速度提升约 4 倍：</p>
<ul>
<li>重构前：约 84ms（分析 CSS 依赖约 71ms）</li>
<li>重构后：约 25ms（分析 CSS 依赖约 11ms）</li>
</ul>
<h2 class="rp-toc-include" id="不兼容更新"><a href="#不兼容更新" class="rp-header-anchor rp-link" aria-hidden="true">#</a>不兼容更新</h2>
<p>Rspack 会在 1.0 版本前，逐步下线所有不稳定的 API 和配置，更多配置 / API / 默认行为将与 webpack 保持一致。</p>
<h3 class="rp-toc-include" id="移除一些不稳定的-javascript-api"><a href="#移除一些不稳定的-javascript-api" class="rp-header-anchor rp-link" aria-hidden="true">#</a>移除一些不稳定的 JavaScript API</h3>
<p>Rspack 初期暴露了一些预期仅供内部使用且不稳定的 API，如 <code>compiler.compilation</code> 和 <code>compiler.builtinPlugins</code> 等，这些 API 并不稳定且无法在 webpack 中使用。</p>
<p>在 v0.7 版本中，我们重新整理了目前暴露的 API 及其接口定义。如果你有使用到这些 API，你需要进行一些调整，切换到与 webpack 一致的实现方式。</p>
<p>以下 API 已废弃：</p>
<ul>
<li><code>compiler.builtinPlugins</code></li>
<li><code>compiler.compilation</code></li>
<li><code>compiler.compilationParams</code></li>
<li><code>compiler.getAsset(name)</code></li>
<li><code>statsError.formatted</code></li>
<li><code>statsWarning.formatted</code></li>
<li>...</li>
</ul>
<p>关于废弃 API 的详细情况可参考 <a href="https://github.com/web-infra-dev/rspack/pull/6448" target="_blank" rel="noopener noreferrer" class="rp-link">rspack#6448</a>、<a href="https://github.com/web-infra-dev/rspack/pull/6505" target="_blank" rel="noopener noreferrer" class="rp-link">rspack#6505</a>。</p>
<h3 class="rp-toc-include" id="css-import-规则须先于其他规则"><a href="#css-import-规则须先于其他规则" class="rp-header-anchor rp-link" aria-hidden="true">#</a>CSS @import 规则须先于其他规则</h3>
<p>0.7 版本我们对 <a href="/zh/config/experiments#experimentscss" class="rp-link">experiments.css</a> 的内部实现进行了部分重构。</p>
<p>重构后，当 <code>@import</code> 不在最顶部时，会得到如下报错，此时需要你手动将 <code>@import</code> 规则调整到顶部。</p>
<div class="rp-codeblock language-bash"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="bash"><code><span class="line"><span style="color:var(--shiki-token-function)">ERROR</span><span style="color:var(--shiki-token-string)"> in</span><span style="color:var(--shiki-token-string)"> ./src/main.css</span></span>
<span class="line"><span style="color:var(--shiki-token-function)">  ×</span><span style="color:var(--shiki-token-string)"> Module</span><span style="color:var(--shiki-token-string)"> parse</span><span style="color:var(--shiki-token-string)"> failed:</span></span>
<span class="line"><span style="color:var(--shiki-token-function)">  ╰─▶</span><span style="color:var(--shiki-token-string)">   ×</span><span style="color:var(--shiki-token-string)"> CSS</span><span style="color:var(--shiki-token-string)"> parsing</span><span style="color:var(--shiki-token-string)"> warning:</span><span style="color:var(--shiki-token-string)"> Any</span><span style="color:var(--shiki-token-string-expression)"> &#x27;@import&#x27;</span><span style="color:var(--shiki-token-string)"> rules</span><span style="color:var(--shiki-token-string)"> must</span><span style="color:var(--shiki-token-string)"> precede</span><span style="color:var(--shiki-token-string)"> all</span><span style="color:var(--shiki-token-string)"> other</span><span style="color:var(--shiki-token-string)"> rules</span></span>
<span class="line"><span style="color:var(--shiki-token-function)">         ╭─[4:1]</span></span>
<span class="line"><span style="color:var(--shiki-token-function)">       4</span><span style="color:var(--shiki-token-string)"> │</span><span style="color:var(--shiki-token-string)"> }</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"><span style="color:var(--shiki-token-function)">       5</span><span style="color:var(--shiki-token-string)"> │</span></span>
<span class="line"><span style="color:var(--shiki-token-function)">       6</span><span style="color:var(--shiki-token-string)"> │</span><span style="color:var(--shiki-token-string)"> @import</span><span style="color:var(--shiki-token-string-expression)"> &#x27;bootstrap/dist/css/bootstrap.css&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"><span style="color:var(--shiki-token-function)">         ·</span><span style="color:var(--shiki-token-string)"> ───────</span></span>
<span class="line"><span style="color:var(--shiki-token-function)">       7</span><span style="color:var(--shiki-token-string)"> │</span></span>
<span class="line"><span style="color:var(--shiki-token-function)">       8</span><span style="color:var(--shiki-token-string)"> │</span></span>
<span class="line"><span style="color:var(--shiki-token-function)">         ╰────</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-function)">  help:</span></span>
<span class="line"><span style="color:var(--shiki-token-function)">        You</span><span style="color:var(--shiki-token-string)"> may</span><span style="color:var(--shiki-token-string)"> need</span><span style="color:var(--shiki-token-string)"> an</span><span style="color:var(--shiki-token-string)"> appropriate</span><span style="color:var(--shiki-token-string)"> loader</span><span style="color:var(--shiki-token-string)"> to</span><span style="color:var(--shiki-token-string)"> handle</span><span style="color:var(--shiki-token-string)"> this</span><span style="color:var(--shiki-token-string)"> file</span><span style="color:var(--shiki-token-string)"> type.</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h3 class="rp-toc-include" id="移除-builtins-以及-experimentsrspackfuturenewtreeshaking"><a href="#移除-builtins-以及-experimentsrspackfuturenewtreeshaking" class="rp-header-anchor rp-link" aria-hidden="true">#</a>移除 builtins 以及 experiments.rspackFuture.newTreeshaking</h3>
<p>v0.7 已移除 <code>builtins.treeShaking</code> (oldTreeShaking) 和 <code>experiments.rspackFuture.newTreeshaking</code> (新 tree shaking 开关) 配置，将旧的 tree shaking 功能彻底下线。</p>
<h3 class="rp-toc-include" id="移除-resolvebrowserfield"><a href="#移除-resolvebrowserfield" class="rp-header-anchor rp-link" aria-hidden="true">#</a>移除 resolve.browserField</h3>
<p>该配置为 <code>resolve.aliasFields = [&quot;browser&quot;]</code> 的简写，由于 Rspack 已经支持 <code>resolve.aliasFields</code>，所以不再需要该配置。</p>
<h3 class="rp-toc-include" id="移除-experimentsnewsplitchunks"><a href="#移除-experimentsnewsplitchunks" class="rp-header-anchor rp-link" aria-hidden="true">#</a>移除 experiments.newSplitChunks</h3>
<p>该配置用于开启新的 splitChunks 实现，由于 Rspack 已经默认使用新的 splitChunks 实现，所以不再需要该配置。</p>
<h3 class="rp-toc-include" id="移除-snapshot"><a href="#移除-snapshot" class="rp-header-anchor rp-link" aria-hidden="true">#</a>移除 snapshot</h3>
<p>该配置用于配置 cache snapshot 的行为。在 Rspack 目前的增量架构下，cache 不再依赖 snapshot，所以不再需要该配置。</p>
<h3 class="rp-toc-include" id="移除-generatorcssexportsconvention"><a href="#移除-generatorcssexportsconvention" class="rp-header-anchor rp-link" aria-hidden="true">#</a>移除 generator.css.exportsConvention</h3>
<p>该配置用于控制 experiments.css 的 CSS 模块导出的命名形式，仅对于模块类型为 <code>css/module</code> 的模块才会有导出，对于模块类型为 <code>css</code> 的模块并不存在导出，所以不需要该配置。</p>
<h3 class="rp-toc-include" id="升级-swc-到-091x"><a href="#升级-swc-到-091x" class="rp-header-anchor rp-link" aria-hidden="true">#</a>升级 SWC 到 0.91.x</h3>
<p>升级 Rust crate <code>swc_core</code> 到 <code>0.91.x</code>，这会对使用 SWC Wasm 插件的用户产生影响。</p>
<h2 class="rp-toc-include" id="迁移指南"><a href="#迁移指南" class="rp-header-anchor rp-link" aria-hidden="true">#</a>迁移指南</h2>
<h3 class="rp-toc-include" id="升级-swc-插件"><a href="#升级-swc-插件" class="rp-header-anchor rp-link" aria-hidden="true">#</a>升级 SWC 插件</h3>
<p>在 v0.7 中，Rust crate <code>swc_core</code> 的版本升级到 <code>0.91.x</code>，使用到的 SWC Wasm 插件需要确保其使用的 <code>swc_core</code> 的版本一致性，否则可能产生无法预知的问题。</p>
<p>详情请参考<a href="https://swc.rs/docs/plugin/selecting-swc-core#091x" target="_blank" rel="noopener noreferrer" class="rp-link">文档</a>。</p>
<h3 class="rp-toc-include" id="替换-resolvebrowserfield-为-resolvealiasfields"><a href="#替换-resolvebrowserfield-为-resolvealiasfields" class="rp-header-anchor rp-link" aria-hidden="true">#</a>替换 resolve.browserField 为 resolve.aliasFields</h3>
<p>如果你之前配置了 <code>resolve.browserField</code>，则需要使用 <code>resolve.aliasFields</code> 进行替换：</p>
<ul>
<li><code>resolve.browserField = true</code> 替换为 <code>resolve.aliasFields = [&quot;browser&quot;]</code></li>
<li><code>resolve.browserField = false</code> 替换为 <code>resolve.aliasFields = []</code></li>
</ul>
<h3 class="rp-toc-include" id="移除-generatorcssexportsconvention-1"><a href="#移除-generatorcssexportsconvention-1" class="rp-header-anchor rp-link" aria-hidden="true">#</a>移除 generator.css.exportsConvention</h3>
<p>如果你之前配置了 <code>module.generator.css.exportsConvention</code> 或在 <code>module.rule</code> 中配置了 <code>generator.exportsConvention</code>，只需要删除该配置即可。</p>
<h2 class="rp-toc-include" id="rsbuild-v07"><a href="#rsbuild-v07" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rsbuild v0.7</h2>
<p>Rsbuild v0.7 已与 Rspack v0.7 同步发布，请阅读 <a href="https://rsbuild.rs/zh/community/releases/v0-7" target="_blank" rel="noopener noreferrer" class="rp-link">Rsbuild v0.7 发布</a> 了解更多。</p><!--/$-->]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Rspack 0.6 发布公告]]></title>
            <link>https://rspack.rs/zh/blog/announcing-0-6</link>
            <guid isPermaLink="false">/zh/blog/announcing-0-6</guid>
            <pubDate>Wed, 10 Apr 2024 12:00:00 GMT</pubDate>
            <description><![CDATA[Rspack 0.6 版本发布，内置支持 mini-css-extract-plugin，默认开启新版 tree shaking。]]></description>
            <content:encoded><![CDATA[<!--$--><p><em>2024 年 4 月 10 日</em></p>
<h1 class="rp-toc-include" id="rspack-06-发布公告"><a href="#rspack-06-发布公告" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rspack 0.6 发布公告<!-- --> </h1><div class="rp-not-doc rp-llms-container"><button class="rp-not-doc rp-llms-button rp-llms-copy-button"><div class="rp-llms-copy-button__icon-wrapper"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-llms-copy-button__icon-success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-llms-copy-button__icon-copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg></div><span>复制 Markdown</span></button><button class="rp-llms-button rp-llms-view-options__trigger "><svg width="1em" height="1em" viewBox="0 0 32 32" class="rp-llms-view-options__arrow "><path fill="currentColor" d="M16 22 6 12l1.4-1.4 8.6 8.6 8.6-8.6L26 12z"></path></svg></button></div>
<h2 class="rp-toc-include" id="主要功能更新"><a href="#主要功能更新" class="rp-header-anchor rp-link" aria-hidden="true">#</a>主要功能更新</h2>
<h3 class="rp-toc-include" id="内置支持-mini-css-extract-plugin"><a href="#内置支持-mini-css-extract-plugin" class="rp-header-anchor rp-link" aria-hidden="true">#</a>内置支持 mini-css-extract-plugin</h3>
<p>你现在可以使用 <code>rspack.CssExtractRspackPlugin</code> 作为 <code>mini-css-extract-plugin</code> 的替代。</p>
<p>这在一些场景很实用，例如当内置的 CSS 处理不能满足你的需求，有更定制化的 CSS Modules name 等，或者你想要使用一些依赖 css-loader 的 loader，但仍然想要将 CSS 提取成单独文件。</p>
<p>详细配置见 <a href="/zh/plugins/rspack/css-extract-rspack-plugin#cssextractrspackplugin" class="rp-link">CssExtractRspackPlugin</a>。</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { rspack } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;@rspack/core&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  plugins</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span><span style="color:var(--shiki-token-keyword)">new</span><span style="color:var(--shiki-token-constant)"> rspack</span><span style="color:var(--shiki-token-function)">.CssExtractRspackPlugin</span><span style="color:var(--shiki-foreground)">()]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  module</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    rules</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        test</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> /\.css</span><span style="color:var(--shiki-token-keyword)">$</span><span style="color:var(--shiki-token-string-expression)">/</span><span style="color:var(--shiki-token-keyword)">i</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        use</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span><span style="color:var(--shiki-token-constant)">rspack</span><span style="color:var(--shiki-foreground)">.</span><span style="color:var(--shiki-token-constant)">CssExtractRspackPlugin</span><span style="color:var(--shiki-foreground)">.loader</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-string-expression)"> &#x27;css-loader&#x27;</span><span style="color:var(--shiki-foreground)">]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    ]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<blockquote>
<p>你可以在<a href="https://github.com/rstackjs/rstack-examples/tree/main/rspack/react-with-extract-css" target="_blank" rel="noopener noreferrer" class="rp-link">这里</a>找到一个基础的项目例子。</p>
</blockquote>
<h3 class="rp-toc-include" id="默认开启新版-tree-shaking"><a href="#默认开启新版-tree-shaking" class="rp-header-anchor rp-link" aria-hidden="true">#</a>默认开启新版 tree shaking</h3>
<p>Rspack 在 0.1.0 支持了基本的 tree shaking 功能，由于最初的架构还未稳定, 我们使用了相对简单的方法实现了基础版的 tree shaking（仅支持未使用导出删除），但是随着 Rspack 功能的完善，架构逐渐稳定
基础的 tree shaking 无法满足用户的需求，比如：</p>
<ol>
<li>无法处理循环引用，无法给其他构建阶段足够的优化信息，实现进一步的优化 (mangleExports, concatenateModules, barrel exports optimization)。</li>
<li>经常出现一些 interop 相关的 badcase，例如: worker-thread 模块，Common Js 模块，module federation 等</li>
</ol>
<p>为了解决以上问题，我们决定使用类似 webpack 的方案，自底向上重新实现整个优化流程，并在 0.4.2 引入 <code>experiments.rspackFuture.newTreeshaking</code> 配置，来实验性的开启新的优化算法。
经过 4 个月 bug 修复和优化，新的 tree shaking 算法已经相对稳定，因此我们决定在 0.6.0 默认开启新的 tree shaking 算法。</p>
<h2 class="rp-toc-include" id="不兼容更新"><a href="#不兼容更新" class="rp-header-anchor rp-link" aria-hidden="true">#</a>不兼容更新</h2>
<h3 class="rp-toc-include" id="移除-experimentsrspackfuturedisableapplyentrylazily"><a href="#移除-experimentsrspackfuturedisableapplyentrylazily" class="rp-header-anchor rp-link" aria-hidden="true">#</a>移除 experiments.rspackFuture.disableApplyEntryLazily</h3>
<p><code>experiments.rspackFuture.disableApplyEntryLazily</code> 选项自 v0.5.0 已被默认开启，并在 v0.6.0 中被删除。</p>
<h3 class="rp-toc-include" id="移除-compilerbuild-和-compilerrebuild"><a href="#移除-compilerbuild-和-compilerrebuild" class="rp-header-anchor rp-link" aria-hidden="true">#</a>移除 compiler.build 和 compiler.rebuild</h3>
<p><code>compiler.build</code> 与 <code>compiler.rebuild</code> 不属于 webpack 公开 API，目前已经被移除。</p>
<h3 class="rp-toc-include" id="移除-builtinscss-并引入-css-相关-moduleparser-和-modulegenerator-选项"><a href="#移除-builtinscss-并引入-css-相关-moduleparser-和-modulegenerator-选项" class="rp-header-anchor rp-link" aria-hidden="true">#</a>移除 builtins.css 并引入 CSS 相关 module.parser 和 module.generator 选项</h3>
<p>移除 <code>builtins.css</code>，请使用引入的 CSS 相关的 <a href="/zh/config/module#moduleparsercssauto" class="rp-link"><code>module.parser</code></a> 和 <a href="/zh/config/module#modulegeneratorcssauto" class="rp-link"><code>module.generator</code></a> 选项进行替代。</p>
<p>同时，从 v0.6.0 版本开始，Rspack 的 <code>experiments.css</code> 将会以 webpack 的 <code>experiments.css</code> 为目标进行对齐，这意味着和 webpack <code>experiments.css</code> 一样在未来将不再支持<a href="https://caniuse.com/css-variables" target="_blank" rel="noopener noreferrer" class="rp-link">不支持 CSS 变量的浏览器</a>。因此，对于那些需要使用尚未得到 <code>experiments.css</code> 支持的配置，或者需要兼容老版本浏览器的项目，我们推荐迁移至 <a href="/zh/plugins/rspack/css-extract-rspack-plugin" class="rp-link"><code>rspack.CssExtractRspackPlugin</code></a>。</p>
<p>在 v0.6.0 中，我们引入了三种新的模块类型的 <code>module.generator</code> 和 <code>module.parser</code> 选项：<code>css/auto</code>、<code>css</code> 和 <code>css/module</code>，这些选项只有在启用 experiments.css 时才会生效，关于如何使用可查看<a href="https://github.com/rstackjs/rstack-examples/tree/main/rspack/css-parser-generator-options" target="_blank" rel="noopener noreferrer" class="rp-link">这个例子</a>。</p>
<p>在 <code>module.parser</code> 选项中，<code>css</code>、<code>css/auto</code> 和 <code>css/module</code> 模块类型都包含了 <code>namedExports</code> 属性。它取代了 <code>builtins.css.namedExports</code> 配置。</p>
<p>对于 <code>module.generator</code> 选项，<code>css/auto</code> 和 <code>css/module</code> 模块类型提供了 <code>exportsOnly</code>、<code>exportsConvention</code> 和 <code>localIdentName</code> 属性。<code>css</code> 类型只包含 <code>exportsOnly</code> 和 <code>exportsConvention</code> 属性。<code>exportsOnly</code>、<code>exportsConvention</code> 和 <code>localIdentName</code> 分别取代了 <code>builtins.css.modules.exportsOnly</code>、<code>builtins.css.modules.localsConvention</code> 和 <code>builtins.css.modules.localIdentName</code>。</p>
<p>除此之外，还包括一些关于默认值的修改：</p>
<ol>
<li>
<p><code>exportsConvention</code> 的值从 <code>&#x27;asIs&#x27;</code>, <code>&#x27;camelCaseOnly&#x27;</code> 等变更为 <code>&#x27;as-is&#x27;</code>, <code>&#x27;camel-case-only&#x27;</code> 等，以保持与 webpack <code>experiments.css</code> 的一致。</p>
</li>
<li>
<p><code>namedExports: false</code> 支持同时使用默认导出（default export）、命名导出（named export）和命名空间导出（namespace export），在此之前它只支持使用默认导出：</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js"><code><span class="line"><span style="color:var(--shiki-token-comment)">// v0.6.0 之前只支持使用默认导出</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> classes </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;./index.module.css&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-comment)">// 现在除默认导出之外，也支持：</span></span>
<span class="line"><span style="color:var(--shiki-token-comment)">// 命名空间导出</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-token-constant)"> *</span><span style="color:var(--shiki-token-keyword)"> as</span><span style="color:var(--shiki-foreground)"> classes </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;./index.module.css&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"><span style="color:var(--shiki-token-comment)">// 命名导出</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { class1</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> class2 } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;./index.module.css&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"><span style="color:var(--shiki-token-comment)">// 默认导出和命名导出同时使用</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> classes</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> { class1</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> class2 } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;./index.module.css&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
</li>
<li>
<p><code>namedExports</code> 的默认值从 <code>false</code> 变更为 <code>true</code>，这意味着你需要默认使用命名空间导入（例如 <code>import * as classes from &#x27;./style.css&#x27;</code>）或命名导入（例如 <code>import { class1 } from &#x27;./style.css&#x27;</code>），这将提高与未来<a href="https://web.dev/articles/css-module-scripts" target="_blank" rel="noopener noreferrer" class="rp-link">原生 CSS 模块</a>的兼容性。而这并不意味着你需要一次性迁移所有的导入，你可以通过设置 <code>namedExports: false</code> 来禁用此行为，并且由于现在 <code>namedExports: false</code> 也支持命名导出和命名空间导出，因此你可以逐步迁移这些导入。</p>
</li>
<li>
<p><code>localIdentName</code> 的默认值在从在开发模式下 <code>&#x27;[path][name][ext]__[local]&#x27;</code> 和在生产模式下 <code>&#x27;[hash]&#x27;</code> 变更为在开发和生产模式下都是 <code>&#x27;[uniqueName]-[id]-[local]&#x27;</code>，这将略微改善 CSS 产物的 gzip 压缩大小。</p>
</li>
<li>
<p><code>exportsOnly</code> 的默认值在 <code>target: &#x27;node&#x27;</code> 下由原来的 <code>false</code> 变更为 <code>true</code>。</p>
</li>
<li>
<p>CSS 默认规则的模块类型从 <code>css</code> 变更为 <code>css/auto</code>，<code>css/auto</code> 将自动解析以 <code>.module.</code> 或 <code>.modules.</code> 为中缀的 CSS 文件作为 <a href="https://github.com/css-modules/css-modules" target="_blank" rel="noopener noreferrer" class="rp-link">CSS Modules</a> 处理，这与 <a href="https://github.com/webpack/css-loader?tab=readme-ov-file#auto" target="_blank" rel="noopener noreferrer" class="rp-link"><code>css-loader</code> 的 <code>modules.auto: true</code></a> 行为一致，这将<a href="https://github.com/webpack/webpack/issues/16572" target="_blank" rel="noopener noreferrer" class="rp-link">简化使用 less 或 sass 与 CSS Modules 的规则书写</a>。</p>
</li>
</ol>
<h3 class="rp-toc-include" id="升级-swc-到-090x"><a href="#升级-swc-到-090x" class="rp-header-anchor rp-link" aria-hidden="true">#</a>升级 SWC 到 0.90.x</h3>
<p>升级 Rust crate <code>swc_core</code> 到 <code>0.90.x</code>，这会对使用 SWC Wasm 插件的用户产生影响。</p>
<h3 class="rp-toc-include" id="当-css-的顺序在多个-chunk-中不一致时发出警告"><a href="#当-css-的顺序在多个-chunk-中不一致时发出警告" class="rp-header-anchor rp-link" aria-hidden="true">#</a>当 CSS 的顺序在多个 chunk 中不一致时发出警告</h3>
<p>当多个 chunk 中 CSS 顺序不一致时会发出警告，假如你有两个 entry，entryA 和 entryB，entryA 中引入 a.css 然后引入 b.css，而 entryB 中引入 b.css 然后引入 a.css。
当满足 splitChunks 条件时，a.css 和 b.css 会成为单独 chunk，这个 chunk 中 a.css 和 b.css 的顺序无法保证，会产生如下的警告</p>
<div class="rp-codeblock language-txt"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="txt"><code><span class="line"><span>WARNING in ⚠ chunk src_a_css-src_b_-5c8c53 [css-extract-rspack-plugin]</span></span>
<span class="line"><span>  │ Conflicting order. Following module has been added:</span></span>
<span class="line"><span>  │  * css ./css-loader/dist/cjs.js??ruleSet[1].rules[2].use[1]!./src/a.css</span></span>
<span class="line"><span>  │ despite it was not able to fulfill desired ordering with these modules:</span></span>
<span class="line"><span>  │  * css ./css-loader/dist/cjs.js??ruleSet[1].rules[2].use[1]!./src/b.css</span></span>
<span class="line"><span>  │   - couldn&#x27;t fulfill desired order of chunk group(s) parent2</span></span>
<span class="line"><span>  │   - while fulfilling desired order of chunk group(s) parent1</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>如果你确定他们的顺序不一致没有关系，可以通过配置 <code>ignoreWarnings</code> 来忽略这种错误。</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  ignoreWarnings</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span><span style="color:var(--shiki-token-string-expression)">/Conflicting order/</span><span style="color:var(--shiki-foreground)">]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h2 class="rp-toc-include" id="迁移指南"><a href="#迁移指南" class="rp-header-anchor rp-link" aria-hidden="true">#</a>迁移指南</h2>
<h3 class="rp-toc-include" id="使用-rspackcssextractrspackplugin"><a href="#使用-rspackcssextractrspackplugin" class="rp-header-anchor rp-link" aria-hidden="true">#</a>使用 rspack.CssExtractRspackPlugin</h3>
<p>如果你曾经使用 webpack 和 <code>mini-css-extract-plugin</code>，只需要将 <code>mini-css-extract-plugin</code> 换成 <code>rspack.CssExtractPlugin</code> 即可。</p>
<div class="rp-codeblock language-diff"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="diff" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-inserted)">+ import { rspack } from &#x27;@rspack/core&#x27;;</span></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">- import CssExtract from &#x27;mini-css-extract-plugin&#x27;;</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-foreground)">export default {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  plugins: [new rspack.CssExtractRspackPlugin()],</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  module: {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    rules: [</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        test: /\.css$/i,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        use: [CssExtract.loader, &#x27;css-loader&#x27;],</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      },</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    ],</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  },</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h3 class="rp-toc-include" id="迁移-builtinscss-配置"><a href="#迁移-builtinscss-配置" class="rp-header-anchor rp-link" aria-hidden="true">#</a>迁移 builtins.css 配置</h3>
<ol>
<li>使用 <code>module.parser[&quot;css/auto&quot;].namedExports</code> 替代 <code>builtins.css.namedExports</code>。</li>
<li>使用 <code>module.generator[&quot;css/auto&quot;].exportsOnly</code> 替代 <code>builtins.css.modules.exportsOnly</code>。</li>
<li>使用 <code>module.generator[&quot;css/auto&quot;].exportsConvention</code> 替代 <code>builtins.css.modules.localsConvention</code>。</li>
<li>使用 <code>module.generator[&quot;css/auto&quot;].localIdentName</code> 替代 <code>builtins.css.modules.localIdentName</code>。</li>
</ol>
<p>以上出现的 <code>&quot;css/auto&quot;</code> 为 CSS 默认的模块类型，可根据需要修改为 <code>&quot;css&quot;</code> 或 <code>&quot;css/module&quot;</code>。</p>
<p>添加以下配置将保持原有 <code>builtins.css</code> 默认行为，可根据以下配置根据需要进行修改：</p>
<div class="rp-codeblock language-diff"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="diff" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-foreground)">export default {</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+  module: {</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+    generator: {</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+      &quot;css/auto&quot;: {</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+        exportsOnly: false,</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+        exportsConvention: &#x27;as-is&#x27;,</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+        localIdentName: isProduction ? &#x27;[hash]&#x27; : &#x27;[path][name][ext]__[local]&#x27;,</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+      },</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+      &quot;css&quot;: {</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+        exportsOnly: false,</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+        exportsConvention: &#x27;as-is&#x27;,</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+      },</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+      &quot;css/module&quot;: {</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+        exportsOnly: false,</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+        exportsConvention: &#x27;as-is&#x27;,</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+        localIdentName: isProduction ? &#x27;[hash]&#x27; : &#x27;[path][name][ext]__[local]&#x27;,</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+      },</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+    },</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+    parser: {</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+      &quot;css/auto&quot;: {</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+        namedExports: false,</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+      },</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+      &quot;css&quot;: {</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+        namedExports: false,</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+      },</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+      &quot;css/module&quot;: {</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+        namedExports: false,</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+      },</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+    },</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+  },</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">}</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>如需要对部分模块进行配置，可使用 <code>module.rules</code> 中的 <a href="/zh/config/module-rules#rulesparser" class="rp-link"><code>rules[].parser</code></a> 和 <a href="/zh/config/module-rules#rulesgenerator" class="rp-link"><code>rules[].generator</code></a> 选项进行配置。</p>
<h3 class="rp-toc-include" id="调用-compilerrun-执行构建"><a href="#调用-compilerrun-执行构建" class="rp-header-anchor rp-link" aria-hidden="true">#</a>调用 compiler.run 执行构建</h3>
<p><code>compiler.build</code> 或 <code>compiler.rebuild</code> 已经被废弃，请切换到 <code>compiler.run</code> 进行构建，与重新构建。</p>
<h3 class="rp-toc-include" id="升级-swc-插件"><a href="#升级-swc-插件" class="rp-header-anchor rp-link" aria-hidden="true">#</a>升级 SWC 插件</h3>
<p>在 <code>0.6.0</code> 中，Rust crate <code>swc_core</code> 的版本升级到 <code>0.90.x</code>，使用到的 SWC Wasm 插件需要确保其使用的 <code>swc_core</code> 的版本一致性，否则可能产生无法预知的问题。</p>
<p>详情请参考<a href="https://swc.rs/docs/plugin/selecting-swc-core#090x" target="_blank" rel="noopener noreferrer" class="rp-link">文档</a>。</p><!--/$-->]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Rspack 0.5 发布公告]]></title>
            <link>https://rspack.rs/zh/blog/announcing-0-5</link>
            <guid isPermaLink="false">/zh/blog/announcing-0-5</guid>
            <pubDate>Tue, 09 Jan 2024 16:52:00 GMT</pubDate>
            <description><![CDATA[Rspack 0.5 版本发布，支持模块联邦，移除默认的 SWC 转换。]]></description>
            <content:encoded><![CDATA[<!--$--><p><em>2024 年 1 月 9 日</em></p>
<h1 class="rp-toc-include" id="rspack-05-发布公告"><a href="#rspack-05-发布公告" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rspack 0.5 发布公告<!-- --> </h1><div class="rp-not-doc rp-llms-container"><button class="rp-not-doc rp-llms-button rp-llms-copy-button"><div class="rp-llms-copy-button__icon-wrapper"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-llms-copy-button__icon-success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-llms-copy-button__icon-copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg></div><span>复制 Markdown</span></button><button class="rp-llms-button rp-llms-view-options__trigger "><svg width="1em" height="1em" viewBox="0 0 32 32" class="rp-llms-view-options__arrow "><path fill="currentColor" d="M16 22 6 12l1.4-1.4 8.6 8.6 8.6-8.6L26 12z"></path></svg></button></div>
<h2 class="rp-toc-include" id="主要功能更新"><a href="#主要功能更新" class="rp-header-anchor rp-link" aria-hidden="true">#</a>主要功能更新</h2>
<h3 class="rp-toc-include" id="rspack-支持模块联邦"><a href="#rspack-支持模块联邦" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rspack 支持模块联邦</h3>
<p>请查看<a href="/zh/blog/module-federation-added-to-rspack" class="rp-link">此博客</a>以获取更多详细信息。</p>
<h2 class="rp-toc-include" id="破坏性更新"><a href="#破坏性更新" class="rp-header-anchor rp-link" aria-hidden="true">#</a>破坏性更新</h2>
<h3 class="rp-toc-include" id="调整-optimizationchunkids-生产环境默认值为-deterministic"><a href="#调整-optimizationchunkids-生产环境默认值为-deterministic" class="rp-header-anchor rp-link" aria-hidden="true">#</a>调整 optimization.chunkIds 生产环境默认值为 deterministic</h3>
<p>在生产模式下，<code>optimization.chunkIds</code> 默认值为 <code>&quot;deterministic&quot;</code>，这与 webpack 的默认行为一致。</p>
<h3 class="rp-toc-include" id="支持-rspackhotmodulereplacementplugin"><a href="#支持-rspackhotmodulereplacementplugin" class="rp-header-anchor rp-link" aria-hidden="true">#</a>支持 rspack.HotModuleReplacementPlugin</h3>
<p>支持 <code>rspack.HotModuleReplacementPlugin</code>，如果你没有使用 <code>@rspack/dev-server</code> 而是使用自定义的开发服务器，则需要使用 <code>HotModuleReplacementPlugin</code> 来启用 HMR，而不再将 <code>devServer.hot</code> 设置为 <code>true</code>，这与 webpack 相同。这提供了更多在内部使用 <code>HotModuleReplacementPlugin</code> 的插件的兼容性。</p>
<h3 class="rp-toc-include" id="移除默认转换"><a href="#移除默认转换" class="rp-header-anchor rp-link" aria-hidden="true">#</a>移除默认转换</h3>
<p>之前默认转换是内置的，它将源文件（如 TypeScript）内部转换为兼容的源文件（如 JavaScript）。为了使转换更加可定制，我们通过使用 <code>builtin:swc-loader</code> 将此功能交给用户控制，并放弃了对几个 <a href="/zh/config/module-rules#rulestype" class="rp-link">rules[].type</a> 的支持。这些 <code>rules[].type</code> 已被删除：</p>
<ul>
<li><code>&quot;typescript&quot;</code> 或 <code>&quot;ts&quot;</code></li>
<li><code>&quot;tsx&quot;</code></li>
<li><code>&quot;jsx&quot;</code></li>
</ul>
<p>为了实现旧有的行为，请删除 <code>rules[].type</code> 或将其更改为 <code>&quot;javascript/auto&quot;</code> 并应用你的自定义加载器配置。</p>
<p>转译 <code>.jsx</code> 文件：</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  module</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    rules</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        test</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> /\.jsx</span><span style="color:var(--shiki-token-keyword)">$</span><span style="color:var(--shiki-token-string-expression)">/</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        exclude</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> /[\\/]node_modules[\\/]/</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        loader</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;builtin:swc-loader&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        options</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          jsc</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">            parser</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">              syntax</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;ecmascript&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">              jsx</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> true</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">            }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    ]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>转译 <code>.tsx</code> 文件：</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  module</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    rules</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        test</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> /\.tsx</span><span style="color:var(--shiki-token-keyword)">$</span><span style="color:var(--shiki-token-string-expression)">/</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        exclude</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> /[\\/]node_modules[\\/]/</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        loader</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;builtin:swc-loader&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        options</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          jsc</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">            parser</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">              syntax</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;typescript&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">              tsx</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> true</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">            }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    ]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>转译 <code>.ts</code> 文件：</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  module</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    rules</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        test</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> /\.ts</span><span style="color:var(--shiki-token-keyword)">$</span><span style="color:var(--shiki-token-string-expression)">/</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        exclude</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> /[\\/]node_modules[\\/]/</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        loader</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;builtin:swc-loader&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        options</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          jsc</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">            parser</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">              syntax</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;typescript&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">            }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    ]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h3 class="rp-toc-include" id="target-不再影响用户代码"><a href="#target-不再影响用户代码" class="rp-header-anchor rp-link" aria-hidden="true">#</a>target 不再影响用户代码</h3>
<p>Rspack 将 <a href="/zh/config/target" class="rp-link">target</a> 与 webpack 对齐。Rspack 不再转换任意用户代码，而是让 loader 来控制用户代码的转换。要将用户代码转换为目标环境所需的代码，请将 <code>env</code> 添加到 <code>builtin:swc-loader</code> 中：</p>
<div class="rp-codeblock language-diff"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="diff" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-foreground)">export default {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  module: {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    rules: [</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        test: /\.js$/,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        exclude: /[\\/]node_modules[\\/]/,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        loader: &quot;builtin:swc-loader&quot;,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        options: {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          jsc: {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">            parser: {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">              syntax: &quot;ecmascript&quot;</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">            }</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          },</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+         env: {</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+           targets: &quot;Chrome &gt;= 48&quot;</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+         }</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        }</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      }</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    ]</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">}</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h3 class="rp-toc-include" id="移除扩展的-resolve-extensions"><a href="#移除扩展的-resolve-extensions" class="rp-header-anchor rp-link" aria-hidden="true">#</a>移除扩展的 resolve extensions</h3>
<p><code>resolve.extensions</code> 帮助我们在解析路径过程中省略某些文件扩展名。在之前的版本中，内置支持了 <code>.ts</code>、<code>.tsx</code>、<code>.jsx</code> 这些扩展名，在最新版本中删除了这些扩展名，以保持和 webpack 的行为一致。</p>
<p>为了获得与原来相同的行为，请将 <code>resolve.extensions</code> 更改为以下内容：</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  resolve</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    extensions</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span><span style="color:var(--shiki-token-string-expression)">&#x27;...&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-string-expression)"> &#x27;.tsx&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-string-expression)"> &#x27;.ts&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-string-expression)"> &#x27;.jsx&#x27;</span><span style="color:var(--shiki-foreground)">]</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-comment)"> // &quot;...&quot; 代表着默认的文件扩展名。</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h3 class="rp-toc-include" id="将-swchelpers-和-react-refresh-调整为-peerdependencies"><a href="#将-swchelpers-和-react-refresh-调整为-peerdependencies" class="rp-header-anchor rp-link" aria-hidden="true">#</a>将 @swc/helpers 和 react-refresh 调整为 peerDependencies</h3>
<p>在我们移除默认转换之前，可以通过 <code>target</code> 将你的代码降级为 es5，并通过 <code>builtin.react.refresh</code> 将 react 刷新助手代码插入到你的 react 组件中，因此我们安装了 <code>@swc/helpers</code> 和 <code>react-refresh</code> 作为 <code>@rspack/core</code> 的依赖项，以提供开箱即用的体验。但是现在我们已经移除了默认转换，并建议使用 Rsbuild 来获得开箱即用的体验，因此 <code>@swc/helpers</code> 和 <code>react-refresh</code> 不再需要由 <code>@rspack/core</code> 安装，我们将它们调整为 <code>@rspack/core</code> 的 peerDependencies。</p>
<p>如果你正在使用 <code>builtin:swc-loader</code> 或 <code>swc-loader</code> 的 <code>externalHelpers: true</code> 功能，现在你需要将 <code>@swc/helpers</code> 安装为项目的 dependencies。如果你正在使用 <code>@rspack/plugin-react-refresh</code>，现在你需要将 <code>react-refresh</code> 安装为项目的 devDependencies。</p>
<h3 class="rp-toc-include" id="移除已弃用的-builtins-options"><a href="#移除已弃用的-builtins-options" class="rp-header-anchor rp-link" aria-hidden="true">#</a>移除已弃用的 builtins options</h3>
<p>一些 builtins options 自 v0.4.0 以来已被弃用，并在 v0.5.0 中被删除。</p>
<p>如果你正在使用 <code>builtins.noEmitAssets</code>, <code>builtins.devFriendlySplitChunks</code>, <code>builtins.html</code>, <code>builtins.copy</code>, <code>builtins.minifyOptions</code>，请查看<a href="/zh/blog/announcing-0-4#迁移-builtin-options-到-builtin-plugins" class="rp-link">这篇文档</a>并进行迁移。</p>
<p>而如果你正在使用 <code>builtins.presetEnv</code>, <code>builtins.decorator</code>, <code>builtins.react</code>, <code>builtins.pluginImport</code>, <code>builtins.emotion</code>, <code>builtins.relay</code>, 请查看<a href="/zh/blog/announcing-0-4#废弃默认转换" class="rp-link">这篇文档</a>并进行迁移。</p>
<h3 class="rp-toc-include" id="移除-builtinsass-loader"><a href="#移除-builtinsass-loader" class="rp-header-anchor rp-link" aria-hidden="true">#</a>移除 builtin:sass-loader</h3>
<p><code>builtin:sass-loader</code> 自 v0.4.0 以来已被弃用，并在 v0.5.0 中被删除。如果你仍在使用它，请迁移至 <code>sass-loader</code>。</p>
<h3 class="rp-toc-include" id="移除-experimentsincrementalrebuild-选项"><a href="#移除-experimentsincrementalrebuild-选项" class="rp-header-anchor rp-link" aria-hidden="true">#</a>移除 experiments.incrementalRebuild 选项</h3>
<p><code>experiments.incrementalRebuild</code> 选项自 v0.4.0 以来已被弃用，并在 v0.5.0 中被删除。</p>
<h3 class="rp-toc-include" id="移除-builtinsdevfriendlysplitchunks-和-experimentsnewsplitchunks"><a href="#移除-builtinsdevfriendlysplitchunks-和-experimentsnewsplitchunks" class="rp-header-anchor rp-link" aria-hidden="true">#</a>移除 builtins.devFriendlySplitChunks 和 experiments.newSplitChunks</h3>
<p><code>experiments.newSplitChunks</code> 和 <code>builtins.devFriendlySplitChunks</code> 自 v0.4.0 以来已被弃用，并在 v0.5.0 中被删除。</p>
<h3 class="rp-toc-include" id="移除-experimentsrspackfuturenewresolver-选项"><a href="#移除-experimentsrspackfuturenewresolver-选项" class="rp-header-anchor rp-link" aria-hidden="true">#</a>移除 experiments.rspackFuture.newResolver 选项</h3>
<p><code>experiments.rspackFuture.newResolver</code> 选项自 v0.4.0 以来已被弃用，并在 v0.5.0 中被删除。</p>
<h3 class="rp-toc-include" id="废弃入口配置惰性生效这一行为"><a href="#废弃入口配置惰性生效这一行为" class="rp-header-anchor rp-link" aria-hidden="true">#</a>废弃入口配置惰性生效这一行为</h3>
<p>该行为通过 <a href="/zh/config/experiments#experimentsrspackfuturedisableapplyentrylazily" class="rp-link">experiments.rspackFuture.disableApplyEntryLazily</a> 进行废弃，该配置在 v0.4.5 中引入，在 v0.5.0 中默认启用，并将在 v0.6.0 中移除。</p>
<p>当 <code>experiments.rspackFuture.disableApplyEntryLazily</code> 为 <code>false</code>，<code>options.entry</code> 仍然可以进行有效的修改在 <code>rspack(options)</code> 调用之后，但设置为 <code>true</code> 时将不能，并且该行为和 Webpack5 保持一致。</p>
<p>这个配置大部分情况对于使用 Rspack 开发应用的用户没有影响，但是应该被开发 Rspack 插件或上层框架的开发者注意。</p>
<h2 class="rp-toc-include" id="迁移指南"><a href="#迁移指南" class="rp-header-anchor rp-link" aria-hidden="true">#</a>迁移指南</h2>
<p>v0.5.0 移除了许多已经弃用的功能，除此之外，v0.5.0 引入了四个破坏性更新，如果你正在使用 Rspack 开发应用，那么你只需要关注其中两个。因此，如果你已经迁移到 v0.4+ 并且没有弃用警告，那么 v0.5.0 将很容易迁移，如果你还没有，请查看 <a href="https://rspack.rs/blog/announcing-0.4#migration-guide" target="_blank" rel="noopener noreferrer" class="rp-link">v0.4.0 迁移指南</a>.</p>
<h3 class="rp-toc-include" id="添加-resolveextensions"><a href="#添加-resolveextensions" class="rp-header-anchor rp-link" aria-hidden="true">#</a>添加 resolve.extensions</h3>
<p>这是一个很可能会影响到你的破坏性更新。</p>
<p>在将 <code>@rspack/core</code> 升级到 v0.5.0 后，如果构建失败并出现错误：<code>Can&#x27;t resolve &#x27;./src/foo.tsx&#x27;</code>，或者 <code>Can&#x27;t resolve &#x27;./src/foo.ts&#x27;</code>，或者 <code>Can&#x27;t resolve &#x27;./src/foo.jsx&#x27;</code>，则需要在配置中添加 <code>resolve.extensions = [&#x27;...&#x27;, &#x27;.tsx&#x27;, &#x27;.ts&#x27;, &#x27;.jsx&#x27;]</code>。</p>
<div class="rp-codeblock language-diff"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="diff"><code><span class="line"><span style="color:var(--shiki-foreground)">const configuration = {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  resolve: {</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+   extensions: [&#x27;...&#x27;, &#x27;.tsx&#x27;, &#x27;.ts&#x27;, &#x27;.jsx&#x27;],</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  },</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">}</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>你只需要将所需的扩展名添加到 <code>resolve.extensions</code> 中。例如，如果你没有使用任何 <code>.tsx</code> 或 <code>.ts</code> 文件，只使用 <code>.js</code> 或 <code>.jsx</code> 文件，则只需要添加 <code>&#x27;.jsx&#x27;</code> 到 <code>resolve.extensions</code> 中。<code>&#x27;.js&#x27;</code> 是默认扩展名之一，所有默认扩展名（<code>[&#x27;.js&#x27;, &#x27;.json&#x27;, &#x27;.wasm&#x27;]</code>）都由 <code>&#x27;...&#x27;</code> 表示。</p>
<h3 class="rp-toc-include" id="安装-swchelpers-或-react-refresh"><a href="#安装-swchelpers-或-react-refresh" class="rp-header-anchor rp-link" aria-hidden="true">#</a>安装 @swc/helpers 或 react-refresh</h3>
<p>这是一个很可能会影响到你的破坏性更新。</p>
<p>在将 <code>@rspack/core</code> 升级到 v0.5.0 后，如果构建失败并出现错误：<code>Failed to resolve @swc/helpers/some-helper</code> 或 <code>Failed to resolve react-refresh/some-module</code>，则需要在你的项目中安装 <code>@swc/helpers</code> 或 <code>react-refresh</code>。</p>
<p>如果你正在使用 <code>builtin:swc-loader</code> 或 <code>swc-loader</code> 的 <code>externalHelpers: true</code> 功能，现在你需要将 <code>@swc/helpers</code> 安装为项目的 dependencies。</p>
<div class="rp-tabs"><div class="rp-tabs__label rp-tabs__label--no-scrollbar" style="justify-content:flex-start"><div class="rp-tabs__label__item rp-tabs__label__item--selected" data-index="0"><div style="display:flex;align-items:center;font-size:15px"><svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 256 256"><path fill="#C12127" d="M0 256V0h256v256z"></path><path fill="#FFF" d="M48 48h160v160h-32V80h-48v128H48z"></path></svg><span style="margin-left:6px;margin-bottom:2px">npm</span></div></div><div class="rp-tabs__label__item rp-tabs__label__item--not-selected" data-index="1"><div style="display:flex;align-items:center;font-size:15px"><svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 128 128"><g fill="#2c8ebb"><path d="M99.24 80.71C94.9 80.76 91.1 83 87.89 85c-6 3.71-9 3.47-9 3.47l-.1-.17c-.41-.67 1.92-6.68-.69-13.84c-2.82-7.83-7.3-9.72-6.94-10.32c1.53-2.59 5.36-6.7 6.89-14.36c.91-4.64.67-12.28-1.39-16.28c-.38-.74-3.78 1.24-3.78 1.24s-3.18-7.09-4.07-7.66c-2.87-1.84-6 7.61-6 7.61a14 14 0 0 0-11.71 4.5a9.64 9.64 0 0 1-3.85 2.27c-.41.14-.91.12-2.15 3.47c-1.9 5.07 3.24 10.81 3.24 10.81s-6.13 4.33-8.4 9.72a24.78 24.78 0 0 0-1.75 11.68s-4.36 3.78-4.64 7.68a12.87 12.87 0 0 0 1.77 7.83a1.94 1.94 0 0 0 2.63.91s-2.9 3.38-.19 4.81c2.47 1.29 6.63 2 8.83-.19c1.6-1.6 1.92-5.17 2.51-6.63c.14-.34.62.57 1.08 1a10 10 0 0 0 1.36 1s-3.9 1.68-2.3 5.51c.53 1.27 2.42 2.08 5.51 2.06c1.15 0 13.76-.72 17.12-1.53a4.33 4.33 0 0 0 2.61-1.46a63 63 0 0 0 15.49-7c4.74-3.09 6.68-3.93 10.51-4.84c3.16-.75 2.95-5.65-1.24-5.58z"></path><path d="M64 2a62 62 0 1 0 62 62A62 62 0 0 0 64 2zm37.3 87.83c-3.35.81-4.91 1.44-9.41 4.36a67 67 0 0 1-15.56 7.18a8.71 8.71 0 0 1-3.64 1.77c-3.81.93-16.88 1.63-17.91 1.63h-.24c-4 0-6.27-1.24-7.49-2.54c-3.4 1.7-7.8 1-11-.69a5.55 5.55 0 0 1-3-3.9a6 6 0 0 1 0-2.06a6.66 6.66 0 0 1-.79-1A16.38 16.38 0 0 1 30 84.52c.29-3.73 2.87-7.06 4.55-8.83A28.56 28.56 0 0 1 36.61 64a26.82 26.82 0 0 1 6.82-9c-1.65-2.78-3.33-7.06-1.7-11.42c1.17-3.11 2.13-4.84 4.24-5.58a6.84 6.84 0 0 0 2.51-1.34A17.65 17.65 0 0 1 60.34 31c.19-.48.41-1 .65-1.46c1.6-3.4 3.3-5.31 5.29-6a4.88 4.88 0 0 1 4.4.5c.65.43 1.48 1 3.9 6a4.69 4.69 0 0 1 2.85-.1a3.81 3.81 0 0 1 2.39 1.94c2.47 4.74 2.8 13.19 1.72 18.62a33.8 33.8 0 0 1-5.84 13.31a25.73 25.73 0 0 1 5.77 9.43a25.42 25.42 0 0 1 1.41 10.41A28.7 28.7 0 0 0 86 81.91c3.06-1.89 7.68-4.74 13.19-4.81a6.62 6.62 0 0 1 7 5.7a6.35 6.35 0 0 1-4.89 7.03z"></path></g></svg><span style="margin-left:6px;margin-bottom:2px">yarn</span></div></div><div class="rp-tabs__label__item rp-tabs__label__item--not-selected" data-index="2"><div style="display:flex;align-items:center;font-size:15px"><svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 128 128"><path fill="#f8ab00" d="M0 .004V40h39.996V.004Zm43.996 0V40h40V.004Zm44.008 0V40H128V.004Zm0 43.996v39.996H128V44Z"></path><path fill="#4c4c4c" d="M43.996 44v39.996h40V44ZM0 87.996v40h39.996v-40Zm43.996 0v40h40v-40Zm44.008 0v40H128v-40Z"></path></svg><span style="margin-left:6px;margin-bottom:2px">pnpm</span></div></div><div class="rp-tabs__label__item rp-tabs__label__item--not-selected" data-index="3"><div style="display:flex;align-items:center;font-size:15px"><svg id="Bun" width="1.2em" height="1.2em" viewBox="0 0 80 70"><path id="Shadow" d="M71.09,20.74c-.16-.17-.33-.34-.5-.5s-.33-.34-.5-.5-.33-.34-.5-.5-.33-.34-.5-.5-.33-.34-.5-.5-.33-.34-.5-.5-.33-.34-.5-.5A26.46,26.46,0,0,1,75.5,35.7c0,16.57-16.82,30.05-37.5,30.05-11.58,0-21.94-4.23-28.83-10.86l.5.5.5.5.5.5.5.5.5.5.5.5.5.5C19.55,65.3,30.14,69.75,42,69.75c20.68,0,37.5-13.48,37.5-30C79.5,32.69,76.46,26,71.09,20.74Z"></path><g id="Body"><path id="Background" d="M73,35.7c0,15.21-15.67,27.54-35,27.54S3,50.91,3,35.7C3,26.27,9,17.94,18.22,13S33.18,3,38,3s8.94,4.13,19.78,10C67,17.94,73,26.27,73,35.7Z" style="fill:#fbf0df"></path><path id="Bottom_Shadow" data-name="Bottom Shadow" d="M73,35.7a21.67,21.67,0,0,0-.8-5.78c-2.73,33.3-43.35,34.9-59.32,24.94A40,40,0,0,0,38,63.24C57.3,63.24,73,50.89,73,35.7Z" style="fill:#f6dece"></path><path id="Light_Shine" data-name="Light Shine" d="M24.53,11.17C29,8.49,34.94,3.46,40.78,3.45A9.29,9.29,0,0,0,38,3c-2.42,0-5,1.25-8.25,3.13-1.13.66-2.3,1.39-3.54,2.15-2.33,1.44-5,3.07-8,4.7C8.69,18.13,3,26.62,3,35.7c0,.4,0,.8,0,1.19C9.06,15.48,20.07,13.85,24.53,11.17Z" style="fill:#fffefc"></path><path id="Top" d="M35.12,5.53A16.41,16.41,0,0,1,29.49,18c-.28.25-.06.73.3.59,3.37-1.31,7.92-5.23,6-13.14C35.71,5,35.12,5.12,35.12,5.53Zm2.27,0A16.24,16.24,0,0,1,39,19c-.12.35.31.65.55.36C41.74,16.56,43.65,11,37.93,5,37.64,4.74,37.19,5.14,37.39,5.49Zm2.76-.17A16.42,16.42,0,0,1,47,17.12a.33.33,0,0,0,.65.11c.92-3.49.4-9.44-7.17-12.53C40.08,4.54,39.82,5.08,40.15,5.32ZM21.69,15.76a16.94,16.94,0,0,0,10.47-9c.18-.36.75-.22.66.18-1.73,8-7.52,9.67-11.12,9.45C21.32,16.4,21.33,15.87,21.69,15.76Z" style="fill:#ccbea7;fill-rule:evenodd"></path><path id="Outline" d="M38,65.75C17.32,65.75.5,52.27.5,35.7c0-10,6.18-19.33,16.53-24.92,3-1.6,5.57-3.21,7.86-4.62,1.26-.78,2.45-1.51,3.6-2.19C32,1.89,35,.5,38,.5s5.62,1.2,8.9,3.14c1,.57,2,1.19,3.07,1.87,2.49,1.54,5.3,3.28,9,5.27C69.32,16.37,75.5,25.69,75.5,35.7,75.5,52.27,58.68,65.75,38,65.75ZM38,3c-2.42,0-5,1.25-8.25,3.13-1.13.66-2.3,1.39-3.54,2.15-2.33,1.44-5,3.07-8,4.7C8.69,18.13,3,26.62,3,35.7,3,50.89,18.7,63.25,38,63.25S73,50.89,73,35.7C73,26.62,67.31,18.13,57.78,13,54,11,51.05,9.12,48.66,7.64c-1.09-.67-2.09-1.29-3-1.84C42.63,4,40.42,3,38,3Z"></path></g><g id="Mouth"><g id="Background-2" data-name="Background"><path d="M45.05,43a8.93,8.93,0,0,1-2.92,4.71,6.81,6.81,0,0,1-4,1.88A6.84,6.84,0,0,1,34,47.71,8.93,8.93,0,0,1,31.12,43a.72.72,0,0,1,.8-.81H44.26A.72.72,0,0,1,45.05,43Z" style="fill:#b71422"></path></g><g id="Tongue"><path id="Background-3" data-name="Background" d="M34,47.79a6.91,6.91,0,0,0,4.12,1.9,6.91,6.91,0,0,0,4.11-1.9,10.63,10.63,0,0,0,1-1.07,6.83,6.83,0,0,0-4.9-2.31,6.15,6.15,0,0,0-5,2.78C33.56,47.4,33.76,47.6,34,47.79Z" style="fill:#ff6164"></path><path id="Outline-2" data-name="Outline" d="M34.16,47a5.36,5.36,0,0,1,4.19-2.08,6,6,0,0,1,4,1.69c.23-.25.45-.51.66-.77a7,7,0,0,0-4.71-1.93,6.36,6.36,0,0,0-4.89,2.36A9.53,9.53,0,0,0,34.16,47Z"></path></g><path id="Outline-3" data-name="Outline" d="M38.09,50.19a7.42,7.42,0,0,1-4.45-2,9.52,9.52,0,0,1-3.11-5.05,1.2,1.2,0,0,1,.26-1,1.41,1.41,0,0,1,1.13-.51H44.26a1.44,1.44,0,0,1,1.13.51,1.19,1.19,0,0,1,.25,1h0a9.52,9.52,0,0,1-3.11,5.05A7.42,7.42,0,0,1,38.09,50.19Zm-6.17-7.4c-.16,0-.2.07-.21.09a8.29,8.29,0,0,0,2.73,4.37A6.23,6.23,0,0,0,38.09,49a6.28,6.28,0,0,0,3.65-1.73,8.3,8.3,0,0,0,2.72-4.37.21.21,0,0,0-.2-.09Z"></path></g><g id="Face"><ellipse id="Right_Blush" data-name="Right Blush" cx="53.22" cy="40.18" rx="5.85" ry="3.44" style="fill:#febbd0"></ellipse><ellipse id="Left_Bluch" data-name="Left Bluch" cx="22.95" cy="40.18" rx="5.85" ry="3.44" style="fill:#febbd0"></ellipse><path id="Eyes" d="M25.7,38.8a5.51,5.51,0,1,0-5.5-5.51A5.51,5.51,0,0,0,25.7,38.8Zm24.77,0A5.51,5.51,0,1,0,45,33.29,5.5,5.5,0,0,0,50.47,38.8Z" style="fill-rule:evenodd"></path><path id="Iris" d="M24,33.64a2.07,2.07,0,1,0-2.06-2.07A2.07,2.07,0,0,0,24,33.64Zm24.77,0a2.07,2.07,0,1,0-2.06-2.07A2.07,2.07,0,0,0,48.75,33.64Z" style="fill:#fff;fill-rule:evenodd"></path></g></svg><span style="margin-left:6px;margin-bottom:2px">bun</span></div></div><div class="rp-tabs__label__item rp-tabs__label__item--not-selected" data-index="4"><div style="display:flex;align-items:center;font-size:15px"><svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><path fill="currentColor" d="M1.105 18.02A11.9 11.9 0 0 1 0 12.985q0-.698.078-1.376a12 12 0 0 1 .231-1.34A12 12 0 0 1 4.025 4.02a12 12 0 0 1 5.46-2.771a12 12 0 0 1 3.428-.23c1.452.112 2.825.477 4.077 1.05a12 12 0 0 1 2.78 1.774a12.02 12.02 0 0 1 4.053 7.078A12 12 0 0 1 24 12.985q0 .454-.036.914a12 12 0 0 1-.728 3.305a12 12 0 0 1-2.38 3.875c-1.33 1.357-3.02 1.962-4.43 1.936a4.4 4.4 0 0 1-2.724-1.024c-.99-.853-1.391-1.83-1.53-2.919a5 5 0 0 1 .128-1.518c.105-.38.37-1.116.76-1.437c-.455-.197-1.04-.624-1.226-.829c-.045-.05-.04-.13 0-.183a.155.155 0 0 1 .177-.053c.392.134.869.267 1.372.35c.66.111 1.484.25 2.317.292c2.03.1 4.153-.813 4.812-2.627s.403-3.609-1.96-4.685s-3.454-2.356-5.363-3.128c-1.247-.505-2.636-.205-4.06.582c-3.838 2.121-7.277 8.822-5.69 15.032a.191.191 0 0 1-.315.19a12 12 0 0 1-1.25-1.634a12 12 0 0 1-.769-1.404M11.57 6.087c.649-.051 1.214.501 1.31 1.236c.13.979-.228 1.99-1.41 2.013c-1.01.02-1.315-.997-1.248-1.614c.066-.616.574-1.575 1.35-1.635"></path></svg><span style="margin-left:6px;margin-bottom:2px">deno</span></div></div></div><div class="rp-tabs__content"><div class="rp-tabs__content__item rp-tabs__content__item--active" aria-hidden="false" data-index="0"><div class="rp-codeblock language-bash"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" data-lang="bash"><code style="white-space:pre"><span class="line"><span style="color:var(--shiki-token-function)">npm</span><span style="color:var(--shiki-token-string)"> install @swc/helpers</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div></div><div class="rp-tabs__content__item rp-tabs__content__item--hidden" aria-hidden="true" data-index="1"><div class="rp-codeblock language-bash"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" data-lang="bash"><code style="white-space:pre"><span class="line"><span style="color:var(--shiki-token-function)">yarn</span><span style="color:var(--shiki-token-string)"> add @swc/helpers</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div></div><div class="rp-tabs__content__item rp-tabs__content__item--hidden" aria-hidden="true" data-index="2"><div class="rp-codeblock language-bash"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" data-lang="bash"><code style="white-space:pre"><span class="line"><span style="color:var(--shiki-token-function)">pnpm</span><span style="color:var(--shiki-token-string)"> add @swc/helpers</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div></div><div class="rp-tabs__content__item rp-tabs__content__item--hidden" aria-hidden="true" data-index="3"><div class="rp-codeblock language-bash"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" data-lang="bash"><code style="white-space:pre"><span class="line"><span style="color:var(--shiki-token-function)">bun</span><span style="color:var(--shiki-token-string)"> add @swc/helpers</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div></div><div class="rp-tabs__content__item rp-tabs__content__item--hidden" aria-hidden="true" data-index="4"><div class="rp-codeblock language-bash"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" data-lang="bash"><code style="white-space:pre"><span class="line"><span style="color:var(--shiki-token-function)">deno</span><span style="color:var(--shiki-token-string)"> add npm:@swc/helpers</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div></div></div></div>
<p>如果你正在使用 <code>@rspack/plugin-react-refresh</code>，现在你需要将 <code>react-refresh</code> 安装为项目的 devDependencies。</p>
<div class="rp-tabs"><div class="rp-tabs__label rp-tabs__label--no-scrollbar" style="justify-content:flex-start"><div class="rp-tabs__label__item rp-tabs__label__item--selected" data-index="0"><div style="display:flex;align-items:center;font-size:15px"><svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 256 256"><path fill="#C12127" d="M0 256V0h256v256z"></path><path fill="#FFF" d="M48 48h160v160h-32V80h-48v128H48z"></path></svg><span style="margin-left:6px;margin-bottom:2px">npm</span></div></div><div class="rp-tabs__label__item rp-tabs__label__item--not-selected" data-index="1"><div style="display:flex;align-items:center;font-size:15px"><svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 128 128"><g fill="#2c8ebb"><path d="M99.24 80.71C94.9 80.76 91.1 83 87.89 85c-6 3.71-9 3.47-9 3.47l-.1-.17c-.41-.67 1.92-6.68-.69-13.84c-2.82-7.83-7.3-9.72-6.94-10.32c1.53-2.59 5.36-6.7 6.89-14.36c.91-4.64.67-12.28-1.39-16.28c-.38-.74-3.78 1.24-3.78 1.24s-3.18-7.09-4.07-7.66c-2.87-1.84-6 7.61-6 7.61a14 14 0 0 0-11.71 4.5a9.64 9.64 0 0 1-3.85 2.27c-.41.14-.91.12-2.15 3.47c-1.9 5.07 3.24 10.81 3.24 10.81s-6.13 4.33-8.4 9.72a24.78 24.78 0 0 0-1.75 11.68s-4.36 3.78-4.64 7.68a12.87 12.87 0 0 0 1.77 7.83a1.94 1.94 0 0 0 2.63.91s-2.9 3.38-.19 4.81c2.47 1.29 6.63 2 8.83-.19c1.6-1.6 1.92-5.17 2.51-6.63c.14-.34.62.57 1.08 1a10 10 0 0 0 1.36 1s-3.9 1.68-2.3 5.51c.53 1.27 2.42 2.08 5.51 2.06c1.15 0 13.76-.72 17.12-1.53a4.33 4.33 0 0 0 2.61-1.46a63 63 0 0 0 15.49-7c4.74-3.09 6.68-3.93 10.51-4.84c3.16-.75 2.95-5.65-1.24-5.58z"></path><path d="M64 2a62 62 0 1 0 62 62A62 62 0 0 0 64 2zm37.3 87.83c-3.35.81-4.91 1.44-9.41 4.36a67 67 0 0 1-15.56 7.18a8.71 8.71 0 0 1-3.64 1.77c-3.81.93-16.88 1.63-17.91 1.63h-.24c-4 0-6.27-1.24-7.49-2.54c-3.4 1.7-7.8 1-11-.69a5.55 5.55 0 0 1-3-3.9a6 6 0 0 1 0-2.06a6.66 6.66 0 0 1-.79-1A16.38 16.38 0 0 1 30 84.52c.29-3.73 2.87-7.06 4.55-8.83A28.56 28.56 0 0 1 36.61 64a26.82 26.82 0 0 1 6.82-9c-1.65-2.78-3.33-7.06-1.7-11.42c1.17-3.11 2.13-4.84 4.24-5.58a6.84 6.84 0 0 0 2.51-1.34A17.65 17.65 0 0 1 60.34 31c.19-.48.41-1 .65-1.46c1.6-3.4 3.3-5.31 5.29-6a4.88 4.88 0 0 1 4.4.5c.65.43 1.48 1 3.9 6a4.69 4.69 0 0 1 2.85-.1a3.81 3.81 0 0 1 2.39 1.94c2.47 4.74 2.8 13.19 1.72 18.62a33.8 33.8 0 0 1-5.84 13.31a25.73 25.73 0 0 1 5.77 9.43a25.42 25.42 0 0 1 1.41 10.41A28.7 28.7 0 0 0 86 81.91c3.06-1.89 7.68-4.74 13.19-4.81a6.62 6.62 0 0 1 7 5.7a6.35 6.35 0 0 1-4.89 7.03z"></path></g></svg><span style="margin-left:6px;margin-bottom:2px">yarn</span></div></div><div class="rp-tabs__label__item rp-tabs__label__item--not-selected" data-index="2"><div style="display:flex;align-items:center;font-size:15px"><svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 128 128"><path fill="#f8ab00" d="M0 .004V40h39.996V.004Zm43.996 0V40h40V.004Zm44.008 0V40H128V.004Zm0 43.996v39.996H128V44Z"></path><path fill="#4c4c4c" d="M43.996 44v39.996h40V44ZM0 87.996v40h39.996v-40Zm43.996 0v40h40v-40Zm44.008 0v40H128v-40Z"></path></svg><span style="margin-left:6px;margin-bottom:2px">pnpm</span></div></div><div class="rp-tabs__label__item rp-tabs__label__item--not-selected" data-index="3"><div style="display:flex;align-items:center;font-size:15px"><svg id="Bun" width="1.2em" height="1.2em" viewBox="0 0 80 70"><path id="Shadow" d="M71.09,20.74c-.16-.17-.33-.34-.5-.5s-.33-.34-.5-.5-.33-.34-.5-.5-.33-.34-.5-.5-.33-.34-.5-.5-.33-.34-.5-.5-.33-.34-.5-.5A26.46,26.46,0,0,1,75.5,35.7c0,16.57-16.82,30.05-37.5,30.05-11.58,0-21.94-4.23-28.83-10.86l.5.5.5.5.5.5.5.5.5.5.5.5.5.5C19.55,65.3,30.14,69.75,42,69.75c20.68,0,37.5-13.48,37.5-30C79.5,32.69,76.46,26,71.09,20.74Z"></path><g id="Body"><path id="Background" d="M73,35.7c0,15.21-15.67,27.54-35,27.54S3,50.91,3,35.7C3,26.27,9,17.94,18.22,13S33.18,3,38,3s8.94,4.13,19.78,10C67,17.94,73,26.27,73,35.7Z" style="fill:#fbf0df"></path><path id="Bottom_Shadow" data-name="Bottom Shadow" d="M73,35.7a21.67,21.67,0,0,0-.8-5.78c-2.73,33.3-43.35,34.9-59.32,24.94A40,40,0,0,0,38,63.24C57.3,63.24,73,50.89,73,35.7Z" style="fill:#f6dece"></path><path id="Light_Shine" data-name="Light Shine" d="M24.53,11.17C29,8.49,34.94,3.46,40.78,3.45A9.29,9.29,0,0,0,38,3c-2.42,0-5,1.25-8.25,3.13-1.13.66-2.3,1.39-3.54,2.15-2.33,1.44-5,3.07-8,4.7C8.69,18.13,3,26.62,3,35.7c0,.4,0,.8,0,1.19C9.06,15.48,20.07,13.85,24.53,11.17Z" style="fill:#fffefc"></path><path id="Top" d="M35.12,5.53A16.41,16.41,0,0,1,29.49,18c-.28.25-.06.73.3.59,3.37-1.31,7.92-5.23,6-13.14C35.71,5,35.12,5.12,35.12,5.53Zm2.27,0A16.24,16.24,0,0,1,39,19c-.12.35.31.65.55.36C41.74,16.56,43.65,11,37.93,5,37.64,4.74,37.19,5.14,37.39,5.49Zm2.76-.17A16.42,16.42,0,0,1,47,17.12a.33.33,0,0,0,.65.11c.92-3.49.4-9.44-7.17-12.53C40.08,4.54,39.82,5.08,40.15,5.32ZM21.69,15.76a16.94,16.94,0,0,0,10.47-9c.18-.36.75-.22.66.18-1.73,8-7.52,9.67-11.12,9.45C21.32,16.4,21.33,15.87,21.69,15.76Z" style="fill:#ccbea7;fill-rule:evenodd"></path><path id="Outline" d="M38,65.75C17.32,65.75.5,52.27.5,35.7c0-10,6.18-19.33,16.53-24.92,3-1.6,5.57-3.21,7.86-4.62,1.26-.78,2.45-1.51,3.6-2.19C32,1.89,35,.5,38,.5s5.62,1.2,8.9,3.14c1,.57,2,1.19,3.07,1.87,2.49,1.54,5.3,3.28,9,5.27C69.32,16.37,75.5,25.69,75.5,35.7,75.5,52.27,58.68,65.75,38,65.75ZM38,3c-2.42,0-5,1.25-8.25,3.13-1.13.66-2.3,1.39-3.54,2.15-2.33,1.44-5,3.07-8,4.7C8.69,18.13,3,26.62,3,35.7,3,50.89,18.7,63.25,38,63.25S73,50.89,73,35.7C73,26.62,67.31,18.13,57.78,13,54,11,51.05,9.12,48.66,7.64c-1.09-.67-2.09-1.29-3-1.84C42.63,4,40.42,3,38,3Z"></path></g><g id="Mouth"><g id="Background-2" data-name="Background"><path d="M45.05,43a8.93,8.93,0,0,1-2.92,4.71,6.81,6.81,0,0,1-4,1.88A6.84,6.84,0,0,1,34,47.71,8.93,8.93,0,0,1,31.12,43a.72.72,0,0,1,.8-.81H44.26A.72.72,0,0,1,45.05,43Z" style="fill:#b71422"></path></g><g id="Tongue"><path id="Background-3" data-name="Background" d="M34,47.79a6.91,6.91,0,0,0,4.12,1.9,6.91,6.91,0,0,0,4.11-1.9,10.63,10.63,0,0,0,1-1.07,6.83,6.83,0,0,0-4.9-2.31,6.15,6.15,0,0,0-5,2.78C33.56,47.4,33.76,47.6,34,47.79Z" style="fill:#ff6164"></path><path id="Outline-2" data-name="Outline" d="M34.16,47a5.36,5.36,0,0,1,4.19-2.08,6,6,0,0,1,4,1.69c.23-.25.45-.51.66-.77a7,7,0,0,0-4.71-1.93,6.36,6.36,0,0,0-4.89,2.36A9.53,9.53,0,0,0,34.16,47Z"></path></g><path id="Outline-3" data-name="Outline" d="M38.09,50.19a7.42,7.42,0,0,1-4.45-2,9.52,9.52,0,0,1-3.11-5.05,1.2,1.2,0,0,1,.26-1,1.41,1.41,0,0,1,1.13-.51H44.26a1.44,1.44,0,0,1,1.13.51,1.19,1.19,0,0,1,.25,1h0a9.52,9.52,0,0,1-3.11,5.05A7.42,7.42,0,0,1,38.09,50.19Zm-6.17-7.4c-.16,0-.2.07-.21.09a8.29,8.29,0,0,0,2.73,4.37A6.23,6.23,0,0,0,38.09,49a6.28,6.28,0,0,0,3.65-1.73,8.3,8.3,0,0,0,2.72-4.37.21.21,0,0,0-.2-.09Z"></path></g><g id="Face"><ellipse id="Right_Blush" data-name="Right Blush" cx="53.22" cy="40.18" rx="5.85" ry="3.44" style="fill:#febbd0"></ellipse><ellipse id="Left_Bluch" data-name="Left Bluch" cx="22.95" cy="40.18" rx="5.85" ry="3.44" style="fill:#febbd0"></ellipse><path id="Eyes" d="M25.7,38.8a5.51,5.51,0,1,0-5.5-5.51A5.51,5.51,0,0,0,25.7,38.8Zm24.77,0A5.51,5.51,0,1,0,45,33.29,5.5,5.5,0,0,0,50.47,38.8Z" style="fill-rule:evenodd"></path><path id="Iris" d="M24,33.64a2.07,2.07,0,1,0-2.06-2.07A2.07,2.07,0,0,0,24,33.64Zm24.77,0a2.07,2.07,0,1,0-2.06-2.07A2.07,2.07,0,0,0,48.75,33.64Z" style="fill:#fff;fill-rule:evenodd"></path></g></svg><span style="margin-left:6px;margin-bottom:2px">bun</span></div></div><div class="rp-tabs__label__item rp-tabs__label__item--not-selected" data-index="4"><div style="display:flex;align-items:center;font-size:15px"><svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><path fill="currentColor" d="M1.105 18.02A11.9 11.9 0 0 1 0 12.985q0-.698.078-1.376a12 12 0 0 1 .231-1.34A12 12 0 0 1 4.025 4.02a12 12 0 0 1 5.46-2.771a12 12 0 0 1 3.428-.23c1.452.112 2.825.477 4.077 1.05a12 12 0 0 1 2.78 1.774a12.02 12.02 0 0 1 4.053 7.078A12 12 0 0 1 24 12.985q0 .454-.036.914a12 12 0 0 1-.728 3.305a12 12 0 0 1-2.38 3.875c-1.33 1.357-3.02 1.962-4.43 1.936a4.4 4.4 0 0 1-2.724-1.024c-.99-.853-1.391-1.83-1.53-2.919a5 5 0 0 1 .128-1.518c.105-.38.37-1.116.76-1.437c-.455-.197-1.04-.624-1.226-.829c-.045-.05-.04-.13 0-.183a.155.155 0 0 1 .177-.053c.392.134.869.267 1.372.35c.66.111 1.484.25 2.317.292c2.03.1 4.153-.813 4.812-2.627s.403-3.609-1.96-4.685s-3.454-2.356-5.363-3.128c-1.247-.505-2.636-.205-4.06.582c-3.838 2.121-7.277 8.822-5.69 15.032a.191.191 0 0 1-.315.19a12 12 0 0 1-1.25-1.634a12 12 0 0 1-.769-1.404M11.57 6.087c.649-.051 1.214.501 1.31 1.236c.13.979-.228 1.99-1.41 2.013c-1.01.02-1.315-.997-1.248-1.614c.066-.616.574-1.575 1.35-1.635"></path></svg><span style="margin-left:6px;margin-bottom:2px">deno</span></div></div></div><div class="rp-tabs__content"><div class="rp-tabs__content__item rp-tabs__content__item--active" aria-hidden="false" data-index="0"><div class="rp-codeblock language-bash"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" data-lang="bash"><code style="white-space:pre"><span class="line"><span style="color:var(--shiki-token-function)">npm</span><span style="color:var(--shiki-token-string)"> install react-refresh</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div></div><div class="rp-tabs__content__item rp-tabs__content__item--hidden" aria-hidden="true" data-index="1"><div class="rp-codeblock language-bash"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" data-lang="bash"><code style="white-space:pre"><span class="line"><span style="color:var(--shiki-token-function)">yarn</span><span style="color:var(--shiki-token-string)"> add react-refresh</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div></div><div class="rp-tabs__content__item rp-tabs__content__item--hidden" aria-hidden="true" data-index="2"><div class="rp-codeblock language-bash"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" data-lang="bash"><code style="white-space:pre"><span class="line"><span style="color:var(--shiki-token-function)">pnpm</span><span style="color:var(--shiki-token-string)"> add react-refresh</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div></div><div class="rp-tabs__content__item rp-tabs__content__item--hidden" aria-hidden="true" data-index="3"><div class="rp-codeblock language-bash"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" data-lang="bash"><code style="white-space:pre"><span class="line"><span style="color:var(--shiki-token-function)">bun</span><span style="color:var(--shiki-token-string)"> add react-refresh</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div></div><div class="rp-tabs__content__item rp-tabs__content__item--hidden" aria-hidden="true" data-index="4"><div class="rp-codeblock language-bash"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" data-lang="bash"><code style="white-space:pre"><span class="line"><span style="color:var(--shiki-token-function)">deno</span><span style="color:var(--shiki-token-string)"> add npm:react-refresh</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div></div></div></div>
<h3 class="rp-toc-include" id="调用-rspackhotmodulereplacementplugin"><a href="#调用-rspackhotmodulereplacementplugin" class="rp-header-anchor rp-link" aria-hidden="true">#</a>调用 rspack.HotModuleReplacementPlugin</h3>
<p>如果你正在使用 <code>@rspack/cli</code>、Rsbuild 或其他 Rspack 的上层框架来开发应用程序，你不需要担心这个问题。这应该由上层框架或 cli 处理好。但是，如果你正在使用 <code>@rspack/core</code> 与自定义开发服务器（不是 <code>@rspack/dev-server</code> 或 <code>webpack-dev-server</code>），或者正在开发自定义开发服务器，则需要注意这一点。</p>
<p>之前，在 Rspack 中启用 HMR 需要将 <code>devServer.hot</code> 设置为 <code>true</code>，但现在你需要在自定义开发服务器中自己调用 <code>HotModuleReplacementPlugin</code>。</p>
<div class="rp-codeblock language-diff"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="diff"><code><span class="line"><span style="color:var(--shiki-foreground)">class CustomDevServer {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  enableHMR(compiler) {</span></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">-   compiler.options.devServer ??= {};</span></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">-   compiler.options.devServer.hot = true;</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+   new compiler.rspack.HotModuleReplacementPlugin().apply(compiler);</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">}</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h3 class="rp-toc-include" id="不要在-rspackoptions-调用之后修改入口配置"><a href="#不要在-rspackoptions-调用之后修改入口配置" class="rp-header-anchor rp-link" aria-hidden="true">#</a>不要在 rspack(options) 调用之后修改入口配置</h3>
<p>如果你正在使用 <code>@rspack/cli</code>、Rsbuild 或其他 Rspack 的上层框架来开发应用程序，你不需要担心这个问题。这应该由上层框架或 cli 处理好。但是如果你正在开发 Rspack 插件或上层框架，你需要注意这一点。</p>
<p>之前，在 Rspack 中添加额外的入口，需要将其添加到 <code>compiler.options.entry</code> 中，但现在需要调用 <code>EntryPlugin</code>。</p>
<div class="rp-codeblock language-diff"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="diff"><code><span class="line"><span style="color:var(--shiki-foreground)">const { rspack } = require(&#x27;@rspack/core&#x27;);</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">const compiler = rspack(options);</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-foreground)">function prependEntry(compiler, additionalEntry) {</span></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">-  for (const key in compiler.options.entry) {</span></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">-    compiler.options.entry[key].import = [</span></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">-      additionalEntry,</span></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">-      ...(compiler.options.entry[key].import || []),</span></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">-    ];</span></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">-  }</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+  new compiler.rspack.EntryPlugin(compiler.context, additionalEntry, {</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+    name: undefined, // `name: undefined` to prepend the it to every entry, or add it to a specified entry with specified entry name</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+  }).apply(compiler);</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-foreground)">prependEntry(compiler, &#x27;dev-client.js&#x27;);</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div><!--/$-->]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Rspack 支持模块联邦]]></title>
            <link>https://rspack.rs/zh/blog/module-federation-added-to-rspack</link>
            <guid isPermaLink="false">/zh/blog/module-federation-added-to-rspack</guid>
            <pubDate>Tue, 09 Jan 2024 13:21:00 GMT</pubDate>
            <description><![CDATA[最新的 Rspack 0.5.0 引入了备受期待的模块联邦功能，本文对其进行了详细介绍。]]></description>
            <content:encoded><![CDATA[<!--$--><h1 class="rp-toc-include" id="rspack-支持模块联邦"><a href="#rspack-支持模块联邦" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rspack 支持模块联邦<!-- --> </h1><div class="rp-not-doc rp-llms-container"><button class="rp-not-doc rp-llms-button rp-llms-copy-button"><div class="rp-llms-copy-button__icon-wrapper"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-llms-copy-button__icon-success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-llms-copy-button__icon-copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg></div><span>复制 Markdown</span></button><button class="rp-llms-button rp-llms-view-options__trigger "><svg width="1em" height="1em" viewBox="0 0 32 32" class="rp-llms-view-options__arrow "><path fill="currentColor" d="M16 22 6 12l1.4-1.4 8.6 8.6 8.6-8.6L26 12z"></path></svg></button></div>
<blockquote>
<p>2024 年 1 月 9 日</p>
</blockquote>
<h2 class="rp-toc-include" id="介绍-rspack-050"><a href="#介绍-rspack-050" class="rp-header-anchor rp-link" aria-hidden="true">#</a>介绍 Rspack 0.5.0</h2>
<p>最新的 Rspack 0.5.0 引入了备受期待的模块联邦功能，以及新的 “v1.5” 模块联邦 API。这是模块联邦创建以来最重大的改进。v1.5 为用户和框架作者提供了额外的功能，这是原始设计所无法实现的。</p>
<div><img src="https://assets.rspack.rs/rspack/assets/rspack-federation-with-rspack.png" width="50%" height="50%" alt="Rspack 和无限手套"/></div>
<h2 class="rp-toc-include" id="给-webpack-模块联邦一些爱"><a href="#给-webpack-模块联邦一些爱" class="rp-header-anchor rp-link" aria-hidden="true">#</a>给 webpack 模块联邦一些爱！</h2>
<p>模块联邦 API 已经向用户开放，以丰富、扩展或管理模块联邦的生命周期。虽然 v1.5 具有几个新功能，但它不会对原始模块联邦 API 引入破坏性更改。</p>
<p>v1.5 可通过 <a href="https://www.npmjs.com/package/@module-federation/enhanced" target="_blank" rel="noopener noreferrer" class="rp-link">@module-federation/enhanced</a> 与上游插件生态系统（如 next.js 模块联邦或 node.js 模块联邦）一起使用，你已经可以在它们的 canary 版本中使用模块联邦 v1.5。</p>
<p>在 Rspack 中，可通过 <code>rspack.container.ModuleFederationPlugin</code> 使用模块联邦 v1.5，也可通过 <code>rspack.container.ModuleFederationPluginV1</code> 使用原始模块联邦。</p>
<h2 class="rp-toc-include" id="迁移机会"><a href="#迁移机会" class="rp-header-anchor rp-link" aria-hidden="true">#</a>迁移机会</h2>
<p>Rspack 中的模块联邦为加速打包工具的代码共享提供了多种创意的迁移方式。webpack 和 Rspack 都可以共享代码，依赖于模块联邦在 v1.5 中引入的相同的集中式运行时。这确保了维护功能平衡的可管理性，并且不需要额外 fork 模块联邦来自定义它。</p>
<p><strong>渐进式迁移</strong>到 Rspack 可以通过模块联邦来实现。如果你有锁定在 webpack 的插件或无法完全切换到 Rspack，通过模块联邦，你可以允许 Rspack 和 webpack 共享依赖和代码，这意味着更多的代码可以通过 Rspack 构建，而使用 webpack 的 Host 则做更少的工作，但仍然获得相同的结果。<a href="https://github.com/module-federation/module-federation-examples/pull/3490" target="_blank" rel="noopener noreferrer" class="rp-link">示例：webpack 和 Rspack 交互</a></p>
<p><strong>通过模块联邦共享 node_modules 加速构建速度</strong>。可以告诉 webpack 将共享依赖设置为 <code>import: false</code>，然后 Rspack 可以编译所有共享模块，减少解析开销和 webpack 构建部分需要执行的代码量，通过将其委托给 Rspack，使共享模块的编译只需要几毫秒即可完成。<a href="https://github.com/module-federation/module-federation-examples/pull/3491" target="_blank" rel="noopener noreferrer" class="rp-link">示例：将 Rspack 打包的 Vendor 提供给 webpack 应用</a></p>
<p><strong>一次性进行迁移</strong>。由于 webpack 模块联邦（<a href="https://www.npmjs.com/package/@module-federation/enhanced" target="_blank" rel="noopener noreferrer" class="rp-link">@module-federation/enhanced</a>）和 Rspack 模块联邦之间的接口是一致的，因此用户可以切换到任何现有的模块联邦的构建到 Rspack。我们建议使用 <code>@module-federation/enhanced</code> 来构建遗留的 webpack 应用，该插件利用我们的新设计并导出的 ModuleFederationPlugin。但是，你仍然可以使用 webpack 中提供的原始的模块联邦插件。Rspack 能够与现有的模块联邦应用进行无缝衔接。</p>
<h2 class="rp-toc-include" id="与-webpack-模块联邦的性能比较"><a href="#与-webpack-模块联邦的性能比较" class="rp-header-anchor rp-link" aria-hidden="true">#</a>与 webpack 模块联邦的性能比较</h2>
<p>在一个简单的比较中，使用<a href="https://github.com/module-federation/module-federation-examples/tree/master/comprehensive-demo-react16" target="_blank" rel="noopener noreferrer" class="rp-link">该模块联邦示例</a>。</p>
<ul>
<li>应用：5</li>
<li>Webpack：500-3000ms 生产环境构建</li>
<li>Rspack：130-350ms 生产环境构建</li>
</ul>
<p>通常情况下，我们观察到模块联邦应用的构建速度提高了 5-10 倍，大致与 Rspack 的典型性能提升相一致。在模块联邦示例中，大多数构建都能得到这样的提升。我们迁移后的开发模式构建通常需要不到 150 毫秒的冷启动时间。</p>
<h2 class="rp-toc-include" id="rsbuild-支持"><a href="#rsbuild-支持" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rsbuild 支持</h2>
<p>Rsbuild 提供简化的构建配置方法。它使得使用 Rspack 感觉不像处理基于 webpack 的构建系统。虽然它与模块联邦兼容，但 Rsbuild 将会提供更流畅的模块联邦体验。例如，Rsbuild 插件可以自动共享 react 的默认值，或者 Rsbuild 可以提供方便的预设和常见的模式。</p>
<p>我们已经开始将一些<a href="https://github.com/module-federation/module-federation-examples" target="_blank" rel="noopener noreferrer" class="rp-link">模块联邦示例</a>迁移到 Rspack 和 Rsbuild。其中一个值得注意的例子是 CRA 迁移，这是无缝的，只需几分钟即可<a href="https://github.com/module-federation/module-federation-examples/tree/master/cra" target="_blank" rel="noopener noreferrer" class="rp-link">从 CRA 切换到 Rsbuild</a>。这个指南对于 CRA 用户寻求易于使用的性能提升也非常有益：<a href="/zh/guide/migration/cra" class="rp-link">Rsbuild 迁移指南</a>。将 Rsbuild 作为 <a href="https://rsbuild.rs/guide/migration/vue-cli" target="_blank" rel="noopener noreferrer" class="rp-link">Vue 项目从 vue-cli 迁移</a>到更快、更易用和更适合模块联邦的东西也非常合适。</p>
<h2 class="rp-toc-include" id="模块联邦-v1-和-v15-之间的区别"><a href="#模块联邦-v1-和-v15-之间的区别" class="rp-header-anchor rp-link" aria-hidden="true">#</a>模块联邦 v1 和 v1.5 之间的区别</h2>
<p>原始的模块联邦很简单。远程模块的入口暴露了 <code>{get, init}</code> 接口，仅此而已。这种方式比较受限，但也很简单。随着复杂的使用场景的增多和更多的功能和需求被发现，我们意识到需要更多的控制，超出了仅仅在构建之间共享代码并进行加载的初始想法。</p>
<p>v1.5 引入了运行时插件。这些插件可以通过 <code>runtimePlugins</code> 配置在编译时添加。但你也可以在运行时的 javascript 文件中动态地注册它们。</p>
<p>在 Rspack 中：</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { rspack } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;@rspack/core&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { fileURLToPath } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;node:url&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">new</span><span style="color:var(--shiki-token-constant)"> rspack</span><span style="color:var(--shiki-token-function)">.</span><span style="color:var(--shiki-token-constant)">container</span><span style="color:var(--shiki-token-function)">.ModuleFederationPlugin</span><span style="color:var(--shiki-foreground)">({</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  name</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;app1&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  filename</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;static/js/remoteEntry.js&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  exposes</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-token-string-expression)">    &#x27;./Button&#x27;</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;./src/components/button.js&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  runtimePlugins</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span></span>
<span class="line"><span style="color:var(--shiki-token-function)">    fileURLToPath</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-keyword)">new</span><span style="color:var(--shiki-token-function)"> URL</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">&#x27;./my-custom-plugin.js&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-keyword)"> import</span><span style="color:var(--shiki-foreground)">.</span><span style="color:var(--shiki-token-constant)">meta</span><span style="color:var(--shiki-foreground)">.url))</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  ]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  remotes</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    app2</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;app2@http://localhost:3002/static/js/remoteEntry.js&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  shared</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    react</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> { singleton</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> true</span><span style="color:var(--shiki-foreground)"> }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-token-string-expression)">    &#x27;react-dom&#x27;</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> { singleton</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> true</span><span style="color:var(--shiki-foreground)"> }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">});</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>在 webpack 中：</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { ModuleFederationPlugin } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;@module-federation/enhanced&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { fileURLToPath } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;node:url&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">new</span><span style="color:var(--shiki-token-function)"> ModuleFederationPlugin</span><span style="color:var(--shiki-foreground)">({</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  name</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;app1&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  filename</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;static/js/remoteEntry.js&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  exposes</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-token-string-expression)">    &#x27;./Button&#x27;</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;./src/components/button.js&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  runtimePlugins</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span></span>
<span class="line"><span style="color:var(--shiki-token-function)">    fileURLToPath</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-keyword)">new</span><span style="color:var(--shiki-token-function)"> URL</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">&#x27;./my-custom-plugin.js&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-keyword)"> import</span><span style="color:var(--shiki-foreground)">.</span><span style="color:var(--shiki-token-constant)">meta</span><span style="color:var(--shiki-foreground)">.url))</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  ]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  remotes</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    app2</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;app2@http://localhost:3002/static/js/remoteEntry.js&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  shared</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    react</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> { singleton</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> true</span><span style="color:var(--shiki-foreground)"> }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-token-string-expression)">    &#x27;react-dom&#x27;</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> { singleton</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> true</span><span style="color:var(--shiki-foreground)"> }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">});</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>模块联邦也可以以动态的方式使用，不需要任何构建时插件。你可以在此处阅读<a href="https://github.com/module-federation/universe/tree/feat/async-boundary-option/packages/runtime" target="_blank" rel="noopener noreferrer" class="rp-link">更多有关 v1.5 运行时的信息</a>。</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js"><code><span class="line"><span style="color:var(--shiki-token-comment)">// 可以使用运行时 SDK 加载模块，而无需依赖构建插件。</span></span>
<span class="line"><span style="color:var(--shiki-token-comment)">// 当不使用构建插件时，无法自动复用共享模块。</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { init</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> loadRemote } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;@module-federation/runtime-tools&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> customPlugin </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;./runtimePlugin&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-function)">init</span><span style="color:var(--shiki-foreground)">({</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  name</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;app1&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  remotes</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      name</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;runtime_remote1&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      alias</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;app2&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      entry</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;http://localhost:3006/remoteEntry.js&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  ]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  shared</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    react</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      version</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;18.2.0&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      scope</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;default&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-token-function)">      lib</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> () </span><span style="color:var(--shiki-token-keyword)">=&gt;</span><span style="color:var(--shiki-foreground)"> React</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      shareConfig</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        singleton</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> true</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        requiredVersion</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;&gt;17&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-token-string-expression)">    &#x27;react-dom&#x27;</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      version</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;18.2.0&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      scope</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;default&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-token-function)">      lib</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> () </span><span style="color:var(--shiki-token-keyword)">=&gt;</span><span style="color:var(--shiki-foreground)"> ReactDOM</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      shareConfig</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        singleton</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> true</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        requiredVersion</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;&gt;17&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  plugins</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span><span style="color:var(--shiki-token-function)">customPlugin</span><span style="color:var(--shiki-foreground)">()]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">});</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-comment)">// 通过远程模块的名称加载</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">loadRemote </span><span style="color:var(--shiki-token-keyword)">&lt;</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  { add</span><span style="color:var(--shiki-token-punctuation)">:</span><span style="color:var(--shiki-foreground)"> (</span><span style="color:var(--shiki-token-keyword)">...</span><span style="color:var(--shiki-foreground)">args</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-function)"> Array</span><span style="color:var(--shiki-foreground)">&lt;</span><span style="color:var(--shiki-token-constant)">number</span><span style="color:var(--shiki-foreground)">&gt;) </span><span style="color:var(--shiki-token-keyword)">=&gt;</span><span style="color:var(--shiki-foreground)"> number } </span><span style="color:var(--shiki-token-keyword)">&gt;</span></span>
<span class="line"><span style="color:var(--shiki-token-string-expression)">  &#x27;app2/util&#x27;</span><span style="color:var(--shiki-token-function)">.then</span><span style="color:var(--shiki-foreground)">(md </span><span style="color:var(--shiki-token-keyword)">=&gt;</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-token-constant)">    md</span><span style="color:var(--shiki-token-function)">.add</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-constant)">1</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-constant)"> 2</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-constant)"> 3</span><span style="color:var(--shiki-foreground)">);</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  });</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>了解更多有关模块联邦 1.5 更新的信息：<a href="https://github.com/module-federation/universe/discussions/1936" target="_blank" rel="noopener noreferrer" class="rp-link">模块联邦 1.5</a>。</p><!--/$-->]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Rspack 0.4 发布公告]]></title>
            <link>https://rspack.rs/zh/blog/announcing-0-4</link>
            <guid isPermaLink="false">/zh/blog/announcing-0-4</guid>
            <pubDate>Wed, 22 Nov 2023 17:31:00 GMT</pubDate>
            <description><![CDATA[Rspack 0.4 版本发布，移除对一些内置功能的支持。]]></description>
            <content:encoded><![CDATA[<!--$--><p><em>2023 年 11 月 22 日</em></p>
<h1 class="rp-toc-include" id="rspack-04-发布公告"><a href="#rspack-04-发布公告" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rspack 0.4 发布公告<!-- --> </h1><div class="rp-not-doc rp-llms-container"><button class="rp-not-doc rp-llms-button rp-llms-copy-button"><div class="rp-llms-copy-button__icon-wrapper"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-llms-copy-button__icon-success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-llms-copy-button__icon-copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg></div><span>复制 Markdown</span></button><button class="rp-llms-button rp-llms-view-options__trigger "><svg width="1em" height="1em" viewBox="0 0 32 32" class="rp-llms-view-options__arrow "><path fill="currentColor" d="M16 22 6 12l1.4-1.4 8.6 8.6 8.6-8.6L26 12z"></path></svg></button></div>
<h2 class="rp-toc-include" id="主要变动"><a href="#主要变动" class="rp-header-anchor rp-link" aria-hidden="true">#</a>主要变动</h2>
<h3 class="rp-toc-include" id="停止支持-nodejs-14"><a href="#停止支持-nodejs-14" class="rp-header-anchor rp-link" aria-hidden="true">#</a>停止支持 Node.js 14</h3>
<p>Rspack 不再支持 Node.js 14，现在需要 Node.js 16+。</p>
<h3 class="rp-toc-include" id="调整-rspackcore-为-rspackcli-的-peer-dependency"><a href="#调整-rspackcore-为-rspackcli-的-peer-dependency" class="rp-header-anchor rp-link" aria-hidden="true">#</a>调整 @rspack/core 为 @rspack/cli 的 peer dependency</h3>
<p><code>@rspack/core</code> 现在是 <code>@rspack/cli</code> 的 peerDependency，而不是直接的依赖关系。这意味着现在你需要手动安装 <code>@rspack/core</code> 和 <code>@rspack/cli</code>。这使得 Rspack 更加接近 webpack。从长远来看，<code>@rspack/cli</code> 的定位将不再是开箱即用的解决方案。我们建议使用 <a href="https://rsbuild.rs/" target="_blank" rel="noopener noreferrer" class="rp-link">Rsbuild</a> 作为开箱即用的解决方案。</p>
<h3 class="rp-toc-include" id="废弃默认转换"><a href="#废弃默认转换" class="rp-header-anchor rp-link" aria-hidden="true">#</a>废弃默认转换</h3>
<p><code>experiments.rspackFuture.disableTransformByDefault</code> 在 v0.4.0 中默认启用。对于仍需要旧行为的用户，可以手动将此选项设置为 <code>false</code>。</p>
<p>此功能主要解决三类问题：<a href="https://v0.rspack.rs/config/builtins" target="_blank" rel="noopener noreferrer" class="rp-link">内置</a> 代码转换功能，<a href="/zh/config/target" class="rp-link">目标</a>，和自定义 <a href="/zh/config/module-rules#rulestype" class="rp-link">rules[].type</a>。</p>
<ol>
<li>移除对一些 <a href="https://v0.rspack.rs/config/builtins" target="_blank" rel="noopener noreferrer" class="rp-link">内置</a> 功能的支持：</li>
</ol>
<ul>
<li><a href="https://v0.rspack.rs/config/builtins#builtinsrelay" target="_blank" rel="noopener noreferrer" class="rp-link">builtins.relay</a>：移动到 <code>rspackExperiments.relay</code></li>
<li><a href="https://v0.rspack.rs/config/builtins#builtinsreact" target="_blank" rel="noopener noreferrer" class="rp-link">builtins.react</a>：移动到 <code>jsc.transform.react</code></li>
<li><a href="https://v0.rspack.rs/config/builtins#builtinsemotion" target="_blank" rel="noopener noreferrer" class="rp-link">builtins.emotion</a>：移动到 <code>rspackExperiments.emotion</code></li>
<li><a href="https://v0.rspack.rs/config/builtins#builtinspluginimport" target="_blank" rel="noopener noreferrer" class="rp-link">builtins.pluginImport</a>：移动到 <code>rspackExperiments.import</code></li>
<li><a href="https://v0.rspack.rs/config/builtins#builtinsdecorator" target="_blank" rel="noopener noreferrer" class="rp-link">builtins.decorator</a>：移动到 <code>jsc.parser.decorators</code></li>
<li><a href="https://v0.rspack.rs/config/builtins#builtinspresetenv" target="_blank" rel="noopener noreferrer" class="rp-link">builtins.presetEnv</a>：移动到 <code>jsc.env</code></li>
</ul>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  module</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    rules</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        test</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> /.jsx</span><span style="color:var(--shiki-token-keyword)">$</span><span style="color:var(--shiki-token-string-expression)">/</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        loader</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;builtin:swc-loader&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        options</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          jsc</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">            parser</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">              syntax</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;ecmascript&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">              jsx</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> true</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">            }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">            transform</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">              react</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">                runtime</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;automatic&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">              }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">            }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          rspackExperiments</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">            emotion</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> true</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-comment)"> // 与 `builtins` 相同</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        type</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;javascript/auto&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    ]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  experiments</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    rspackFuture</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      disableTransformByDefault</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> true</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<ol start="2">
<li><a href="/zh/config/target" class="rp-link">target</a> 不再降级用户端代码（包含 node_modules）</li>
</ol>
<div class="rp-codeblock language-diff"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="diff" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-foreground)">export default {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  target: [&quot;web&quot;, &quot;es5&quot;],</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  module: {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    rules: [</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        test: /.js$/,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        exclude: /node_modules/,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        loader: &#x27;builtin:swc-loader&#x27;,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        options: {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          jsc: {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">            parser: {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">              syntax: &quot;ecmascript&quot;</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">            },</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+           target: &quot;es5&quot; // 注意：`jsc.target` 和 `env` 不能同时设置。</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          },</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+        env: { // 注意：`jsc.target` 和 `env` 不能同时设置。</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+         targets: &quot;chrome &gt;= 48&quot;</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+        }</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        }</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        type: &#x27;javascript/auto&#x27;,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      },</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    ],</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<ol start="3">
<li>移除非 webpack 兼容的 <a href="/zh/config/module-rules#rulestype" class="rp-link">rules[].type</a></li>
</ol>
<h3 class="rp-toc-include" id="废弃-builtinreactrefresh"><a href="#废弃-builtinreactrefresh" class="rp-header-anchor rp-link" aria-hidden="true">#</a>废弃 builtin.react.refresh</h3>
<p>由于在 v0.4.0 中默认启用了 <code>experiments.rspackFuture.disableTransformByDefault</code>，<code>builtin.react.refresh</code> 也已被废弃。现在我们建议使用 <code>@rspack/plugin-react-refresh</code> 来启用 React Fast Refresh。你需要手动安装 <a href="https://www.npmjs.com/package/@rspack/plugin-react-refresh" target="_blank" rel="noopener noreferrer" class="rp-link">@rspack/plugin-react-refresh</a> 和 <a href="https://www.npmjs.com/package/react-refresh" target="_blank" rel="noopener noreferrer" class="rp-link">react-refresh</a>。</p>
<div class="rp-codeblock language-diff"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="diff" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-inserted)">+ import { ReactRefreshRspackPlugin } from &#x27;@rspack/plugin-react-refresh&#x27;;</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-foreground)">const isDev = process.env.NODE_ENV === &#x27;development&#x27;;</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-foreground)">export default {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  mode: isDev ? &#x27;development&#x27; : &#x27;production&#x27;,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  module: {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    rules: [</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        test: /.jsx$/,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        use: {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          loader: &#x27;builtin:swc-loader&#x27;,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          options: {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">            jsc: {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">              parser: {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">                syntax: &#x27;ecmascript&#x27;,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">                jsx: true,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">              },</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">              transform: {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">                react: {</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+                  development: isDev,</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+                  refresh: isDev,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">                },</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">              },</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">            },</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          },</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        },</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      },</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    ],</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  },</span></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">-  builtins: {</span></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">-    react: {</span></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">-      refresh: true,</span></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">-    }</span></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">-  },</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  plugins: [</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+    isDev &amp;&amp; new ReactRefreshRspackPlugin()</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  ],</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>查看更多详情，请访问 <a href="/zh/guide/tech/react#fast-refresh" class="rp-link">这里</a>。</p>
<h3 class="rp-toc-include" id="废弃-builtinsass-loader"><a href="#废弃-builtinsass-loader" class="rp-header-anchor rp-link" aria-hidden="true">#</a>废弃 builtin:sass-loader</h3>
<p><code>builtin:sass-loader</code> 现已被废弃。如果你正在使用它，请迁移到 <code>sass-loader</code>。Rspack 将在 v0.5.0 中移除 <code>builtin:sass-loader</code>。</p>
<h3 class="rp-toc-include" id="experimentsincrementalrebuild-配置废弃"><a href="#experimentsincrementalrebuild-配置废弃" class="rp-header-anchor rp-link" aria-hidden="true">#</a>experiments.incrementalRebuild 配置废弃</h3>
<p><code>experiments.incrementalRebuild</code> 已内置开启，所以不再需要该配置。Rspack 将在 v0.5.0 中移除该配置。</p>
<h3 class="rp-toc-include" id="重构-rspackcore-中的导出-api"><a href="#重构-rspackcore-中的导出-api" class="rp-header-anchor rp-link" aria-hidden="true">#</a>重构 @rspack/core 中的导出 API</h3>
<p>以前，一些 API 可能会通过从 @rspack/core 重新导出而被意外导出。现在通过此重构，我们从 @rspack/core 中清理了导出的 API。</p>
<p>这不应该造成任何问题，但如果你意外导出了 API，则可能会出现问题，你可能会以不正确的方式使用 Rspack。</p>
<p>如果确实有需要从此重构中移除的 API，请在 Rspack 仓库中提出问题。</p>
<h3 class="rp-toc-include" id="废弃-builtinsdevfriendlysplitchunks-和-experimentsnewsplitchunks"><a href="#废弃-builtinsdevfriendlysplitchunks-和-experimentsnewsplitchunks" class="rp-header-anchor rp-link" aria-hidden="true">#</a>废弃 <code>builtins.devFriendlySplitChunks</code> 和 <code>experiments.newSplitChunks</code></h3>
<p>为了完全迁移到 webpack 的 splitChunks 实现，这些字段已被废弃。Rspack 将在 v0.5.0 中移除这些字段。</p>
<h3 class="rp-toc-include" id="默认启用新的解析器"><a href="#默认启用新的解析器" class="rp-header-anchor rp-link" aria-hidden="true">#</a>默认启用新的解析器</h3>
<p>新版 resolver 现在默认启用。</p>
<p>新解析器已通过了 <a href="https://www.npmjs.com/package/enhanced-resolve" target="_blank" rel="noopener noreferrer" class="rp-link">enhanced-resolve</a> 的所有测试套件。它比以前的实现快 5 倍，比 enhanced-resolve 快 28 倍。</p>
<p>新解析器可以配置为读取 <code>tsconfig.json</code> 的 <code>compilerOptions.paths</code> 和 <code>references</code> 字段,对 monorepo 的嵌套 alias 提供了内置支持。有关详细信息，请参阅 API <a href="/zh/config/resolve#resolvetsconfig" class="rp-link">resolve.tsConfig</a>。</p>
<p>要退出新解析器，请将 <code>experiments.rspackFuture.newResolver</code> 设置为 <code>false</code>。</p>
<h2 class="rp-toc-include" id="migration-guide"><a href="#migration-guide" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Migration guide</h2>
<p>迁移示例 <a href="https://github.com/rstackjs/rstack-examples/pull/2" target="_blank" rel="noopener noreferrer" class="rp-link">migrate example</a> 展示了如何从 Rspack 0.3.14 迁移到 Rspack 0.4.0</p>
<h3 class="rp-toc-include" id="选择-rspackcli-还是-rsbuild"><a href="#选择-rspackcli-还是-rsbuild" class="rp-header-anchor rp-link" aria-hidden="true">#</a>选择 <code>@rspack/cli</code> 还是 <code>Rsbuild</code>？</h3>
<p>如果你的应用程序是 CSR 应用程序，则我们强烈建议你使用 Rsbuild 而不是自行配置 Rspack，因为与 <code>@rspack/cli</code> 相比，Rsbuild 更容易使用。</p>
<h3 class="rp-toc-include" id="升级-nodejs-版本"><a href="#升级-nodejs-版本" class="rp-header-anchor rp-link" aria-hidden="true">#</a>升级 Node.js 版本</h3>
<p>自 0.4.0 起，Rspack 不再支持 Node.js 14，现在仅支持 Node.js 16+。</p>
<h3 class="rp-toc-include" id="需要手动安装-rspackcore"><a href="#需要手动安装-rspackcore" class="rp-header-anchor rp-link" aria-hidden="true">#</a>需要手动安装 <code>@rspack/core</code></h3>
<div class="rp-codeblock language-diff"><div class="rp-codeblock__title">package.json</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="diff" data-title="package.json"><code><span class="line"><span style="color:var(--shiki-foreground)">{</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  &quot;devDependencies&quot;: {</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+    &quot;@rspack/core&quot;: &quot;0.4.0&quot;,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">     &quot;@rspack/cli&quot;: &quot;0.4.0&quot;</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">}</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h3 class="rp-toc-include" id="使用内置的-builtinswc-loader-支持模块转换"><a href="#使用内置的-builtinswc-loader-支持模块转换" class="rp-header-anchor rp-link" aria-hidden="true">#</a>使用内置的 <code>builtin:swc-loader</code> 支持模块转换</h3>
<p>自 0.4.0 起，Rspack 不再默认转换文件，你仍然可以通过如下方式来开启默认转换，</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js"><code><span class="line"><span style="color:var(--shiki-foreground)">{</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  experiments</span><span style="color:var(--shiki-token-punctuation)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    rspackFuture</span><span style="color:var(--shiki-token-punctuation)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      disableTransformByDefault</span><span style="color:var(--shiki-token-punctuation)">:</span><span style="color:var(--shiki-token-constant)"> false</span><span style="color:var(--shiki-foreground)">; </span><span style="color:var(--shiki-token-comment)">// 开启默认转换</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    }</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">}</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>我们建议迁移到 <code>builtin:swc-loader</code> 来进行模块转换，更多详情请参阅 <a href="#%E5%BA%9F%E5%BC%83%E9%BB%98%E8%AE%A4%E8%BD%AC%E6%8D%A2" class="rp-link">Deprecating default transformation</a>。</p>
<h3 class="rp-toc-include" id="对于-react-应用程序请使用-rspackplugin-react-refresh-来支持-fast-refresh"><a href="#对于-react-应用程序请使用-rspackplugin-react-refresh-来支持-fast-refresh" class="rp-header-anchor rp-link" aria-hidden="true">#</a>对于 React 应用程序，请使用 <code>@rspack/plugin-react-refresh</code> 来支持 Fast Refresh</h3>
<p>当我们禁用默认转换时，<code>builtin.react.refresh</code> 将无法工作，因此你需要使用 <code>@rspack/plugin-react-refresh</code> 来启用 Fast Refresh，更多细节请参阅 <a href="#%E5%BA%9F%E5%BC%83-builtinreactrefresh" class="rp-link">Deprecating builtin.react.refresh</a>。</p>
<h3 class="rp-toc-include" id="迁移-builtin-options-到-builtin-plugins"><a href="#迁移-builtin-options-到-builtin-plugins" class="rp-header-anchor rp-link" aria-hidden="true">#</a>迁移 builtin options 到 builtin plugins</h3>
<p>Rspack 在 v0.4.0 中废弃了部分 builtin options 并迁移至 Rspack <a href="/zh/config/plugins" class="rp-link">内部插件</a>。</p>
<p>目前，rspack 的内部插件分为两类：</p>
<ul>
<li>与 webpack 兼容的插件，如 DefinePlugin, ProvidePlugin 等，这部分实现与 webpack 完成了完整的对齐</li>
<li>Rspack 独有的插件，如 SwcJsMinimizerRspackPlugin, CopyRspackPlugin 等</li>
</ul>
<p>原有的 <code>builtins.define</code> 可以这样迁移：</p>
<div class="rp-codeblock language-diff"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="diff" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-inserted)">+ import { rspack } from &#x27;@rspack/core&#x27;;</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-foreground)">export default {</span></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">-  builtins: {</span></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">-    define: { process.env.NODE_ENV: JSON.stringify(process.env.NODE_ENV) }</span></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">-  },</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+  plugins: [</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+    new rspack.DefinePlugin({ process.env.NODE_ENV: JSON.stringify(process.env.NODE_ENV) })</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+  ]</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">}</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>对于 <code>builtins.html</code> 可以直接迁移到 <a href="/zh/plugins/rspack/html-rspack-plugin" class="rp-link">HtmlRspackPlugin</a>：</p>
<div class="rp-codeblock language-diff"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="diff" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-inserted)">+ import { rspack } from &#x27;@rspack/core&#x27;;</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-foreground)">export default {</span></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">-  builtins: {</span></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">-    html: [{ template: &quot;./index.html&quot; }]</span></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">-  },</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+  plugins: [</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+    new rspack.HtmlRspackPlugin({ template: &quot;./index.html&quot; })</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+  ]</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">}</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>当 <code>builtins.html</code> 中存在多个配置，可以创建多个插件实例：</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { rspack } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;@rspack/core&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  plugins</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">    new</span><span style="color:var(--shiki-token-constant)"> rspack</span><span style="color:var(--shiki-token-function)">.HtmlRspackPlugin</span><span style="color:var(--shiki-foreground)">({ template</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;./index.html&#x27;</span><span style="color:var(--shiki-foreground)"> })</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">    new</span><span style="color:var(--shiki-token-constant)"> rspack</span><span style="color:var(--shiki-token-function)">.HtmlRspackPlugin</span><span style="color:var(--shiki-foreground)">({ template</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;./foo.html&#x27;</span><span style="color:var(--shiki-foreground)"> })</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  ]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>对于 <code>builtins.copy</code> 可以直接迁移到 <a href="/zh/plugins/rspack/copy-rspack-plugin" class="rp-link">CopyRspackPlugin</a>。</p>
<p>原先的 <code>builtins.minifyOptions</code> 我们提供了 <a href="/zh/plugins/rspack/swc-js-minimizer-rspack-plugin" class="rp-link">SwcJsMinimizerRspackPlugin</a>：</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { rspack } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;@rspack/core&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  optimization</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    minimizer</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">      new</span><span style="color:var(--shiki-token-constant)"> rspack</span><span style="color:var(--shiki-token-function)">.SwcJsMinimizerRspackPlugin</span><span style="color:var(--shiki-foreground)">({</span></span>
<span class="line"><span style="color:var(--shiki-token-comment)">        // minimizer 配置</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      })</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    ]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>其他内容可以直接参考 Rspack <a href="/zh/config/plugins" class="rp-link">内部插件</a>进行迁移，也可以在升级到 v0.4.0 后根据 CLI 提示完成操作。</p><!--/$-->]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Rspack 0.3 发布公告]]></title>
            <link>https://rspack.rs/zh/blog/announcing-0-3</link>
            <guid isPermaLink="false">/zh/blog/announcing-0-3</guid>
            <pubDate>Thu, 24 Aug 2023 12:15:00 GMT</pubDate>
            <description><![CDATA[Rspack 0.3 版本发布，新增 web workers、builtin:swc-loader 支持。]]></description>
            <content:encoded><![CDATA[<!--$--><p><em>2023 年 8 月 24 日</em></p>
<h1 class="rp-toc-include" id="rspack-03-发布公告"><a href="#rspack-03-发布公告" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rspack 0.3 发布公告<!-- --> </h1><div class="rp-not-doc rp-llms-container"><button class="rp-not-doc rp-llms-button rp-llms-copy-button"><div class="rp-llms-copy-button__icon-wrapper"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-llms-copy-button__icon-success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-llms-copy-button__icon-copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg></div><span>复制 Markdown</span></button><button class="rp-llms-button rp-llms-view-options__trigger "><svg width="1em" height="1em" viewBox="0 0 32 32" class="rp-llms-view-options__arrow "><path fill="currentColor" d="M16 22 6 12l1.4-1.4 8.6 8.6 8.6-8.6L26 12z"></path></svg></button></div>
<h2 class="rp-toc-include" id="破坏性更新"><a href="#破坏性更新" class="rp-header-anchor rp-link" aria-hidden="true">#</a>破坏性更新</h2>
<p>Rspack 在 0.3 版本将 <code>experiments.css = true</code> 的情况下的 CSS 默认处理行为和 webpack 进行了对齐，移除了很多内置的 CSS 转换逻辑,这同时带来了一些 breaking change，如果你的应用之前依赖了这些转换逻辑，请注意按照下述迁移方式进行迁移。</p>
<h3 class="rp-toc-include" id="移除-rspackpostcss-loader-和-builtinspostcss"><a href="#移除-rspackpostcss-loader-和-builtinspostcss" class="rp-header-anchor rp-link" aria-hidden="true">#</a>移除 <code>@rspack/postcss-loader</code> 和 <code>builtins.postcss</code></h3>
<p>在 Rspack 完全支持 <code>postcss-loader</code> 之前，Rspack fork 实现了 <code>@rspack/postcss-loader</code> 和内置实现了 <code>builtins.postcss</code> 以满足功能，目前 Rspack 已经完全支持了 <code>postcss-loader</code>，因此我们决定废弃掉 <code>@rspack/postcss-loader</code> 和 <code>builtins.postcss</code>，使用 <code>@rspack/postcss-loader</code> 的用户可以无缝迁移到 <code>postcss-loader</code> 上，而之前 Rspack 的 <code>builtins.postcss</code> 只实现了 <code>px2rem</code> 的转换功能，使用该功能的用户可以迁移到 <code>postcss-loader</code> 和 <code>postcss-plugin-px2rem</code> 上，如下是迁移方式。</p>
<ul>
<li>before:</li>
</ul>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  builtins</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    postcss</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      pxtorem</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        rootValue</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> 50</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<ul>
<li>after:</li>
</ul>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  module</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    rules</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        test</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> /\.css</span><span style="color:var(--shiki-token-keyword)">$</span><span style="color:var(--shiki-token-string-expression)">/</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        use</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">            loader</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;postcss-loader&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">            options</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">              postcssOptions</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">                plugins</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">                  [</span></span>
<span class="line"><span style="color:var(--shiki-token-string-expression)">                    &#x27;postcss-plugin-px2rem&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">                    {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">                      rootValue</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> 100</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">                    }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">                  ]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">                ]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">              }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">            }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        ]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    ]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h3 class="rp-toc-include" id="移除了内置的-css-autoprefixer-功能"><a href="#移除了内置的-css-autoprefixer-功能" class="rp-header-anchor rp-link" aria-hidden="true">#</a>移除了内置的 CSS autoprefixer 功能</h3>
<p>为了更好的对齐 webpack 的 CSS 处理， Rspack 从 0.3 移除了内置的 autoprefixer 功能，你可以使用 postcss-loader 来实现 autoprefixer。</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  module</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    rules</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        test</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> /\.css</span><span style="color:var(--shiki-token-keyword)">$</span><span style="color:var(--shiki-token-string-expression)">/</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        use</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">            loader</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;postcss-loader&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">            options</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">              postcssOptions</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">                plugins</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [[</span><span style="color:var(--shiki-token-string-expression)">&#x27;autoprefixer&#x27;</span><span style="color:var(--shiki-foreground)">]]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">              }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">            }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        ]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        type</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;css&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    ]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>完整的示例可参考 <a href="https://github.com/rstackjs/rstack-examples/tree/main/rspack/postcss-loader" target="_blank" rel="noopener noreferrer" class="rp-link">examples/postcss-loader</a>。</p>
<h3 class="rp-toc-include" id="限制访问内部模块"><a href="#限制访问内部模块" class="rp-header-anchor rp-link" aria-hidden="true">#</a>限制访问内部模块</h3>
<p>考虑到 Rspack 目前的内部模块的 API 不够稳定，直接使用 Rspack 内部模块的 API 很容易导致 breaking，因此 Rspack 限制了用户直接访问内部模块的能力，仅支持从根模块访问 Rspack 的 API。</p>
<ul>
<li>before</li>
</ul>
<div class="rp-codeblock language-js"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { Stats } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;@rspack/core/dist/stats&#x27;</span><span style="color:var(--shiki-foreground)">; </span><span style="color:var(--shiki-token-comment)">// not supported since 0.3</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<ul>
<li>after</li>
</ul>
<div class="rp-codeblock language-js"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { Stats } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;@rspack/core&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h2 class="rp-toc-include" id="主要功能更新"><a href="#主要功能更新" class="rp-header-anchor rp-link" aria-hidden="true">#</a>主要功能更新</h2>
<h3 class="rp-toc-include" id="web-workers-支持"><a href="#web-workers-支持" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Web Workers 支持</h3>
<p>Rspack 原生支持了 Web Workers，这意味着你不需要使用 <a href="https://github.com/webpack-contrib/worker-loader" target="_blank" rel="noopener noreferrer" class="rp-link">worker-loader</a> 即可开箱即用的使用 Web Workers。使用方式如下：</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js"><code><span class="line"><span style="color:var(--shiki-token-keyword)">new</span><span style="color:var(--shiki-token-function)"> Worker</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-keyword)">new</span><span style="color:var(--shiki-token-function)"> URL</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">&#x27;./worker.js&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-keyword)"> import</span><span style="color:var(--shiki-foreground)">.</span><span style="color:var(--shiki-token-constant)">meta</span><span style="color:var(--shiki-foreground)">.url));</span></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">new</span><span style="color:var(--shiki-token-function)"> Worker</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-keyword)">new</span><span style="color:var(--shiki-token-function)"> URL</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">&#x27;./worker.js&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-keyword)"> import</span><span style="color:var(--shiki-foreground)">.</span><span style="color:var(--shiki-token-constant)">meta</span><span style="color:var(--shiki-foreground)">.url)</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  name</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;my-worker&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">});</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>更多关于 Web Workers 的支持说明见 <a href="/zh/guide/features/web-workers" class="rp-link">Web Workers 文档</a></p>
<h3 class="rp-toc-include" id="builtinswc-loader-支持"><a href="#builtinswc-loader-支持" class="rp-header-anchor rp-link" aria-hidden="true">#</a><code>builtin:swc-loader</code> 支持</h3>
<p>Rspack 虽然提供了很多 SWC 的编译配置选项，但是这些配置都是全局性的编译配置，业务侧如果需要不同的模块走不同的 SWC 转换逻辑则难以满足，因此 Rspack 支持 <code>builtin:swc-loader</code> 以提供更精细的 SWC 转换配置，<code>builtin:swc-loader</code> 相比于 JS 版本的 <a href="https://github.com/swc-project/swc-loader" target="_blank" rel="noopener noreferrer" class="rp-link">swc-loader</a> 性能更优。你可以通过如下方式使用 <code>builtin:swc-loader</code></p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { defineConfig } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;@rspack/cli&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-token-function)"> defineConfig</span><span style="color:var(--shiki-foreground)">({</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  module</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    rules</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        test</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> /\.jsx</span><span style="color:var(--shiki-token-keyword)">$</span><span style="color:var(--shiki-token-string-expression)">/</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        use</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          loader</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;builtin:swc-loader&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          options</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">            jsc</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">              parser</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">                syntax</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;ecmascript&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">                jsx</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> true</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">              }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">              transform</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">                react</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">                  pragma</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;React.createElement&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">                  pragmaFrag</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;React.Fragment&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">                  throwIfNamespace</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> true</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">                  development</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> false</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">                }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">              }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">            }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">          }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        type</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;javascript/auto&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    ]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">});</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>更多的示例可参考 <a href="https://github.com/rstackjs/rstack-examples/tree/main/rspack/builtin-swc-loader" target="_blank" rel="noopener noreferrer" class="rp-link">examples/builtin-swc-loader</a>
目前的 <code>builtin:swc-loader</code> 仍然有诸多限制，如不支持 Wasm plugin 等，Rspack 在后续版本将继续迭代支持 <code>builtin:swc-loader</code> 的更多功能。</p>
<h3 class="rp-toc-include" id="更好的-profile-支持"><a href="#更好的-profile-支持" class="rp-header-anchor rp-link" aria-hidden="true">#</a>更好的 profile 支持</h3>
<p>业务支持中性能调优是一个很常见的需求，为了减小给业务调优性能的成本，我们优化了 Rspack Profile 的体验，你可以通过 RSPACK_PROFILE 环境变量来生成 profile 相关文件来进行性能调优。</p>
<div class="rp-codeblock language-sh"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="sh"><code><span class="line"><span style="color:var(--shiki-token-function)">$</span><span style="color:var(--shiki-token-string)"> RSPACK_PROFILE=ALL</span><span style="color:var(--shiki-token-string)"> rspack</span><span style="color:var(--shiki-token-string)"> build</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>关于 Profile 更详细的说明，见<a href="/zh/guide/optimization/profile" class="rp-link">性能分析</a></p>
<h3 class="rp-toc-include" id="对齐了更多的-api"><a href="#对齐了更多的-api" class="rp-header-anchor rp-link" aria-hidden="true">#</a>对齐了更多的 API</h3>
<ul>
<li><code>splitChunks.chunks</code> 支持正则</li>
<li>支持 <code>splitChunk.\{cacheGroup\}.type</code></li>
<li>支持 <code>splitChunk.\{cacheGroup\}.idHint</code></li>
<li>支持 <code>ensureChunkConditionsPlugin</code></li>
<li><code>rules[].use</code> 支持函数</li>
<li>支持 <code>configuration.profile</code></li>
</ul>
<h3 class="rp-toc-include" id="更多的-hook-和插件支持"><a href="#更多的-hook-和插件支持" class="rp-header-anchor rp-link" aria-hidden="true">#</a>更多的 Hook 和插件支持</h3>
<p>相比 0.2 版本，我们在 0.3 版本中实现了更多的插件 API 和兼容了更多的插件，同时我们对 webpack 的 插件 API 进行了梳理，将 插件 API 的支持进度透明化，你可以在这里<a href="https://github.com/orgs/web-infra-dev/projects/9/views/1" target="_blank" rel="noopener noreferrer" class="rp-link">plugin-api-progress</a> 追踪插件 API 的实现进度。</p>
<h3 class="rp-toc-include" id="和-webpack-架构对齐"><a href="#和-webpack-架构对齐" class="rp-header-anchor rp-link" aria-hidden="true">#</a>和 webpack 架构对齐</h3>
<p>我们在 0.3 版本进一步优化了和 webpack 架构的对齐工作，从原来的基于 AST 的 codegen 架构迁移到基于字符串变换的架构，该对齐工作可以进一步保障 Rspack 在 codegen 阶段能够对齐 webpack 更多的 Hook API 以兼容更多的社区插件。</p>
<h3 class="rp-toc-include" id="rspack-生态"><a href="#rspack-生态" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rspack 生态</h3>
<p>Rspack 在 0.2 版本提供了对 <code>vue-loader</code> 的支持,但是基于 <code>vue-loader</code> 封装一套完整的 Vue.js cli 的解决方案是一个较为复杂工作，<a href="https://rsbuild.rs/" target="_blank" rel="noopener noreferrer" class="rp-link">Rsbuild</a> 提供了 Vue.js 开箱即用的工程化方案来简化使用 Rspack 开发 Vue.js 的工作。</p><!--/$-->]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Rspack 0.2 发布公告]]></title>
            <link>https://rspack.rs/zh/blog/announcing-0-2</link>
            <guid isPermaLink="false">/zh/blog/announcing-0-2</guid>
            <pubDate>Fri, 02 Jun 2023 13:11:00 GMT</pubDate>
            <description><![CDATA[Rspack 0.2 版本发布，新增了诸多功能，如 realContentHash、DataURI、ESM format 的支持等。]]></description>
            <content:encoded><![CDATA[<!--$--><p><em>2023 年 6 月 2 日</em></p>
<h1 class="rp-toc-include" id="rspack-02-发布公告"><a href="#rspack-02-发布公告" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rspack 0.2 发布公告<!-- --> </h1><div class="rp-not-doc rp-llms-container"><button class="rp-not-doc rp-llms-button rp-llms-copy-button"><div class="rp-llms-copy-button__icon-wrapper"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-llms-copy-button__icon-success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-llms-copy-button__icon-copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg></div><span>复制 Markdown</span></button><button class="rp-llms-button rp-llms-view-options__trigger "><svg width="1em" height="1em" viewBox="0 0 32 32" class="rp-llms-view-options__arrow "><path fill="currentColor" d="M16 22 6 12l1.4-1.4 8.6 8.6 8.6-8.6L26 12z"></path></svg></button></div>
<p>自 Rspack 0.1 版本发布的将近三个月以来，我们得到了非常多社区的关注和反馈，感谢大家对 Rspack 的支持。在 0.2 版本中，我们新增了诸多功能，如 realContentHash、DataURI、ESM format 的支持等，同时加强了与 webpack 的兼容性，并优化了诸多细节。</p>
<p>另外，得益于对 webpack API 良好的兼容性，我们对于周边生态也完成了进一步的兼容，例如，测试完成了对 vue-loader 17（对应 Vue 3）和 15（对应 Vue 2）版本的兼容，现在大家可以尝试在 Vue 2 / 3 项目中使用 Rspack 了。我们期待你在 0.2 版本中体验到这些全新的改进，并欢迎你随时给我们提供反馈。</p>
<h2 class="rp-toc-include" id="主要功能更新"><a href="#主要功能更新" class="rp-header-anchor rp-link" aria-hidden="true">#</a>主要功能更新</h2>
<h3 class="rp-toc-include" id="loader"><a href="#loader" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Loader</h3>
<p>0.2 版本完成了 loader 大部分 API 的兼容，其中包括了 inline match resource，pitching loader，inline loader 等。更多的 API 进一步提升了对 webpack loader 的兼容性，详情可以参考下方 webpack 兼容性更新。更多信息请参考 <a href="/zh/api/loader-api/" class="rp-link">Loader API</a></p>
<h3 class="rp-toc-include" id="plugin-hooks"><a href="#plugin-hooks" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Plugin hooks</h3>
<p>新增一些插件的的钩子</p>
<p>Compiler hooks</p>
<ol>
<li><a href="/zh/api/plugin-api/compiler-hooks#beforecompile" class="rp-link">beforeCompile</a></li>
<li><a href="/zh/api/plugin-api/compiler-hooks#aftercompile" class="rp-link">afterCompile</a></li>
</ol>
<p>Compilation hooks</p>
<ol>
<li><a href="/zh/api/plugin-api/compilation-hooks#optimizemodules" class="rp-link">optimizeModules</a></li>
<li><a href="/zh/api/plugin-api/compilation-hooks#optimizechunkmodules" class="rp-link">optimizeChunkModule</a></li>
<li><a href="/zh/api/plugin-api/compilation-hooks#finishmodules" class="rp-link">finishModules</a></li>
<li><a href="/zh/api/plugin-api/compilation-hooks#chunkasset" class="rp-link">chunkAsset</a></li>
</ol>
<p>NormalModuleFactory hooks</p>
<ol>
<li><a href="/zh/api/plugin-api/normal-module-factory-hooks#beforeresolve" class="rp-link">beforeResolve</a></li>
<li><a href="/zh/api/plugin-api/normal-module-factory-hooks#afterresolve" class="rp-link">afterResolve</a></li>
<li><a href="/zh/api/plugin-api/normal-module-factory-hooks#resolveforscheme" class="rp-link">ResolveForScheme</a></li>
</ol>
<p>ContextModuleFactory hooks</p>
<ol>
<li><a href="/zh/api/plugin-api/context-module-factory-hooks#beforeresolve" class="rp-link">beforeResolve</a></li>
</ol>
<h3 class="rp-toc-include" id="realcontenthash"><a href="#realcontenthash" class="rp-header-anchor rp-link" aria-hidden="true">#</a>realContentHash</h3>
<p>我们实现了 <code>optimization.realContentHash</code>，它会根据最终产物的文件内容进行 Hash 的计算，因此它所生成的 Hash 更为稳定，对缓存有更好的利用率，在 0.2 版本中，对于生产环境的构建会默认开启这一功能。</p>
<h3 class="rp-toc-include" id="esmsystem-format"><a href="#esmsystem-format" class="rp-header-anchor rp-link" aria-hidden="true">#</a>ESM/System format</h3>
<p>在新版本中，支持了生成 System/ESM 产物，输出 ESM 的产物配置如下：</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  output</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    chunkFormat</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;module&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    chunkLoading</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;import&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    library</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      type</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;module&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h3 class="rp-toc-include" id="新的-splitchunksplugin-实现"><a href="#新的-splitchunksplugin-实现" class="rp-header-anchor rp-link" aria-hidden="true">#</a>新的 <code>SplitChunksPlugin</code> 实现</h3>
<p>我们重构了 Rspack 现有的 <code>SplitChunksPlugin</code> 实现，这次重构使得 <code>SplitChunksPlugin</code> 的行为更加易于预测，同时也减少了排查相关问题的成本。</p>
<p>在重构后，我们有信心在 <code>SplitChunksPlugin</code> 上实现更多的新功能。我们很高兴地宣布，在 0.2 版本中，<code>SplitChunksPlugin</code> 支持了以下配置项：</p>
<ul>
<li><code>splitChunks.maxSize</code></li>
<li><code>splitChunks.maxAsyncSize</code></li>
<li><code>splitChunks.maxInitialSize</code></li>
<li><code>splitChunks.maxAsyncRequests</code></li>
<li><code>splitChunks.maxInitialRequests</code></li>
</ul>
<p>在 0.2 版本中，我们会默认使用新的 <code>SplitChunksPlugin</code>。如果你遇到问题，请及时反馈，我们会尽快修复。你可以通过 <code>experiments.newSplitChunks: false</code> 来切换回旧版本的实现，但我们强烈建议你使用新版本。我们将在 0.3 版本中，移除掉旧有的实现。</p>
<h3 class="rp-toc-include" id="datauri-支持"><a href="#datauri-支持" class="rp-header-anchor rp-link" aria-hidden="true">#</a>DataURI 支持</h3>
<p>我们实现了 DataURI 的支持，现在你可以编写以下代码以实现虚拟模块：</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> x </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> &#x27;data:text/javascript,export default 42&#x27;</span><span style="color:var(--shiki-foreground)">;</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>除此之外我们还支持了 <code>mimetype</code> 和 <code>scheme</code> 这两种 module rule condition，比如，你可以通过以下方式让 <code>scheme</code> 为 <code>&#x27;data&#x27;</code> 的资源不再当作内联处理，而是作为单独的资源文件</p>
<div class="rp-codeblock language-js"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  module</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    rules</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        scheme</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;data&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">        type</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> &#x27;asset/resource&#x27;</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">      }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">    ]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<h2 class="rp-toc-include" id="breaking-changes"><a href="#breaking-changes" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Breaking changes</h2>
<ul>
<li>
<p>文件名生成逻辑对齐</p>
<p>在 0.1.12 版本我们为了进一步对齐 webpack 的文件名生成逻辑，重构了文件名生成的实现，但导致 [ext] 在 <code>output.filename</code>、<code>output.chunkFilename</code>、<code>output.cssFilename</code> 和 <code>output.cssChunkFilename</code> 中的 [ext] 不会再被替换，这一行为现在和 webpack 保持一致，但对于 Rspack 0.1.12 之前的版本造成了 breaking change，如果你在以上 4 个文件名配置中使用了 [ext]，你需要修改成对应的 <code>.js</code> 或 <code>.css</code>，比如：</p>
<div class="rp-codeblock language-diff"><div class="rp-codeblock__title">rspack.config.mjs</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="diff" data-title="rspack.config.mjs"><code><span class="line"><span style="color:var(--shiki-foreground)">export default {</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  output: {</span></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">-    filename: &quot;[name][ext]&quot;,</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+    filename: &quot;[name].js&quot;,</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">-    chunkFilename: &quot;async/[name][ext]&quot;,</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+    chunkFilename: &quot;async/[name].js&quot;,</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">-    cssFilename: &quot;[name][ext]&quot;,</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+    cssFilename: &quot;[name].css&quot;,</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--shiki-token-deleted)">-    cssChunkFilename: &quot;async/[name][ext]&quot;,</span></span>
<span class="line"><span style="color:var(--shiki-token-inserted)">+    cssChunkFilename: &quot;async/[name].css&quot;,</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">  }</span></span>
<span class="line"><span style="color:var(--shiki-foreground)">}</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="复制代码"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg></button></div></div></div>
<p>详情：<a href="https://github.com/web-infra-dev/rspack/issues/3270" target="_blank" rel="noopener noreferrer" class="rp-link">https://github.com/web-infra-dev/rspack/issues/3270</a></p>
</li>
<li>
<p>生产环境下默认启用 realContentHash</p>
<p>详情：<a href="https://github.com/web-infra-dev/rspack/pull/3338" target="_blank" rel="noopener noreferrer" class="rp-link">https://github.com/web-infra-dev/rspack/pull/3338</a></p>
</li>
<li>
<p>修改了 resolve 的 extensions</p>
<p>详情：<a href="https://github.com/web-infra-dev/rspack/pull/3242" target="_blank" rel="noopener noreferrer" class="rp-link">https://github.com/web-infra-dev/rspack/pull/3242</a></p>
</li>
<li>
<p>修改了 @rspack/dev-middleware 和 @rspack/html-plugin 的导出方式，并移除了@rspack/dev-middleware 导出的 <code>getRspackMemoryAssets</code></p>
<p>详情：<a href="https://github.com/web-infra-dev/rspack/pull/3358" target="_blank" rel="noopener noreferrer" class="rp-link">https://github.com/web-infra-dev/rspack/pull/3358</a></p>
</li>
</ul>
<h2 class="rp-toc-include" id="webpack-兼容性更新"><a href="#webpack-兼容性更新" class="rp-header-anchor rp-link" aria-hidden="true">#</a>webpack 兼容性更新</h2>
<p>随着我们支持了更多的 webpack API，我们也兼容了更多的社区的 Plugin 和 Loader。我们适配了一些社区呼声较高的 Plugin 和 Loader。</p>
<h3 class="rp-toc-include" id="fork-ts-checker-webpack-plugin"><a href="#fork-ts-checker-webpack-plugin" class="rp-header-anchor rp-link" aria-hidden="true">#</a>fork-ts-checker-webpack-plugin</h3>
<p>在 Rspack 里进行 TypeScript 的类型检查是一个广泛的需求，Rspack 已经完全适配了 <a href="https://github.com/TypeStrong/fork-ts-checker-webpack-plugin" target="_blank" rel="noopener noreferrer" class="rp-link">fork-ts-checker-webpack-plugin</a>，你可以通过该插件在编译时进行 TypeScript 的类型检查，值得注意的是因为 TypeScript 的类型检查通常十分耗时，这使得在较大的项目上类型检查的耗时可能远超过 Rspack 本身的构建耗时。在 dev 模式下，该插件并不会阻塞构建，但是在 build 模式下该插件会阻塞构建，请根据你的实际需求选择是否启用该插件。</p>
<h3 class="rp-toc-include" id="license-webpack-plugin"><a href="#license-webpack-plugin" class="rp-header-anchor rp-link" aria-hidden="true">#</a>license-webpack-plugin</h3>
<p>一个广泛反馈的社区需求就是支持提取代码里的 license，Rspack 现在可以通过 <a href="https://github.com/xz64/license-webpack-plugin" target="_blank" rel="noopener noreferrer" class="rp-link">license-webpack-plugin</a> 实现提取代码里的 license 需求。</p>
<h3 class="rp-toc-include" id="style-loader--css-loader"><a href="#style-loader--css-loader" class="rp-header-anchor rp-link" aria-hidden="true">#</a>style-loader &amp; css-loader</h3>
<p>虽然 Rspack 支持并默认开启了 webpack 的 <code>experiments.css</code> 功能，但是社区上仍然有较多的生态强依赖 <a href="https://github.com/webpack/style-loader" target="_blank" rel="noopener noreferrer" class="rp-link">style-loader</a> &amp; <a href="https://github.com/webpack/css-loader" target="_blank" rel="noopener noreferrer" class="rp-link">css-loader</a>，我们在 0.2.0 完成了对 style-loader 和 css-loader 的支持，这也使得我们可以更好的适配 Svelte 和 Vue 等框架。</p>
<h3 class="rp-toc-include" id="node-loader"><a href="#node-loader" class="rp-header-anchor rp-link" aria-hidden="true">#</a>node-loader</h3>
<p>当使用 Rspack 打包如 NestJS 等 Node 应用时，一个常见的需求就是打包一些包含 addon 的库，这些库里的 native 依赖无法直接被打包进 JS 里，因此需要特殊处理，Rspack 适配了 <a href="https://github.com/webpack-contrib/node-loader" target="_blank" rel="noopener noreferrer" class="rp-link">node-loader</a> 所以你可以使用 Rspack 去构建 node 应用了。
Rspack 适配的 webpack 的 plugin 和 loader 远不仅此，我们在 <a href="https://github.com/rstackjs/rstack-examples/tree/main/rspack/loader-compat" target="_blank" rel="noopener noreferrer" class="rp-link">loader-compat</a> 和 <a href="https://github.com/rstackjs/rstack-examples/tree/main/rspack/plugin" target="_blank" rel="noopener noreferrer" class="rp-link">plugin-compat</a> 对已经适配的 plugin 和 loader 进行了追踪，如果你发现你使用的社区 plugin 和 loader 也已经兼容，欢迎提交给我们。</p>
<h2 class="rp-toc-include" id="框架生态更新"><a href="#框架生态更新" class="rp-header-anchor rp-link" aria-hidden="true">#</a>框架生态更新</h2>
<h3 class="rp-toc-include" id="modernjs-框架"><a href="#modernjs-框架" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Modern.js 框架</h3>
<p>得益于 <a href="https://modernjs.dev" target="_blank" rel="noopener noreferrer" class="rp-link">Modern.js 框架</a> 与 Rspack 的紧密合作与并行迭代，<strong>Modern.js Rspack 模式已经覆盖了 85% 的框架能力</strong>，支持 SSR、BFF、微前端等场景，并对齐了 TypeScript 类型检查、代码兼容性检测等功能。</p>
<p>在字节跳动内部，已有 80+ 个业务项目在使用 Modern.js Rspack 模式。其中一部分项目已经上线至生产环境，获得 10 倍左右的构建性能提升。</p>
<h3 class="rp-toc-include" id="modernjs-doc"><a href="#modernjs-doc" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Modern.js Doc</h3>
<p>除了 Modern.js 框架，Modern.js 体系下的文档站开发方案 —— <a href="https://modernjs.dev/doc-tools/zh/" target="_blank" rel="noopener noreferrer" class="rp-link">Modern.js Doc</a> 也将构建工具从 webpack 切换到了 Rspack，并将 MDX 编译流程基于 Rust 重写。</p>
<p>相较于早期使用 webpack 的版本，当前版本的文档构建速度可以缩短至秒级。以 Modern.js 官网文档为例，项目的启动和构建时间从 30s 缩短到 2s 以内。未来，我们计划将 Modern.js Doc 更名为 <strong>Rspress</strong>，作为 Rspack 官方的文档站方案，并通过单独的仓库进行维护。</p>
<blockquote>
<p>欢迎访问 <a href="https://github.com/web-infra-dev/modern.js" target="_blank" rel="noopener noreferrer" class="rp-link">Modern.js 代码仓库</a> 并体验上述内容。</p>
</blockquote>
<h3 class="rp-toc-include" id="vue"><a href="#vue" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Vue</h3>
<p>Rspack 0.2 已经完成了对 vue-loader 的兼容。对于 Vue 3 项目，你可以使用 Rspack 原生的 CSS、TS 处理器提升 Vue 项目的编译速度，你仅需要将 vue-loader 升级到 17.2.2 以上的版本，并设置 <code>experimentalInlineMatchResource: true</code> 即可。对于 Vue 3/Vue 2 支持的更多信息请参考 <a href="/zh/guide/tech/vue" class="rp-link">Vue</a>。</p>
<h3 class="rp-toc-include" id="svelte"><a href="#svelte" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Svelte</h3>
<p>得益于 Rspack 对 Loader API 的良好支持和 <a href="https://github.com/sveltejs/svelte-loader" target="_blank" rel="noopener noreferrer" class="rp-link">svelte-loader</a> 的优良设计，Rspack 已经完全适配了 <a href="https://github.com/sveltejs/svelte-loader" target="_blank" rel="noopener noreferrer" class="rp-link">svelte-loader</a>，因此你可以在 Rspack 直接使用 <a href="https://github.com/sveltejs/svelte-loader" target="_blank" rel="noopener noreferrer" class="rp-link">svelte-loader</a> 进行 svelte 应用的开发，你可以参考 <a href="https://github.com/rstackjs/rstack-examples/tree/main/rspack/svelte" target="_blank" rel="noopener noreferrer" class="rp-link">example-svelte</a> 完成 svelte-loader 相关配置。</p>
<h3 class="rp-toc-include" id="storybook"><a href="#storybook" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Storybook</h3>
<p>在 Storybook 团队的帮助下，Rspack 完成了对 Storybook React 版本的支持，你可以按照 <a href="/zh/guide/migration/storybook" class="rp-link">迁移 Storybook</a> 的方式从 webpack 版本迁移到 Rspack 版本，在实际的项目中测试在不开启 docgen 功能的情况下，Rspack 版本比 webpack 版本快 5-10 倍，在开启了 docgen 的情况下，因为 Rspack 仍然依赖 babel 处理 docgen,因此性能受到影响，但也有 2-3 倍左右提升。</p>
<h3 class="rp-toc-include" id="angular"><a href="#angular" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Angular</h3>
<p>在 Valor 团队的帮助下，Rspack 完成了对 angular 的初步支持，你可以使用 Rspack 构建 angular 应用，但是目前对 dev 和 HMR 的支持还没适配完，我们将在 0.2.x 版本继续跟进 Angular 的支持。</p>
<h3 class="rp-toc-include" id="nestjs"><a href="#nestjs" class="rp-header-anchor rp-link" aria-hidden="true">#</a>NestJS</h3>
<p>在 Rosa、Nx 和 Valor 的帮助下，Rspack 完成了对 NestJS 的编译支持，你可以使用 Rspack 打包 NestJS 应用，在实际项目中进行测试，Rspack 相比 webpack 版本有 5-10 倍的构建性能提升。</p>
<h2 class="rp-toc-include" id="开发指南"><a href="#开发指南" class="rp-header-anchor rp-link" aria-hidden="true">#</a>开发指南</h2>
<p>Rspack 团队非常重视开源社区做出的宝贵贡献。我们致力于保持开放的态度，努力在每一步都让开源社区参与进来。
这就是为什么我们目前正在制作一份全面的<a href="/zh/contribute/" class="rp-link">开发指南</a>，为贡献者提供 Rspack 所有的开发文档。
当前版本的指南包含构建、测试、调试和分析 Rspack 的所有必要资料。此外，它还包括贡献流程，例如如何创建最小的<a href="https://github.com/web-infra-dev/rspack-repro" target="_blank" rel="noopener noreferrer" class="rp-link">可重现示例</a>。
将来，该指南还会概述 Rspack 的整体架构，使贡献者能够深入了解该项目的内部工作原理。</p>
<h2 class="rp-toc-include" id="测试架构"><a href="#测试架构" class="rp-header-anchor rp-link" aria-hidden="true">#</a>测试架构</h2>
<p>针对稳定发布，我们目前：</p>
<ul>
<li>在 Rspack 仓库中集成各种示例（目前有 38 个示例）</li>
<li>正在从 webpack 仓库移植所有的 webpack 集成测试</li>
<li>在 Node.js 版本 14、16 和 18 上运行所有测试</li>
<li>搭建了独立的 ecosystem-ci 仓库用于集成社区的上层框架</li>
</ul>
<h2 class="rp-toc-include" id="nightly-release"><a href="#nightly-release" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Nightly release</h2>
<p>为了加速迭代，Rspack 每天发布一次带有“@nightly” 标签的 npm 包。</p>
<h2 class="rp-toc-include" id="致谢"><a href="#致谢" class="rp-header-anchor rp-link" aria-hidden="true">#</a>致谢</h2>
<p>随着 Rspack 0.2 版本的发布，我们衷心感谢所有为这个版本付出努力的贡献者。</p>
<p>特别感谢</p>
<ul>
<li><a href="https://github.com/TheLarkInn" target="_blank" rel="noopener noreferrer" class="rp-link">@TheLarkInn</a> 和 <a href="https://github.com/alexander-akait" target="_blank" rel="noopener noreferrer" class="rp-link">@alexander-akait</a> ，回答和解决了很多 Rspack 团队关于 webpack 的疑问。</li>
<li><a href="https://github.com/zackarychapple" target="_blank" rel="noopener noreferrer" class="rp-link">@zackarychapple</a>、<a href="https://github.com/valorkin" target="_blank" rel="noopener noreferrer" class="rp-link">@valorkin</a>、<a href="https://github.com/edusperoni" target="_blank" rel="noopener noreferrer" class="rp-link">@edusperoni</a> 以及 <a href="https://github.com/Coly010" target="_blank" rel="noopener noreferrer" class="rp-link">@Coly101</a> ，帮助 Rspack 对 Angular 做了基本支持，特别是 <a href="https://github.com/zackarychapple" target="_blank" rel="noopener noreferrer" class="rp-link">@zackarychapple</a> 帮助我们 review 这篇发布公告的英文版本。</li>
<li><a href="https://github.com/suxin2017" target="_blank" rel="noopener noreferrer" class="rp-link">@suxin2017</a>，在 Rspack 里支持了 System.js format，optional-dependency 等功能，并在 Windows 兼容方面做了很多贡献。</li>
<li><a href="https://github.com/faga295" target="_blank" rel="noopener noreferrer" class="rp-link">@faga295</a>，在 Rspack 里支持了解压代码注释功能和 <code>rspack preview</code> 功能。</li>
<li><a href="https://github.com/lippzhang" target="_blank" rel="noopener noreferrer" class="rp-link">@lippzhang</a>，在对齐 webpack 行为方面做了很多贡献。</li>
<li><a href="https://github.com/HerringtonDarkholme" target="_blank" rel="noopener noreferrer" class="rp-link">@HerringtonDarkholme</a>，允许 Rspack 使用 rspack.config.ts 作为配置文件</li>
<li><a href="https://github.com/dhruvkelawala" target="_blank" rel="noopener noreferrer" class="rp-link">@dhruvkelawala</a>, 在 Rspack 里实现了 builtins.provide 功能</li>
<li><a href="https://github.com/magic-akari" target="_blank" rel="noopener noreferrer" class="rp-link">@magic-akari</a>，在 Rspack 里支持了 <code>new URL(&quot;./foo&quot;, import.meta.url)</code> 语法</li>
<li><a href="https://github.com/tuchg" target="_blank" rel="noopener noreferrer" class="rp-link">@tuchg</a>，在 Rspack 里支持了打包 .wasm 文件</li>
</ul>
<p>我们还要感谢所有使用 Rspack 的用户，对 Rspack 这样一个年轻的开源项目展现出信任，你们的宝贵反馈对我们项目的改进和优化起到了关键作用。你们的支持和信任是我们前进的动力。</p>
<p>最后，让我们共同庆祝 Rspack 0.2 版本的发布，并期待未来的发展和更多的合作机会。再次感谢所有支持和关注 Rspack 的朋友们！</p><!--/$-->]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Rspack 正式发布了]]></title>
            <link>https://rspack.rs/zh/blog/announcing-0-1</link>
            <guid isPermaLink="false">/zh/blog/announcing-0-1</guid>
            <pubDate>Mon, 06 Mar 2023 21:37:00 GMT</pubDate>
            <description><![CDATA[Rspack 正式发布了！]]></description>
            <content:encoded><![CDATA[<!--$--><p><em>2023 年 3 月 6 日</em></p>
<h1 class="rp-toc-include" id="rspack-正式发布了"><a href="#rspack-正式发布了" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Rspack 正式发布了<!-- --> </h1><div class="rp-not-doc rp-llms-container"><button class="rp-not-doc rp-llms-button rp-llms-copy-button"><div class="rp-llms-copy-button__icon-wrapper"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-llms-copy-button__icon-success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-llms-copy-button__icon-copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg></div><span>复制 Markdown</span></button><button class="rp-llms-button rp-llms-view-options__trigger "><svg width="1em" height="1em" viewBox="0 0 32 32" class="rp-llms-view-options__arrow "><path fill="currentColor" d="M16 22 6 12l1.4-1.4 8.6 8.6 8.6-8.6L26 12z"></path></svg></button></div>
<p>今天我们很高兴跟大家宣布 Rspack 正式发布了！Rspack 是由 ByteDance Web Infra 团队孵化的基于 Rust 语言开发的 Bundler，拥有高性能、兼容 webpack 生态、定制性强等多种优点，它解决了我们在业务场景中遇到的非常多的问题，让很多开发者的体验有了质的提升。为了让更多的人可以参与到这样有趣的事情中，我们正式开放 Rspack 的源码，欢迎大家参与建设。</p>
<h2 class="rp-toc-include" id="为什么要做-rspack"><a href="#为什么要做-rspack" class="rp-header-anchor rp-link" aria-hidden="true">#</a>为什么要做 Rspack？</h2>
<p>字节跳动内部存在非常多的巨型前端应用，它们有着非常复杂的构建配置，十几分钟甚至半小时的构建耗时，我们尝试了多种方法去优化这些项目的编译速度，但是社区内存在的方案都或多或少存在一些问题，在对这些问题总结后，我们理解到工程师对 Bundler 的诉求是：</p>
<ul>
<li>良好的 Dev 启动性能，<code>npm run dev</code> 是开发者每天需要运行很多次的命令，大型项目每次都需要等待 10 分钟，这对于工程师来说是非常痛苦的，所以优化 dev start 的时间是非常重要的。</li>
<li>良好的 Build 性能，<code>npm run build</code> 是在 CI CD 环境中经常运行的指令，他决定了应用生产交付的效率，在生产环境中有些应用经常需要 20 ～ 30 分钟的构建时间，如果能缩短这里的耗时对开发链路也会非常有帮助。</li>
<li>足够灵活的配置，用户工程的配置灵活多变，并没有做到完全的统一，在之前尝试将 webpack 配置迁移到其他构建工具的过程中我们就遇到了非常多的问题，他们的配置都很难达到 webpack 的灵活程度。</li>
<li>生产环境的产物优化能力，在启动 Rspack 之前，我们实践了社区内的各种方案，但是他们都面临了生产环境一定程度负优化的情况，例如 拆包拆的不够精细等等。所以生产环境产物优化是我们不可舍弃的功能点。</li>
</ul>
<p>在明确这四点之后，我们调研了社区内的所有技术方案，发现并没有完全满足我们需求的，所以我们决定自研 Rspack。</p>
<h2 class="rp-toc-include" id="目前-rspack-是什么阶段"><a href="#目前-rspack-是什么阶段" class="rp-header-anchor rp-link" aria-hidden="true">#</a>目前 Rspack 是什么阶段？</h2>
<p>到今天为止 Rspack 已经开发 11 个月左右的时间了，虽然还处于比较早期的阶段，但是在我们验证中， Rspack 可以给项目带来 5 ～ 10 倍的编译时间的提升，并且随着我们内置了越来越多的常见 features，性能还在逐步的提升中。</p>
<p>目前 Rspack 已经完成了 webpack Loader 架构的支持，你可以在 Rspack 中使用很多你之前见到的 Loader，如 <code>babel-loader</code> <code>less-loader</code> <code>svgr</code> 等等。我们长期的目标是完整支持 Loader，未来可以直接在 Rspack 中使用社区内的 <code>vue-loader</code>。</p>
<p>当下 Rspack 对缓存的支持还比较简单，只有内存级别的缓存，未来我们会建设更强的缓存能力，包括可以写入硬盘的缓存，并且我们会把缓存做到可以跨设备共享和迁移，提升大型应用的缓存复用率。</p>
<p>Rspack 作为一个较为底层的基础设施，需要通过和社区内的各种上层框架结合才能在开发中获得发挥作用，目前 Rspack 已经接入了字节内的各种研发框架，外部的合作将逐渐开始。</p>
<h2 class="rp-toc-include" id="acknowledgement"><a href="#acknowledgement" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Acknowledgement</h2>
<p>Rspack 能在今天面世，离不开社区内各个项目的启发和支持，在这里对这些前辈表示致敬和感谢：</p>
<ul>
<li><a href="https://webpack.js.org/" target="_blank" rel="noopener noreferrer" class="rp-link">webpack 团队和社区</a> 创建了一个优秀的打包工具和丰富的生态。</li>
<li><a href="https://github.com/sokra" target="_blank" rel="noopener noreferrer" class="rp-link">@sokra</a> 在 <a href="https://github.com/webpack/webpack" target="_blank" rel="noopener noreferrer" class="rp-link">webpack</a> 项目上的出色工作。</li>
<li><a href="https://github.com/ScriptedAlchemy" target="_blank" rel="noopener noreferrer" class="rp-link">@ScriptedAlchemy</a> 创造了模块联邦，并帮助 Rspack 与社区建立联系。</li>
<li><a href="https://swc.rs/" target="_blank" rel="noopener noreferrer" class="rp-link">SWC</a> 项目（由 <a href="https://github.com/kdy1" target="_blank" rel="noopener noreferrer" class="rp-link">@kdy1</a> 创建），为 Rspack 的代码解析、转换和压缩提供了支持。</li>
<li><a href="https://github.com/evanw/esbuild" target="_blank" rel="noopener noreferrer" class="rp-link">esbuild</a> 项目（由 <a href="https://github.com/evanw" target="_blank" rel="noopener noreferrer" class="rp-link">@evanw</a> 创建），它启发了 Rspack 的并发架构。</li>
<li><a href="https://github.com/napi-rs/napi-rs" target="_blank" rel="noopener noreferrer" class="rp-link">NAPI-RS</a> 项目（由 <a href="https://github.com/Brooooooklyn" target="_blank" rel="noopener noreferrer" class="rp-link">@Brooooooklyn</a> 创建），为 Rspack 的 node-binding 实现提供了支持。</li>
<li><a href="https://github.com/parcel-bundler/parcel" target="_blank" rel="noopener noreferrer" class="rp-link">Parcel</a> 项目(由 <a href="https://github.com/devongovett" target="_blank" rel="noopener noreferrer" class="rp-link">@devongovett</a>创建)，它是 Rust Bundler 的先行探索者并启发了 Rspack 的增量构建架构.</li>
<li><a href="https://github.com/vitejs/vite" target="_blank" rel="noopener noreferrer" class="rp-link">Vite</a> 由<a href="https://github.com/yyx990803" target="_blank" rel="noopener noreferrer" class="rp-link">尤雨溪</a>创建，它和 Rollup 社区的兼容性设计启发了 Rspack 和 webpack 社区的兼容设计。</li>
<li><a href="https://github.com/rolldown-rs/rolldown" target="_blank" rel="noopener noreferrer" class="rp-link">Rolldown</a> 项目(由 <a href="https://github.com/sponsors/rolldown-rs" target="_blank" rel="noopener noreferrer" class="rp-link">Rolldown 团队</a>创建)，它探索了使用 Rust 构建高性能 Bundler + 兼容 Rollup API 的可能性，启发了 Rspack 的设计方向。</li>
<li><a href="https://github.com/jantimon/html-webpack-plugin" target="_blank" rel="noopener noreferrer" class="rp-link">html-webpack-plugin</a> 项目（由 <a href="https://github.com/jantimon" target="_blank" rel="noopener noreferrer" class="rp-link">@jantimon</a> 创建）, Rspack 的 <code>@rspack/html-plugin</code> 是 [<a href="https://github.com/jantimon/html-webpack-plugin" target="_blank" rel="noopener noreferrer" class="rp-link">html-webpack-plugin</a> 的一个 fork 来避免使用在 Rspack 中尚未支持的 webpack API。</li>
<li><a href="https://github.com/vercel/turbo" target="_blank" rel="noopener noreferrer" class="rp-link">Turbopack</a> 项目，它启发了 Rspack 里基于 AST 的路径重写逻辑。</li>
</ul>
<h2 class="rp-toc-include" id="未来计划"><a href="#未来计划" class="rp-header-anchor rp-link" aria-hidden="true">#</a>未来计划</h2>
<h3 class="rp-toc-include" id="完善基础能力"><a href="#完善基础能力" class="rp-header-anchor rp-link" aria-hidden="true">#</a>完善基础能力</h3>
<p>Rspack 虽然目前提供的能力能够满足大多数的项目使用，但是相比 webpack 提供的丰富能力仍然相差很多，我们在未来会根据社区反馈，丰富 Rspack 的基础能力，满足更多的构建场景需求。</p>
<h3 class="rp-toc-include" id="跟社区内的伙伴合作"><a href="#跟社区内的伙伴合作" class="rp-header-anchor rp-link" aria-hidden="true">#</a>跟社区内的伙伴合作</h3>
<p>Rspack 作为一个底层依赖解决了我们自己在工作中遇到的很多问题，相信他也可以解决社区的问题。我们非常愿意给社区内的框架团队一些支持，让大家发挥出来 Rspack 真正的性能优势。如果你凑巧在开发一个前端框架，请联系我们。
<strong>同时我们也和 webpack 团队确立了合作关系</strong>，Rspack 作为 webpack 通过 Rust 进行性能优化的一个尝试，未来我们会和 webpack 团队一起探索优化 webpack 的更多可能性。当 Rspack 达到一定的成熟度时，webpack 团队将尝试以实验特性的方式将 Rspack 集成到 webpack 中。</p>
<h3 class="rp-toc-include" id="提升插件能力"><a href="#提升插件能力" class="rp-header-anchor rp-link" aria-hidden="true">#</a>提升插件能力</h3>
<p>目前 Rspack 已经基本支持了 Loader API，和较少的 webpack Plugin API，有很多 API 因为会产生较大的性能问题影响，所以我们暂时没有暴露，我们同时也在探索更高性能的插件通信方案，另外一部分 API 是因为我们精力问题暂时没有完成，欢迎大家 PR。在未来，我们会考虑提供高性能的动态插件方案，这些插件可以在提供自由定制的功能的同时，带给开发者更好的开发体验。</p>
<h3 class="rp-toc-include" id="持续提升性能"><a href="#持续提升性能" class="rp-header-anchor rp-link" aria-hidden="true">#</a>持续提升性能</h3>
<p>目前 Rspack 是以性能为核心卖点的项目，所以在未来我们会做很多的事情以保持这个特性，如完善性能观测实验室，做好性能防劣化的工作；在更多的场景中使用并发/多核友好的算法；研发可跨平台共享的缓存体系；优化内存占用和消耗等等。</p>
<h3 class="rp-toc-include" id="建设质量保障体系"><a href="#建设质量保障体系" class="rp-header-anchor rp-link" aria-hidden="true">#</a>建设质量保障体系</h3>
<p>在保障性能的同时，我们也会努力去保障 Rspack 的质量，webpack 已经积累了非常丰富的测试用例，未来 Rspack 会复用 webpack 已有的测试用例来完善自己的逻辑。建设更加完善的 CI 体系，和社区项目共建 Ecosystem CI 体系，保障项目升级不对上游的项目造成 break，保障项目长期健康，并且在测试覆盖率上保障长期上升；</p>
<p>根据我们过去使用 webpack 的经验，升级构建工具是一件耗时耗力的操作，我们也要请大家帮助我们贡献更多的测试用例，Rspack 会在迭代中尽量保持兼容。</p>
<h2 class="rp-toc-include" id="试用"><a href="#试用" class="rp-header-anchor rp-link" aria-hidden="true">#</a>试用</h2>
<ul>
<li>快速开始：<a href="/zh/guide/start/quick-start" class="rp-link">rspack.rs</a></li>
<li>GitHub 仓库：<a href="https://github.com/web-infra-dev/rspack" target="_blank" rel="noopener noreferrer" class="rp-link">github.com/web-infra-dev/rspack</a></li>
</ul><!--/$-->]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Rspack 博客]]></title>
            <link>https://rspack.rs/zh/blog/</link>
            <guid isPermaLink="false">/zh/blog/</guid>
            <description><![CDATA[Rspack 博客归档，汇总版本发布、生态更新、团队动态与技术实践文章，便于按时间线浏览与查阅，帮助快速定位相关信息。]]></description>
            <content:encoded><![CDATA[<h1 class="rp-toc-include" id="rspack-博客"><span>Rspack 博客</span><a href="#rspack-博客" class="rp-header-anchor rp-link" aria-hidden="true">#</a> </h1><div class="rp-not-doc rp-llms-container"><button class="rp-not-doc rp-llms-button rp-llms-copy-button"><div class="rp-llms-copy-button__icon-wrapper"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-llms-copy-button__icon-success"><path fill="currentColor" d="m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-llms-copy-button__icon-copy"><path fill="currentColor" d="M20 8v12H8V8zm0-2H8a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2"></path><path fill="currentColor" d="M4 16H2V4a2 2 0 0 1 2-2h12v2H4Z"></path></svg></div><span>复制 Markdown</span></button><button class="rp-llms-button rp-llms-view-options__trigger "><svg width="1em" height="1em" viewBox="0 0 32 32" class="rp-llms-view-options__arrow "><path fill="currentColor" d="M16 22 6 12l1.4-1.4 8.6 8.6 8.6-8.6L26 12z"></path></svg></button></div><!--$--><p>浏览 Rspack 团队 <a href="https://x.com/rspack_dev" target="_blank" rel="noopener noreferrer" class="rp-link">@rspack_dev</a> 发布的版本说明、生态动态与技术文章。</p>
<!-- -->
<div class="blogPage-QpKeWn rp-not-doc"><section class="featuredSection-Y3bjII"><a href="/zh/blog/announcing-2-0" class="card-tONMLM featured-W4XJYg interactiveCard-MMJbVF rp-link" data-tilt-card="true"><span class="date-Td1gj5">2026年4月22日</span><div class="title-zAqg4x featuredTitle-BicFLy">Rspack 2.0 正式发布</div><div class="description-WkXUDU featuredDescription-rgRiSD clampedDescription-A_BULP"><p class="descriptionParagraph-xUjGh7">Rspack 2.0 正式发布，在保持与 webpack 生态兼容的同时，引入了更现代的默认行为、API 设计和构建产物。</p></div><div class="footer-vhcqbm"><div class="compactGroup-Ij3Cuk avatarOverride-LGUxCZ" title="Rspack Team"><div class="compactAvatars-K_PsP6" aria-hidden="true"><img src="https://assets.rspack.rs/rspack/rspack-logo-with-background.png" alt="" class="compactAvatar-VpXzKi" loading="lazy" decoding="async"/></div><div class="compactNames-yJrKbP">Rspack Team</div></div></div></a></section><section class="grid-Xrk9hS"><a href="/zh/blog/announcing-1-7" class="card-tONMLM gridItem-W7_sGP interactiveCard-MMJbVF rp-link" data-tilt-card="true"><span class="date-Td1gj5">2025年12月31日</span><div class="title-zAqg4x">Rspack 1.7 发布公告</div><div class="description-WkXUDU clampedDescription-A_BULP"><p class="descriptionParagraph-xUjGh7">Rspack 1.7 版本发布，提升了 SWC Wasm 插件兼容性，支持 Import Bytes 资源导入，并将多项实验特性稳定化。</p></div><div class="footer-vhcqbm"><div class="compactGroup-Ij3Cuk avatarOverride-LGUxCZ" title="Rspack Team"><div class="compactAvatars-K_PsP6" aria-hidden="true"><img src="https://assets.rspack.rs/rspack/rspack-logo-with-background.png" alt="" class="compactAvatar-VpXzKi" loading="lazy" decoding="async"/></div><div class="compactNames-yJrKbP">Rspack Team</div></div></div></a><a href="/zh/blog/announcing-1-6" class="card-tONMLM gridItem-W7_sGP interactiveCard-MMJbVF rp-link" data-tilt-card="true"><span class="date-Td1gj5">2025年10月30日</span><div class="title-zAqg4x">Rspack 1.6 发布公告</div><div class="description-WkXUDU clampedDescription-A_BULP"><p class="descriptionParagraph-xUjGh7">Rspack 1.6 版本发布，带来了更好的 ESM 输出、增强 tree shaking 能力、支持 defer import 语法、稳定 layers 特性，以及默认启用 barrel 文件优化。</p></div><div class="footer-vhcqbm"><div class="compactGroup-Ij3Cuk avatarOverride-LGUxCZ" title="Rspack Team"><div class="compactAvatars-K_PsP6" aria-hidden="true"><img src="https://assets.rspack.rs/rspack/rspack-logo-with-background.png" alt="" class="compactAvatar-VpXzKi" loading="lazy" decoding="async"/></div><div class="compactNames-yJrKbP">Rspack Team</div></div></div></a><a href="/zh/blog/announcing-1-5" class="card-tONMLM gridItem-W7_sGP interactiveCard-MMJbVF rp-link" data-tilt-card="true"><span class="date-Td1gj5">2025年8月26日</span><div class="title-zAqg4x">Rspack 1.5 发布公告</div><div class="description-WkXUDU clampedDescription-A_BULP"><p class="descriptionParagraph-xUjGh7">Rspack 1.5 版本发布，支持 Barrel 文件优化、常量内联优化，新增了内置文件系统监听器、虚拟模块插件和 Rust 扩展机制，并不再支持 Node 16。</p></div><div class="footer-vhcqbm"><div class="compactGroup-Ij3Cuk avatarOverride-LGUxCZ" title="Rspack Team"><div class="compactAvatars-K_PsP6" aria-hidden="true"><img src="https://assets.rspack.rs/rspack/rspack-logo-with-background.png" alt="" class="compactAvatar-VpXzKi" loading="lazy" decoding="async"/></div><div class="compactNames-yJrKbP">Rspack Team</div></div></div></a><a href="https://github.com/orgs/web-infra-dev/discussions/28" target="_blank" rel="noopener noreferrer" class="card-tONMLM gridItem-W7_sGP interactiveCard-MMJbVF rp-link" data-tilt-card="true"><span class="date-Td1gj5">2025年7月31日</span><div class="title-zAqg4x">Bundler tree shaking 原理及差异</div><div class="description-WkXUDU clampedDescription-A_BULP"><p class="descriptionParagraph-xUjGh7">Tree shaking 已经成为现代前端打包工具的重要组成部分。本文简要概述了不同打包工具中 tree shaking 的原理，并探讨了它们之间的主要差异。</p></div><div class="footer-vhcqbm"><div class="compactGroup-Ij3Cuk avatarOverride-LGUxCZ" title="Rspack Team"><div class="compactAvatars-K_PsP6" aria-hidden="true"><img src="https://assets.rspack.rs/rspack/rspack-logo-with-background.png" alt="" class="compactAvatar-VpXzKi" loading="lazy" decoding="async"/></div><div class="compactNames-yJrKbP">Rspack Team</div></div></div></a><a href="/zh/blog/announcing-1-4" class="card-tONMLM gridItem-W7_sGP interactiveCard-MMJbVF rp-link" data-tilt-card="true"><span class="date-Td1gj5">2025年6月26日</span><div class="title-zAqg4x">Rspack 1.4 发布公告</div><div class="description-WkXUDU clampedDescription-A_BULP"><span class="descriptionParagraph-xUjGh7">Rspack 1.4 版本发布，支持在浏览器中运行、默认启用增量构建，同时集成更快的 SWC、生成更小的构建产物，并引入了 `CssChunkingPlugin` 等新功能。</span></div><div class="footer-vhcqbm"><div class="compactGroup-Ij3Cuk avatarOverride-LGUxCZ" title="Rspack Team"><div class="compactAvatars-K_PsP6" aria-hidden="true"><img src="https://assets.rspack.rs/rspack/rspack-logo-with-background.png" alt="" class="compactAvatar-VpXzKi" loading="lazy" decoding="async"/></div><div class="compactNames-yJrKbP">Rspack Team</div></div></div></a><a href="/zh/blog/rspack-next-partner" class="card-tONMLM gridItem-W7_sGP interactiveCard-MMJbVF rp-link" data-tilt-card="true"><span class="date-Td1gj5">2025年4月10日</span><div class="title-zAqg4x">Rspack 加入 Next.js 生态</div><div class="description-WkXUDU clampedDescription-A_BULP"><p class="descriptionParagraph-xUjGh7">今天，我们很高兴地推出 next-rspack，这是一个社区驱动的插件，让 Next.js 能够直接使用 Rspack 作为打包工具。</p></div><div class="footer-vhcqbm"><div class="compactGroup-Ij3Cuk avatarOverride-LGUxCZ" title="Rspack Team"><div class="compactAvatars-K_PsP6" aria-hidden="true"><img src="https://assets.rspack.rs/rspack/rspack-logo-with-background.png" alt="" class="compactAvatar-VpXzKi" loading="lazy" decoding="async"/></div><div class="compactNames-yJrKbP">Rspack Team</div></div></div></a><a href="/zh/blog/announcing-1-3" class="card-tONMLM gridItem-W7_sGP interactiveCard-MMJbVF rp-link" data-tilt-card="true"><span class="date-Td1gj5">2025年3月28日</span><div class="title-zAqg4x">Rspack 1.3 发布公告</div><div class="description-WkXUDU clampedDescription-A_BULP"><p class="descriptionParagraph-xUjGh7">Rspack 1.3 版本发布，支持检测循环引用、构建 HTTP 模块和引用 AMD 模块，引入全新的 lazy compilation 中间件，以及优化了代码分割性能、产物体积和内存占用。</p></div><div class="footer-vhcqbm"><div class="compactGroup-Ij3Cuk avatarOverride-LGUxCZ" title="Rspack Team"><div class="compactAvatars-K_PsP6" aria-hidden="true"><img src="https://assets.rspack.rs/rspack/rspack-logo-with-background.png" alt="" class="compactAvatar-VpXzKi" loading="lazy" decoding="async"/></div><div class="compactNames-yJrKbP">Rspack Team</div></div></div></a><a href="/zh/blog/announcing-1-2" class="card-tONMLM gridItem-W7_sGP interactiveCard-MMJbVF rp-link" data-tilt-card="true"><span class="date-Td1gj5">2025年1月21日</span><div class="title-zAqg4x">Rspack 1.2 发布公告</div><div class="description-WkXUDU clampedDescription-A_BULP"><p class="descriptionParagraph-xUjGh7">Rspack 1.2 版本发布，引入实验性的持久化缓存、更快的代码分割算法以及 Yarn PnP 支持等功能。</p></div><div class="footer-vhcqbm"><div class="compactGroup-Ij3Cuk avatarOverride-LGUxCZ" title="Rspack Team"><div class="compactAvatars-K_PsP6" aria-hidden="true"><img src="https://assets.rspack.rs/rspack/rspack-logo-with-background.png" alt="" class="compactAvatar-VpXzKi" loading="lazy" decoding="async"/></div><div class="compactNames-yJrKbP">Rspack Team</div></div></div></a><a href="https://github.com/orgs/web-infra-dev/discussions/22" target="_blank" rel="noopener noreferrer" class="card-tONMLM gridItem-W7_sGP interactiveCard-MMJbVF rp-link" data-tilt-card="true"><span class="date-Td1gj5">2025年1月7日</span><div class="title-zAqg4x">构建系统与前端打包工具</div><div class="description-WkXUDU clampedDescription-A_BULP"><p class="descriptionParagraph-xUjGh7">本文会简单介绍 &quot;Build Systems à la Carte: Theory and Practice&quot; 这篇论文的内容，并尝试从 build system 的角度来概括 bundlers。</p></div><div class="footer-vhcqbm"><div class="compactGroup-Ij3Cuk avatarOverride-LGUxCZ" title="Rspack Team"><div class="compactAvatars-K_PsP6" aria-hidden="true"><img src="https://assets.rspack.rs/rspack/rspack-logo-with-background.png" alt="" class="compactAvatar-VpXzKi" loading="lazy" decoding="async"/></div><div class="compactNames-yJrKbP">Rspack Team</div></div></div></a><a href="https://github.com/orgs/web-infra-dev/discussions/21" target="_blank" rel="noopener noreferrer" class="card-tONMLM gridItem-W7_sGP interactiveCard-MMJbVF rp-link" data-tilt-card="true"><span class="date-Td1gj5">2025年1月6日</span><div class="title-zAqg4x">RSC 和 Server Action 构建实践</div><div class="description-WkXUDU clampedDescription-A_BULP"><p class="descriptionParagraph-xUjGh7">本文介绍了 React 中 RSC（React Server Components）和 Server Action 的构建实践，包括它们的概念、渲染方式、在 webpack 中的打包流程，以及 Turbopack 是如何在一个模块图中完成打包多个环境模块的。</p></div><div class="footer-vhcqbm"><div class="compactGroup-Ij3Cuk avatarOverride-LGUxCZ" title="Rspack Team"><div class="compactAvatars-K_PsP6" aria-hidden="true"><img src="https://assets.rspack.rs/rspack/rspack-logo-with-background.png" alt="" class="compactAvatar-VpXzKi" loading="lazy" decoding="async"/></div><div class="compactNames-yJrKbP">Rspack Team</div></div></div></a><a href="/zh/blog/announcing-1-1" class="card-tONMLM gridItem-W7_sGP interactiveCard-MMJbVF rp-link" data-tilt-card="true"><span class="date-Td1gj5">2024年11月7日</span><div class="title-zAqg4x">Rspack 1.1 发布公告</div><div class="description-WkXUDU clampedDescription-A_BULP"><p class="descriptionParagraph-xUjGh7">Rspack 和 Rsbuild 1.1 版本发布，显著提升了冷启动和增量构建的性能，同时改进了内置的 HTML 插件和配置选项的类型提示。</p></div><div class="footer-vhcqbm"><div class="compactGroup-Ij3Cuk avatarOverride-LGUxCZ" title="Rspack Team"><div class="compactAvatars-K_PsP6" aria-hidden="true"><img src="https://assets.rspack.rs/rspack/rspack-logo-with-background.png" alt="" class="compactAvatar-VpXzKi" loading="lazy" decoding="async"/></div><div class="compactNames-yJrKbP">Rspack Team</div></div></div></a><a href="/zh/blog/announcing-1-0" class="card-tONMLM gridItem-W7_sGP interactiveCard-MMJbVF rp-link" data-tilt-card="true"><span class="date-Td1gj5">2024年8月28日</span><div class="title-zAqg4x">Rspack 1.0 发布公告</div><div class="description-WkXUDU clampedDescription-A_BULP"><p class="descriptionParagraph-xUjGh7">今天，Rspack 终于到达了一个崭新的阶段 —— 1.0。这意味着 Rspack 已经达到生产稳定，覆盖了 webpack 绝大多数的 API 和功能，并已经做好支持更多用户的准备。</p></div><div class="footer-vhcqbm"><div class="compactGroup-Ij3Cuk avatarOverride-LGUxCZ" title="Rspack Team"><div class="compactAvatars-K_PsP6" aria-hidden="true"><img src="https://assets.rspack.rs/rspack/rspack-logo-with-background.png" alt="" class="compactAvatar-VpXzKi" loading="lazy" decoding="async"/></div><div class="compactNames-yJrKbP">Rspack Team</div></div></div></a><a href="/zh/blog/announcing-1-0-alpha" class="card-tONMLM gridItem-W7_sGP interactiveCard-MMJbVF rp-link" data-tilt-card="true"><span class="date-Td1gj5">2024年6月28日</span><div class="title-zAqg4x">Rspack 1.0 alpha 发布公告</div><div class="description-WkXUDU clampedDescription-A_BULP"><p class="descriptionParagraph-xUjGh7">Rspack 1.0 alpha 现已发布至 npm！在发布 Rspack 1.0 稳定版之前，我们将进行 1～2 个月的测试，以改进 1.0 版本的 API 稳定性和可靠性，并验证对下游项目的影响。</p></div><div class="footer-vhcqbm"><div class="compactGroup-Ij3Cuk avatarOverride-LGUxCZ" title="Rspack Team"><div class="compactAvatars-K_PsP6" aria-hidden="true"><img src="https://assets.rspack.rs/rspack/rspack-logo-with-background.png" alt="" class="compactAvatar-VpXzKi" loading="lazy" decoding="async"/></div><div class="compactNames-yJrKbP">Rspack Team</div></div></div></a><a href="/zh/blog/announcing-0-7" class="card-tONMLM gridItem-W7_sGP interactiveCard-MMJbVF rp-link" data-tilt-card="true"><span class="date-Td1gj5">2024年5月28日</span><div class="title-zAqg4x">Rspack 0.7 发布公告</div><div class="description-WkXUDU clampedDescription-A_BULP"><p class="descriptionParagraph-xUjGh7">Rspack 0.7 版本发布，支持 lazy compilation，能够显著提升大型应用的 dev startup 性能。同时引入了全新的 css-module-lexer，使 CSS 打包速度提升 4 倍。</p></div><div class="footer-vhcqbm"><div class="compactGroup-Ij3Cuk avatarOverride-LGUxCZ" title="Rspack Team"><div class="compactAvatars-K_PsP6" aria-hidden="true"><img src="https://assets.rspack.rs/rspack/rspack-logo-with-background.png" alt="" class="compactAvatar-VpXzKi" loading="lazy" decoding="async"/></div><div class="compactNames-yJrKbP">Rspack Team</div></div></div></a><a href="https://github.com/orgs/web-infra-dev/discussions/17" target="_blank" rel="noopener noreferrer" class="card-tONMLM gridItem-W7_sGP interactiveCard-MMJbVF rp-link" data-tilt-card="true"><span class="date-Td1gj5">2024年4月17日</span><div class="title-zAqg4x">Deep dive into Rspack tree shaking</div><div class="description-WkXUDU clampedDescription-A_BULP"><p class="descriptionParagraph-xUjGh7">本文主要侧重于理解 Rspack 和 webpack 中 tree shaking 的概念。</p></div><div class="footer-vhcqbm"><div class="compactGroup-Ij3Cuk avatarOverride-LGUxCZ" title="Rspack Team"><div class="compactAvatars-K_PsP6" aria-hidden="true"><img src="https://assets.rspack.rs/rspack/rspack-logo-with-background.png" alt="" class="compactAvatar-VpXzKi" loading="lazy" decoding="async"/></div><div class="compactNames-yJrKbP">Rspack Team</div></div></div></a><a href="/zh/blog/announcing-0-6" class="card-tONMLM gridItem-W7_sGP interactiveCard-MMJbVF rp-link" data-tilt-card="true"><span class="date-Td1gj5">2024年4月10日</span><div class="title-zAqg4x">Rspack 0.6 发布公告</div><div class="description-WkXUDU clampedDescription-A_BULP"><p class="descriptionParagraph-xUjGh7">Rspack 0.6 版本发布，内置支持 mini-css-extract-plugin，默认开启新版 tree shaking。</p></div><div class="footer-vhcqbm"><div class="compactGroup-Ij3Cuk avatarOverride-LGUxCZ" title="Rspack Team"><div class="compactAvatars-K_PsP6" aria-hidden="true"><img src="https://assets.rspack.rs/rspack/rspack-logo-with-background.png" alt="" class="compactAvatar-VpXzKi" loading="lazy" decoding="async"/></div><div class="compactNames-yJrKbP">Rspack Team</div></div></div></a><a href="https://github.com/orgs/web-infra-dev/discussions/16" target="_blank" rel="noopener noreferrer" class="card-tONMLM gridItem-W7_sGP interactiveCard-MMJbVF rp-link" data-tilt-card="true"><span class="date-Td1gj5">2024年1月12日</span><div class="title-zAqg4x">Webpack chunk graph 策略</div><div class="description-WkXUDU clampedDescription-A_BULP"><p class="descriptionParagraph-xUjGh7">本文介绍了 webpack 的 chunk 策略，通过这篇文章，你可以理解代码中什么时候会产生 chunk，怎样减少 chunk 体积等。</p></div><div class="footer-vhcqbm"><div class="compactGroup-Ij3Cuk avatarOverride-LGUxCZ" title="Rspack Team"><div class="compactAvatars-K_PsP6" aria-hidden="true"><img src="https://assets.rspack.rs/rspack/rspack-logo-with-background.png" alt="" class="compactAvatar-VpXzKi" loading="lazy" decoding="async"/></div><div class="compactNames-yJrKbP">Rspack Team</div></div></div></a><a href="/zh/blog/announcing-0-5" class="card-tONMLM gridItem-W7_sGP interactiveCard-MMJbVF rp-link" data-tilt-card="true"><span class="date-Td1gj5">2024年1月9日</span><div class="title-zAqg4x">Rspack 0.5 发布公告</div><div class="description-WkXUDU clampedDescription-A_BULP"><p class="descriptionParagraph-xUjGh7">Rspack 0.5 版本发布，支持模块联邦，移除默认的 SWC 转换。</p></div><div class="footer-vhcqbm"><div class="compactGroup-Ij3Cuk avatarOverride-LGUxCZ" title="Rspack Team"><div class="compactAvatars-K_PsP6" aria-hidden="true"><img src="https://assets.rspack.rs/rspack/rspack-logo-with-background.png" alt="" class="compactAvatar-VpXzKi" loading="lazy" decoding="async"/></div><div class="compactNames-yJrKbP">Rspack Team</div></div></div></a><a href="/zh/blog/module-federation-added-to-rspack" class="card-tONMLM gridItem-W7_sGP interactiveCard-MMJbVF rp-link" data-tilt-card="true"><span class="date-Td1gj5">2024年1月9日</span><div class="title-zAqg4x">Rspack 支持模块联邦</div><div class="description-WkXUDU clampedDescription-A_BULP"><p class="descriptionParagraph-xUjGh7">最新的 Rspack 0.5.0 引入了备受期待的模块联邦功能，本文对其进行了详细介绍。</p></div><div class="footer-vhcqbm"><div class="compactGroup-Ij3Cuk avatarOverride-LGUxCZ" title="Rspack Team"><div class="compactAvatars-K_PsP6" aria-hidden="true"><img src="https://assets.rspack.rs/rspack/rspack-logo-with-background.png" alt="" class="compactAvatar-VpXzKi" loading="lazy" decoding="async"/></div><div class="compactNames-yJrKbP">Rspack Team</div></div></div></a><a href="https://github.com/orgs/web-infra-dev/discussions/13" target="_blank" rel="noopener noreferrer" class="card-tONMLM gridItem-W7_sGP interactiveCard-MMJbVF rp-link" data-tilt-card="true"><span class="date-Td1gj5">2023年11月29日</span><div class="title-zAqg4x">Webpack CSS 顺序问题</div><div class="description-WkXUDU clampedDescription-A_BULP"><p class="descriptionParagraph-xUjGh7">本文介绍了 webpack 中 CSS 顺序问题是怎样产生的，以及如何解决。</p></div><div class="footer-vhcqbm"><div class="compactGroup-Ij3Cuk avatarOverride-LGUxCZ" title="Rspack Team"><div class="compactAvatars-K_PsP6" aria-hidden="true"><img src="https://assets.rspack.rs/rspack/rspack-logo-with-background.png" alt="" class="compactAvatar-VpXzKi" loading="lazy" decoding="async"/></div><div class="compactNames-yJrKbP">Rspack Team</div></div></div></a><a href="/zh/blog/announcing-0-4" class="card-tONMLM gridItem-W7_sGP interactiveCard-MMJbVF rp-link" data-tilt-card="true"><span class="date-Td1gj5">2023年11月22日</span><div class="title-zAqg4x">Rspack 0.4 发布公告</div><div class="description-WkXUDU clampedDescription-A_BULP"><p class="descriptionParagraph-xUjGh7">Rspack 0.4 版本发布，移除对一些内置功能的支持。</p></div><div class="footer-vhcqbm"><div class="compactGroup-Ij3Cuk avatarOverride-LGUxCZ" title="Rspack Team"><div class="compactAvatars-K_PsP6" aria-hidden="true"><img src="https://assets.rspack.rs/rspack/rspack-logo-with-background.png" alt="" class="compactAvatar-VpXzKi" loading="lazy" decoding="async"/></div><div class="compactNames-yJrKbP">Rspack Team</div></div></div></a><a href="https://github.com/orgs/web-infra-dev/discussions/10" target="_blank" rel="noopener noreferrer" class="card-tONMLM gridItem-W7_sGP interactiveCard-MMJbVF rp-link" data-tilt-card="true"><span class="date-Td1gj5">2023年10月26日</span><div class="title-zAqg4x">深入了解 Top-level await</div><div class="description-WkXUDU clampedDescription-A_BULP"><p class="descriptionParagraph-xUjGh7">在本文中，我们将对 Top-level await 的 specification、toolchain support、webpack runtime、profiling 等方面进行深入的分析。</p></div><div class="footer-vhcqbm"><div class="compactGroup-Ij3Cuk avatarOverride-LGUxCZ" title="Rspack Team"><div class="compactAvatars-K_PsP6" aria-hidden="true"><img src="https://assets.rspack.rs/rspack/rspack-logo-with-background.png" alt="" class="compactAvatar-VpXzKi" loading="lazy" decoding="async"/></div><div class="compactNames-yJrKbP">Rspack Team</div></div></div></a><a href="https://github.com/orgs/web-infra-dev/discussions/4" target="_blank" rel="noopener noreferrer" class="card-tONMLM gridItem-W7_sGP interactiveCard-MMJbVF rp-link" data-tilt-card="true"><span class="date-Td1gj5">2023年8月30日</span><div class="title-zAqg4x">Bundler 的设计取舍</div><div class="description-WkXUDU clampedDescription-A_BULP"><p class="descriptionParagraph-xUjGh7">本文介绍了我们为什么要开发 Rspack，设计过程中进行了哪些取舍。</p></div><div class="footer-vhcqbm"><div class="compactGroup-Ij3Cuk avatarOverride-LGUxCZ" title="Rspack Team"><div class="compactAvatars-K_PsP6" aria-hidden="true"><img src="https://assets.rspack.rs/rspack/rspack-logo-with-background.png" alt="" class="compactAvatar-VpXzKi" loading="lazy" decoding="async"/></div><div class="compactNames-yJrKbP">Rspack Team</div></div></div></a><a href="/zh/blog/announcing-0-3" class="card-tONMLM gridItem-W7_sGP interactiveCard-MMJbVF rp-link" data-tilt-card="true"><span class="date-Td1gj5">2023年8月24日</span><div class="title-zAqg4x">Rspack 0.3 发布公告</div><div class="description-WkXUDU clampedDescription-A_BULP"><p class="descriptionParagraph-xUjGh7">Rspack 0.3 版本发布，新增 web workers、builtin:swc-loader 支持。</p></div><div class="footer-vhcqbm"><div class="compactGroup-Ij3Cuk avatarOverride-LGUxCZ" title="Rspack Team"><div class="compactAvatars-K_PsP6" aria-hidden="true"><img src="https://assets.rspack.rs/rspack/rspack-logo-with-background.png" alt="" class="compactAvatar-VpXzKi" loading="lazy" decoding="async"/></div><div class="compactNames-yJrKbP">Rspack Team</div></div></div></a><a href="/zh/blog/announcing-0-2" class="card-tONMLM gridItem-W7_sGP interactiveCard-MMJbVF rp-link" data-tilt-card="true"><span class="date-Td1gj5">2023年6月2日</span><div class="title-zAqg4x">Rspack 0.2 发布公告</div><div class="description-WkXUDU clampedDescription-A_BULP"><p class="descriptionParagraph-xUjGh7">Rspack 0.2 版本发布，新增了诸多功能，如 realContentHash、DataURI、ESM format 的支持等。</p></div><div class="footer-vhcqbm"><div class="compactGroup-Ij3Cuk avatarOverride-LGUxCZ" title="Rspack Team"><div class="compactAvatars-K_PsP6" aria-hidden="true"><img src="https://assets.rspack.rs/rspack/rspack-logo-with-background.png" alt="" class="compactAvatar-VpXzKi" loading="lazy" decoding="async"/></div><div class="compactNames-yJrKbP">Rspack Team</div></div></div></a><a href="/zh/blog/announcing-0-1" class="card-tONMLM gridItem-W7_sGP interactiveCard-MMJbVF rp-link" data-tilt-card="true"><span class="date-Td1gj5">2023年3月6日</span><div class="title-zAqg4x">Rspack 正式发布了</div><div class="description-WkXUDU clampedDescription-A_BULP"><p class="descriptionParagraph-xUjGh7">Rspack 正式发布了！</p></div><div class="footer-vhcqbm"><div class="compactGroup-Ij3Cuk avatarOverride-LGUxCZ" title="Rspack Team"><div class="compactAvatars-K_PsP6" aria-hidden="true"><img src="https://assets.rspack.rs/rspack/rspack-logo-with-background.png" alt="" class="compactAvatar-VpXzKi" loading="lazy" decoding="async"/></div><div class="compactNames-yJrKbP">Rspack Team</div></div></div></a></section><style>
      .rp-doc > h1 { font-weight: 700; }
      .rp-doc > p { color: var(--rs-blog-list-desc-color); }
      .rp-doc-layout__sidebar-placeholder { display: none; }
      .rp-doc-layout__outline { display: none; }
      .rp-doc-layout__doc { width: 100% !important; max-width: 100% !important; }
      .rp-doc-layout__doc-container { margin: 0 auto; }
      </style></div><div class="blogBackground-ESH_4Z"><div class="glowBackground-Pe6ULN"></div><div class="blogFrame-_M1lGW"></div><canvas style="position:absolute;top:0;left:0;width:100%;height:65vh;z-index:-1;filter:blur(.5px);opacity:0.8"></canvas></div><!--/$-->]]></content:encoded>
        </item>
    </channel>
</rss>