Menu

Next.js コンパイラ

Next.js コンパイラは、SWC を使用して Rust で記述され、本番環境用の 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 に切り替えることで、Fast Refresh で約 3 倍、ビルドで約 5 倍高速化を実現しました。さらなる最適化の余地もあります。
  • WebAssembly: Rust の WASM サポートは、すべての可能なプラットフォームをサポートし、Next.js の開発をあらゆる場所に展開するために不可欠です。
  • コミュニティ: Rust のコミュニティとエコシステムは素晴らしく、成長し続けています。

サポートされている機能

スタイル付きコンポーネント

babel-plugin-styled-components を Next.js コンパイラに移植する作業を進めています。

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

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

高度なユースケースでは、スタイル付きコンポーネントのコンパイル用に個々のプロパティを設定できます。

注意: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[],
      // デフォルトで有効。
      minify?: boolean,
      // デフォルトで有効。
      transpileTemplateLiterals?: boolean,
      // デフォルトは空。
      namespace?: string,
      // デフォルトで無効。
      pure?: boolean,
      // デフォルトで有効。
      cssProp?: boolean,
    },
  },
}

Jest

Next.js コンパイラはテストをトランスパイルし、Next.js との Jest の設定を簡素化します:

  • .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')
 
// next.config.js と .env ファイルを読み込むための Next.js アプリへのパスを提供
const createJestConfig = nextJest({ dir: './' })
 
// 任意のカスタム Jest 設定
const customJestConfig = {
  setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
}
 
// 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$'] },
  },
}

コンソールの削除

この変換により、(node_modules ではなく)アプリケーションコードのすべての console.* 呼び出しを削除できます。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.jsonexperimentalDecorators を自動的に検出します。レガシーデコレータは、mobx のような古いバージョンのライブラリでよく使用されます。

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

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

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

importSource

Next.js は jsconfig.json または tsconfig.jsonjsxImportSource を自動的に検出し、それを適用します。これは 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 | {
      // デフォルトは 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],
          }
        }
      },
    },
  },
}

ミニファイケーション

Next.jsのswcコンパイラは、v13から標準でミニファイケーションに使用されています。これはTerserと比較して7倍高速です。

何らかの理由でTerserが必要な場合は、以下のように設定できます。

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

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

Next.jsは、ローカルパッケージ(モノレポなど)や外部の依存関係(node_modules)から、依存関係を自動的にトランスパイルしてバンドルできます。これはnext-transpile-modulesパッケージに代わるものです。

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

インポートのモジュール化

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

実験的機能

SWCトレースプロファイリング

Chromiumのトレースイベント形式でSWCの内部変換トレースを生成できます。

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プラグイン(実験的)

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 Properties削除、レガシーデコレータ、Consoleの削除、jsxImportSourceのサポートが追加。
v12.0.0Next.jsコンパイラが導入