Rspack 0.5 版本發佈

2024 年 1 月 9 日

主要功能更新

Rspack 新增模組聯邦 (Module Federation)

請查看這篇部落格以了解更多細節。

重大變更

預設情況下,在生產模式中,optimization.chunkIds 是確定性的

在生產模式下,optimization.chunkIds 現在預設為 "deterministic",這與 webpack 的預設行為一致。

支援 rspack.HotModuleReplacementPlugin

在 Rspack 中支援 rspack.HotModuleReplacementPlugin。如果您沒有使用 @rspack/dev-server 且使用自訂開發伺服器,您需要套用 HotModuleReplacementPlugin 來啟用 HMR,而不是將 devServer.hot 設定為 true,這與 webpack 中的相同。這提供了與內部使用 HotModuleReplacementPlugin 的外掛程式更好的相容性。

移除預設轉換

預設轉換是一個內建功能,它會在內部將原始檔案(例如 TypeScript)轉換為相容的來源(例如 JavaScript)。為了使轉換更具可自訂性,我們將此功能交給使用者,透過使用 builtin:swc-loader,並捨棄對數個rule.type 的支援。以下 rule.type 已捨棄

  • "typescript""ts"
  • "tsx"
  • "jsx"

為了實現舊的行為,請移除 rule.type 或將其變更為 "javascript/auto" 並套用您的自訂載入器設定。

轉換 .jsx 檔案

module.exports = {
  module: {
    rules: [
      {
        test: /\.jsx$/,
        exclude: /[\\/]node_modules[\\/]/,
        loader: 'builtin:swc-loader',
        options: {
          jsc: {
            parser: {
              syntax: 'ecmascript',
              jsx: true,
            },
          },
        },
      },
    ],
  },
};

轉換 .tsx 檔案

module.exports = {
  module: {
    rules: [
      {
        test: /\.tsx$/,
        exclude: /[\\/]node_modules[\\/]/,
        loader: 'builtin:swc-loader',
        options: {
          jsc: {
            parser: {
              syntax: 'typescript',
              tsx: true,
            },
          },
        },
      },
    ],
  },
};

轉換 .ts 檔案

module.exports = {
  module: {
    rules: [
      {
        test: /\.ts$/,
        exclude: /[\\/]node_modules[\\/]/,
        loader: 'builtin:swc-loader',
        options: {
          jsc: {
            parser: {
              syntax: 'typescript',
            },
          },
        },
      },
    ],
  },
};

target 不再影響使用者程式碼

Rspack 將 target 與 webpack 對齊。Rspack 現在不再轉換任意的使用者程式碼,而是讓載入器控制使用者程式碼的轉換。若要將使用者程式碼轉換為您的目標環境所需的程式碼,請將 env 新增至 builtin:swc-loader

module.exports = {
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /[\\/]node_modules[\\/]/,
        loader: "builtin:swc-loader",
        options: {
          jsc: {
            parser: {
              syntax: "ecmascript"
            }
          },
+         env: {
+           targets: "Chrome >= 48"
+         }
        }
      }
    ]
  }
}

移除擴充的解析擴展名

resolve.extensions 有助於我們在解析期間省略某些檔案擴展名。在先前的版本中,支援 .ts.tsx.jsx,這些擴展名在最新版本中已移除,這與 webpack 的行為一致。

為了獲得相同的行為,請將 resolve.extensions 變更為以下內容

module.exports = {
  resolve: {
    extensions: ['...', '.tsx', '.ts', '.jsx'], // "..." means to extend from the default extensions
  },
};

將 @swc/helpers 和 react-refresh 作為對等相依性

在我們移除預設轉換之前,可以使用它透過 target 將您的程式碼降級為 es5,並透過 builtin.react.refresh 將 react refresh 輔助程式碼插入您的 react 元件中,因此我們安裝了 @swc/helpersreact-refresh 作為 @rspack/core 的相依性,以提供開箱即用的體驗。但是,由於我們現在移除了預設轉換,並建議使用 Rsbuild 來獲得開箱即用的體驗,因此 @rspack/core 不再需要安裝 @swc/helpersreact-refresh,我們將它們作為 @rspack/core 的對等相依性。

如果您正在搭配 builtin:swc-loaderswc-loader 使用 externalHelpers: true,現在您需要安裝 @swc/helpers 作為您專案的相依性。如果您正在使用 @rspack/plugin-react-refresh,現在您需要安裝 react-refresh 作為您專案的開發相依性。

移除已棄用的 builtins 選項

自 v0.4.0 以來,某些 builtins 選項已棄用。

如果您仍在使用 builtins.noEmitAssetsbuiltins.devFriendlySplitChunksbuiltins.reactbuiltins.htmlbuiltins.copybuiltins.minifyOptions,請查看將 builtins 選項遷移到 builtins 外掛程式來進行遷移。

如果您仍在使用 builtins.presetEnvbuiltins.decoratorbuiltins.pluginImportbuiltins.emotionbuiltins.relay,請查看此處的遷移指南。

移除 builtin:sass-loader

builtin:sass-loader 自 v0.4.0 以來已棄用。它在 v0.5.0 中已移除。如果您仍在使用它,請遷移到 sass-loader

移除 experiments.incrementalRebuild 選項

experiments.incrementalRebuild 選項自 v0.4.0 以來已棄用。它在 v0.5.0 中已移除。

移除 builtins.devFriendlySplitChunks 和 experiments.newSplitChunks

experiments.newSplitChunksbuiltins.devFriendlySplitChunks 自 v0.4.0 以來已棄用。它在 v0.5.0 中已移除。

移除 experiments.rspackFuture.newResolver 選項

experiments.rspackFuture.newResolver 自 v0.4.0 以來已棄用。它在 v0.5.0 中已移除。

棄用延遲套用 entry

延遲套用 entry 已被 rspackFuture 棄用:experiments.rspackFuture.disableApplyEntryLazily,它在 v0.4.5 中引入,在 v0.5.0 中預設啟用,並將在 v0.6.0 中移除。

experiments.rspackFuture.disableApplyEntryLazilyfalse 時,options.entry 仍然可以在呼叫 rspack(options) 之後進行有效的變更,但是當 true 時則不行,而且它的行為與 webpack5 相同。

此設定在大多數情況下不會影響在 Rspack 中開發應用程式的使用者,但 Rspack 外掛程式或更高階框架的開發人員應注意。

遷移指南

v0.5.0 移除了許多已棄用的功能,除此之外,v0.5.0 還引入了四個重大變更,如果您是使用 Rspack 開發應用程式,則只需要注意其中兩個。因此,如果您已經遷移到 v0.4+ 且沒有棄用警告,則 v0.5.0 很容易遷移,如果您尚未遷移,請查看 v0.4.0 遷移指南

新增 resolve.extensions

這是一個最有可能影響您的重大變更。

在您將 @rspack/core 升級到 v0.5.0 之後,如果您的建置失敗並出現錯誤:Can't resolve './src/foo.tsx'Can't resolve './src/foo.ts'Can't resolve './src/foo.jsx',您需要在您的設定中新增 resolve.extensions = ['...', '.tsx', '.ts', '.jsx']

const configuration = {
  // ...
  resolve: {
+   extensions: ['...', '.tsx', '.ts', '.jsx'],
  },
}

您只需要將需要的擴展名新增到 resolve.extensions。例如,如果您沒有使用任何 .tsx.ts 檔案,僅使用 .js.jsx 檔案,那麼您只需要將 '.jsx' 新增到 resolve.extensions。'.js' 是預設的擴展名之一,所有預設的擴展名(['.js', '.json', '.wasm'])都由 '...' 表示。

安裝 @swc/helpers 或 react-refresh

這是一個最有可能影響您的重大變更。

在您將 @rspack/core 升級到 v0.5.0 之後,如果您的建置失敗並出現錯誤:Failed to resolve @swc/helpers/some-helperFailed to resolve react-refresh/some-module,您需要在您的專案中安裝 @swc/helpersreact-refresh

如果您正在搭配 builtin:swc-loaderswc-loader 使用 externalHelpers: true,現在您需要安裝 @swc/helpers 作為您專案的相依性。

npm
yarn
pnpm
bun
npm install @swc/helpers

如果您正在使用 @rspack/plugin-react-refresh,現在您需要安裝 react-refresh 作為您專案的開發相依性。

npm
yarn
pnpm
bun
npm install react-refresh

套用 rspack.HotModuleReplacementPlugin

如果您正在使用 @rspack/cli、rsbuild 或其他 Rspack 的高階框架來開發應用程式,則無需擔心此問題。高階框架或 CLI 應該會妥善處理。但是,如果您正在使用 @rspack/core 與自訂的開發伺服器(不是 @rspack/dev-serverwebpack-dev-server),或是正在開發自訂的開發伺服器,則需要留意此事項。

在 Rspack 中啟用 HMR 之前,是將 devServer.hot 設定為 true,但現在您需要在自訂的開發伺服器中自行套用 HotModuleReplacementPlugin

class CustomDevServer {
  // ...
  enableHMR(compiler) {
-   compiler.options.devServer ??= {};
-   compiler.options.devServer.hot = true;
+   new compiler.webpack.HotModuleReplacementPlugin().apply(compiler);
  }
}

在 rspack(options) 之後,請勿變更 entry 選項

如果您正在使用 @rspack/cli、rsbuild 或其他 Rspack 的高階框架來開發應用程式,則無需擔心此問題。高階框架或 CLI 應該會妥善處理。但是,如果您正在開發外掛程式或高階框架,則需要留意此事項。

在 Rspack 中預先加入額外的 entry 之前,是將其預先加入到 compiler.options.entry 中,但現在您需要自行套用 EntryPlugin

const rspack = require('@rspack/core');
const compiler = rspack(options);

function prependEntry(compiler, additionalEntry) {
-  for (const key in compiler.options.entry) {
-    compiler.options.entry[key].import = [
-      additionalEntry,
-      ...(compiler.options.entry[key].import || []),
-    ];
-  }
+  new compiler.webpack.EntryPlugin(compiler.context, additionalEntry, {
+    name: undefined, // `name: undefined` to prepend the it to every entry, or add it to a specified entry with specified entry name
+  }).apply(compiler);
}

prependEntry(compiler, 'dev-client.js');