コンテンツへスキップ
はじめにアーキテクチャNext.js コンパイラ

Next.js コンパイラ

Next.js コンパイラは、Rust で書かれた SWC を使用しており、Next.js で JavaScript コードを本番用に変換およびミニファイすることができます。これにより、個々のファイルの Babel と出力バンドルのミニファイの Terser が置き換えられます。

Next.js コンパイラを使ったコンパイルは Babel より17倍高速で、Next.js バージョン12以降ではデフォルトで有効になっています。既存の Babel 設定を使用している場合、または未対応の機能を使用している場合、アプリケーションは Next.js コンパイラの利用を停止し、引き続き Babel を使用します。

なぜSWCなのか?

SWC は、次世代の高速開発ツール向けに拡張可能な Rust ベースのプラットフォームです。

SWC は、コンパイル、ミニファイ、バンドルなどに使用でき、拡張できるように設計されています。コード変換(組み込みまたはカスタム)を実行するために呼び出すことができます。これらの変換は、Next.js のような高レベルのツールを通じて行われます。

SWC をベースに構築することを選択した理由はいくつかあります。

  • 拡張性: SWC は Next.js 内部で Crate として使用でき、ライブラリをフォークしたり設計上の制約を回避したりする必要がありません。
  • パフォーマンス: SWC に切り替えることで、Next.js で Fast Refresh が約3倍、ビルドが約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 のコンパイル個々のプロパティを設定できます。

注: ssrdisplayName の変換は、Next.js で styled-components を使用するための主要な要件です。

next.config.js
module.exports = {
  compiler: {
    // see https://styled-components.dokyumento.jp/docs/tooling#babel-plugin for more info on the options.
    styledComponents: {
      // Enabled by default in development, disabled in production to reduce file size,
      // setting this will override the default for all environments.
      displayName?: boolean,
      // Enabled by default.
      ssr?: boolean,
      // Enabled by default.
      fileName?: boolean,
      // Empty by default.
      topLevelImportPaths?: string[],
      // Defaults to ["index"].
      meaninglessFileNames?: string[],
      // Enabled by default.
      minify?: boolean,
      // Enabled by default.
      transpileTemplateLiterals?: boolean,
      // Empty by default.
      namespace?: string,
      // Disabled by default.
      pure?: boolean,
      // Enabled by default.
      cssProp?: boolean,
    },
  },
}

Jest

Next.js コンパイラはテストをトランスパイルし、Jest を Next.js と連携して設定するのを簡素化します。これには以下が含まれます。

  • .css.module.css(およびその .scss バリアント)、画像インポートの自動モック
  • SWC を使用して transform を自動的に設定
  • .env(およびすべてのバリアント)を process.env にロード
  • テスト解決および変換から node_modules を無視
  • テスト解決から .next を無視
  • 実験的な SWC 変換を有効にするフラグのために next.config.js をロード

まず、Next.js を最新バージョンに更新します: npm install next@latest。次に、jest.config.js ファイルを更新します。

jest.config.js
const nextJest = require('next/jest')
 
// Providing the path to your Next.js app which will enable loading next.config.js and .env files
const createJestConfig = nextJest({ dir: './' })
 
// Any custom config you want to pass to Jest
const customJestConfig = {
  setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
}
 
// createJestConfig is exported in this way to ensure that next/jest can load the Next.js configuration, which is async
module.exports = createJestConfig(customJestConfig)

Relay

Relay のサポートを有効にするには

next.config.js
module.exports = {
  compiler: {
    relay: {
      // This should match 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: {
    // The regexes defined here are processed in Rust so the syntax is different from
    // JavaScript `RegExp`s. See https://docs.rs/regex.
    reactRemoveProperties: { properties: ['^data-custom$'] },
  },
}

コンソールの削除

この変換により、アプリケーションコード内のすべての console.* 呼び出し(node_modules は除く)を削除できます。babel-plugin-transform-remove-console と同様です。

すべての console.* 呼び出しを削除

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

console.error を除く console.* 出力を削除

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

レガシーデコレータ

Next.js は jsconfig.json または tsconfig.json 内の experimentalDecorators を自動的に検出します。レガシーデコレータは、mobx などの古いライブラリのバージョンでよく使用されます。

このフラグは、既存のアプリケーションとの互換性のためにのみサポートされています。新しいアプリケーションではレガシーデコレータの使用を推奨しません。

まず、Next.js を最新バージョンに更新します: npm install next@latest。次に、jsconfig.json または tsconfig.json ファイルを更新します。

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

importSource

Next.js は jsconfig.json または tsconfig.json 内の jsxImportSource を自動的に検出して適用します。これは Theme UI のようなライブラリでよく使用されます。

まず、Next.js を最新バージョンに更新します: npm install next@latest。次に、jsconfig.json または tsconfig.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 | {
      // default is true. It will be disabled when build type is production.
      sourceMap?: boolean,
      // default is 'dev-only'.
      autoLabel?: 'never' | 'dev-only' | 'always',
      // default is '[local]'.
      // Allowed values: `[local]` `[filename]` and `[dirname]`
      // This option only works when autoLabel is set to 'dev-only' or 'always'.
      // It allows you to define the format of the resulting label.
      // The format is defined via string where variable parts are enclosed in square brackets [].
      // For example labelFormat: "my-classname--[local]", where [local] will be replaced with the name of the variable the result is assigned to.
      labelFormat?: string,
      // default is undefined.
      // This option allows you to tell the compiler what imports it should
      // look at to determine what it should transform so if you re-export
      // Emotion's exports, you can still use transforms.
      importMap?: {
        [packageName: string]: {
          [exportName: string]: {
            canonicalImport?: [string, string],
            styledBaseImport?: [string, string],
          }
        }
      },
    },
  },
}

ミニファイ

Next.js の SWC コンパイラは、v13 以降でデフォルトでミニファイに使用されます。これは Terser より7倍高速です。

補足: v15 以降、ミニファイは next.config.js を使用してカスタマイズできません。swcMinify フラグのサポートは削除されました。

モジュールトランスパイル

Next.js は、ローカルパッケージ(モノレポなど)または外部依存関係(node_modules)からの依存関係を自動的にトランスパイルおよびバンドルできます。これにより、next-transpile-modules パッケージが置き換えられます。

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

モジュール化されたインポート

このオプションは Next.js 13.5 で optimizePackageImports に置き換えられました。インポートパスの手動設定が不要な新しいオプションを使用するためにアップグレードすることをお勧めします。

Define (ビルド時の変数置換)

define オプションを使用すると、ビルド時にコード内の変数を静的に置換できます。このオプションはキーと値のペアとしてオブジェクトを受け取り、キーは対応する値で置換されるべき変数です。

next.config.jscompiler.define フィールドを使用します。

next.config.js
module.exports = {
  compiler: {
    define: {
      MY_STRING_VARIABLE: JSON.stringify('my-string'),
      MY_NUMBER_VARIABLE: '42',
    },
  },
}

実験的機能

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 の変換を設定して、wasm で書かれた SWC の実験的なプラグインサポートを使用し、変換動作をカスタマイズできます。

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

swcPlugins はプラグインを設定するためのタプルの配列を受け入れます。プラグインのタプルには、プラグインへのパスとプラグイン設定用のオブジェクトが含まれます。プラグインへのパスは、npm モジュールパッケージ名または .wasm バイナリ自体への絶対パスです。

未対応機能

アプリケーションに .babelrc ファイルがある場合、Next.js は個々のファイルの変換に自動的に Babel にフォールバックします。これにより、カスタム Babel プラグインを活用している既存のアプリケーションとの後方互換性が保証されます。

カスタム Babel セットアップを使用している場合は、設定を共有してください。今後、よく使われる Babel 変換をできるだけ多く移植し、プラグインもサポートできるよう取り組んでいます。

バージョン履歴

バージョン変更点
v13.1.0モジュールトランスパイルモジュール化されたインポート が安定版に。
v13.0.0SWC ミニファイアがデフォルトで有効に。
v12.3.0SWC ミニファイアが安定版に。
v12.2.0SWC プラグインの実験的サポートを追加。
v12.1.0Styled Components、Jest、Relay、React プロパティの削除、レガシーデコレータ、コンソールの削除、jsxImportSource のサポートを追加。
v12.0.0Next.js コンパイラが導入されました。