Next.js 編譯器

Next.js 編譯器使用 SWC 並以 Rust 編寫,能為生產環境轉換和壓縮您的 JavaScript 程式碼。這取代了 Babel 處理單一檔案和 Terser 壓縮輸出套件的功能。

自 Next.js 12 版起預設啟用此編譯器,其速度比 Babel 快 17 倍。若您現有 Babel 配置或使用不支援的功能,應用程式將自動切回使用 Babel 而非 Next.js 編譯器。

為何選擇 SWC?

SWC 是一個基於 Rust 的可擴展平台,專為新一代高效開發工具而設計。

SWC 可用於編譯、壓縮、打包等用途,並設計為可擴展。您可呼叫它來執行程式碼轉換(內建或自訂)。這些轉換透過如 Next.js 等高階工具執行。

我們選擇基於 SWC 開發的原因如下:

  • 可擴展性:SWC 可作為 Crate 在 Next.js 內部使用,無需分叉函式庫或繞過設計限制。
  • 效能:轉用 SWC 後,我們在 Next.js 中實現了約 3 倍快的快速刷新 (Fast Refresh) 和約 5 倍快的建置速度,且仍有優化空間。
  • WebAssembly:Rust 對 WASM 的支援對兼容所有平台和擴展 Next.js 開發至關重要。
  • 社群:Rust 社群和生態系統非常出色且持續成長。

支援的功能

Styled Components

我們正將 babel-plugin-styled-components 移植到 Next.js 編譯器。

首先更新至最新版 Next.js:npm install next@latest。然後更新 next.config.js 檔案:

next.config.js
module.exports = {
  compiler: {
    styledComponents: true,
  },
}

進階使用情境下,您可為 styled-components 編譯配置個別屬性。

注意:minifytranspileTemplateLiteralspure 尚未實作。您可在此追蹤進度ssrdisplayName 轉換是在 Next.js 中使用 styled-components 的主要需求。

next.config.js
module.exports = {
  compiler: {
    // 詳見 https://styled-components.com/docs/tooling#babel-plugin 取得選項更多資訊。
    styledComponents: {
      // 開發環境預設啟用,生產環境預設停用以減少檔案大小,
      // 設定此值將覆蓋所有環境的預設值。
      displayName?: boolean,
      // 預設啟用。
      ssr?: boolean,
      // 預設啟用。
      fileName?: boolean,
      // 預設為空。
      topLevelImportPaths?: string[],
      // 預設為 ["index"]。
      meaninglessFileNames?: string[],
      // 預設啟用。
      cssProp?: boolean,
      // 預設為空。
      namespace?: string,
      // 尚未支援。
      minify?: boolean,
      // 尚未支援。
      transpileTemplateLiterals?: boolean,
      // 尚未支援。
      pure?: boolean,
    },
  },
}

Jest

Next.js 編譯器會轉譯您的測試,並簡化與 Next.js 一起配置 Jest 的流程,包括:

  • 自動模擬 .css.module.css(及其 .scss 變體)和圖片匯入
  • 使用 SWC 自動設定 transform
  • .env(及其所有變體)載入 process.env
  • 從測試解析和轉換中忽略 node_modules
  • 從測試解析中忽略 .next
  • 載入 next.config.js 以啟用實驗性 SWC 轉換標誌

首先更新至最新版 Next.js:npm install next@latest。然後更新 jest.config.js 檔案:

jest.config.js
const nextJest = require('next/jest')

// 提供 Next.js 應用路徑以載入 next.config.js 和 .env 檔案
const createJestConfig = nextJest({ dir: './' })

// 您想傳遞給 Jest 的任何自訂配置
const customJestConfig = {
  setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
}

// 以這種方式匯出 createJestConfig 以確保 next/jest 能非同步載入 Next.js 配置
module.exports = createJestConfig(customJestConfig)

Relay

啟用 Relay 支援:

next.config.js
module.exports = {
  compiler: {
    relay: {
      // 這應與 relay.config.js 相符
      src: './',
      artifactDirectory: './__generated__',
      language: 'typescript',
      eagerEsModules: false,
    },
  },
}

須知:在 Next.js 中,pages 目錄下的所有 JavaScript 檔案均視為路由。因此,relay-compiler 需指定 artifactDirectory 配置在 pages 之外,否則 relay-compiler 會在 __generated__ 目錄中生成檔案,這些檔案將被視為路由,導致生產建置失敗。

移除 React 屬性

允許移除 JSX 屬性。常用於測試。類似於 babel-plugin-react-remove-properties

移除符合預設正則式 ^data-test 的屬性:

next.config.js
module.exports = {
  compiler: {
    reactRemoveProperties: true,
  },
}

移除自訂屬性:

next.config.js
module.exports = {
  compiler: {
    // 此處定義的正則式在 Rust 中處理,因此語法與 JavaScript `RegExp` 不同。詳見 https://docs.rs/regex。
    reactRemoveProperties: { properties: ['^data-custom$'] },
  },
}

移除 Console

此轉換允許移除應用程式碼(非 node_modules)中的所有 console.* 呼叫。類似於 babel-plugin-transform-remove-console

移除所有 console.* 呼叫:

next.config.js
module.exports = {
  compiler: {
    removeConsole: true,
  },
}

移除 console.* 輸出,但保留 console.error

next.config.js
module.exports = {
  compiler: {
    removeConsole: {
      exclude: ['error'],
    },
  },
}

舊版裝飾器

Next.js 會自動偵測 jsconfig.jsontsconfig.json 中的 experimentalDecorators。舊版裝飾器常用於如 mobx 等舊版函式庫。

此標誌僅為兼容現有應用程式而支援。我們不建議在新應用程式中使用舊版裝飾器。

首先更新至最新版 Next.js:npm install next@latest。然後更新 jsconfig.jsontsconfig.json 檔案:

{
  "compilerOptions": {
    "experimentalDecorators": true
  }
}

importSource

Next.js 會自動偵測 jsconfig.jsontsconfig.json 中的 jsxImportSource 並套用。這常用於如 Theme UI 等函式庫。

首先更新至最新版 Next.js:npm install next@latest。然後更新 jsconfig.jsontsconfig.json 檔案:

{
  "compilerOptions": {
    "jsxImportSource": "theme-ui"
  }
}

Emotion

我們正將 @emotion/babel-plugin 移植到 Next.js 編譯器。

首先更新至最新版 Next.js:npm install next@latest。然後更新 next.config.js 檔案:

next.config.js

module.exports = {
  compiler: {
    emotion: boolean | {
      // 預設為 true。建置類型為生產環境時將停用。
      sourceMap?: boolean,
      // 預設為 'dev-only'。
      autoLabel?: 'never' | 'dev-only' | 'always',
      // 預設為 '[local]'。
      // 允許值:`[local]` `[filename]` 和 `[dirname]`
      // 此選項僅在 autoLabel 設為 'dev-only' 或 'always' 時有效。
      // 它允許您定義結果標籤的格式。
      // 格式透過字串定義,變數部分用方括號 [] 包圍。
      // 例如 labelFormat: "my-classname--[local]",其中 [local] 將替換為結果賦予的變數名稱。
      labelFormat?: string,
      // 預設為 undefined。
      // 此選項允許您告訴編譯器應查看哪些匯入以確定需轉換的內容,
      // 因此如果您重新匯出 Emotion 的匯出,仍可使用轉換。
      importMap?: {
        [packageName: string]: {
          [exportName: string]: {
            canonicalImport?: [string, string],
            styledBaseImport?: [string, string],
          }
        }
      },
    },
  },
}

壓縮

自 v13 起,Next.js 預設使用 swc 編譯器進行壓縮。這比 Terser 快 7 倍。

若仍需使用 Terser,可進行配置。

next.config.js
module.exports = {
  swcMinify: false,
}

模組轉譯

Next.js 可自動轉譯和打包來自本地套件(如 monorepos)或外部依賴(node_modules)的依賴項。這取代了 next-transpile-modules 套件。

next.config.js
module.exports = {
  transpilePackages: ['@acme/ui', 'lodash-es'],
}

模組化匯入

此選項已在 Next.js 13.5 中被 optimizePackageImports 取代。建議升級使用無需手動配置匯入路徑的新選項。

實驗性功能

SWC 追蹤分析

您可以生成 SWC 內部轉換追蹤,格式為 chromium 的追蹤事件格式

next.config.js
module.exports = {
  experimental: {
    swcTraceProfiling: true,
  },
}

啟用後,swc 將在 .next/ 下生成名為 swc-trace-profile-${timestamp}.json 的追蹤檔案。Chromium 的追蹤檢視器(chrome://tracing/、https://ui.perfetto.dev/)或兼容的火焰圖檢視器(https://www.speedscope.app/)可載入並視覺化生成的追蹤。

SWC 插件(實驗性)

您可以配置 swc 的轉換以使用 SWC 的實驗性 wasm 插件支援,自訂轉換行為。

next.config.js
module.exports = {
  experimental: {
    swcPlugins: [
      [
        'plugin',
        {
          ...pluginOptions,
        },
      ],
    ],
  },
}

swcPlugins 接受一個元組陣列來配置插件。插件元組包含插件路徑和插件配置物件。插件路徑可以是 npm 模組套件名稱或 .wasm 二進位檔案的絕對路徑。

不支援的功能

當應用程式擁有 .babelrc 檔案時,Next.js 將自動回退使用 Babel 轉換單一檔案。這確保了與使用自訂 Babel 插件的現有應用程式向後兼容。

若您使用自訂 Babel 設定,請分享您的配置。我們正致力移植盡可能多常用的 Babel 轉換,並在未來支援插件。

版本歷史

版本變更
v13.1.0模組轉譯模組化匯入 穩定。
v13.0.0預設啟用 SWC 壓縮器。
v12.3.0SWC 壓縮器穩定
v12.2.0新增 SWC 插件 實驗性支援。
v12.1.0新增對 Styled Components、Jest、Relay、移除 React 屬性、舊版裝飾器、移除 Console 和 jsxImportSource 的支援。
v12.0.0Next.js 編譯器推出

On this page