Menu

Next.js Compiler

Next.js CompilerはSWCを使用してRustで記述されており、Next.jsが本番環境用のJavaScriptコードを変換・最小化することを可能にします。これにより、個別ファイルのBabelと出力バンドルの最小化のためのTerserが置き換わります。

Next.js Compilerを使用したコンパイルはBabelより17倍高速であり、Next.jsバージョン12以降デフォルトで有効になっています。既存のBabel設定がある場合、またはサポートされていない機能を使用している場合、アプリケーションはNext.js Compilerをオプトアウトし、引き続きBabelを使用します。

なぜSWCなのか?

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

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

SWCの上で構築することを選択した理由はいくつかあります:

  • 拡張性: SWCはNext.js内でCrateとして使用でき、ライブラリをフォークしたり設計上の制約を回避したりする必要がありません。
  • パフォーマンス: SWCに切り替えることで、Next.jsで約3倍高速なFast Refreshと約5倍高速なビルドを実現でき、さらに最適化の余地があります。
  • WebAssembly: RustのWASMサポートは、すべての可能なプラットフォームをサポートし、Next.js開発をあらゆる場所に展開するために不可欠です。
  • コミュニティ: Rustコミュニティとエコシステムは素晴らしく、まだ成長し続けています。

サポートされている機能

Styled Components

babel-plugin-styled-componentsをNext.js Compilerに移植するための作業を進めています。

まず、最新版のNext.jsに更新してください:npm install next@latest。その後、next.config.jsファイルを更新してください:

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

高度な使用例では、styled-componentsコンパイルの個別プロパティを設定できます。

注意:ssrおよびdisplayNameトランスフォームは、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 Compilerはテストをトランスパイルし、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.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.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 Compilerに移植するための作業を進めています。

まず、最新版の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,
      // デフォルトは未定義です。
      // このオプションを使用すると、何を変換すべきかを判定するために
      // コンパイラが何をチェックすべきかを指定できます。
      // Emotionのエクスポートを再エクスポートする場合、引き続き変換を使用できます。
      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フィールドを使用して、すべての環境(サーバー、エッジ、クライアント)の変数を定義するか、compiler.defineServerを使用してサーバー側(サーバーとエッジ)コードの変数のみを定義します:

next.config.js
module.exports = {
  compiler: {
    define: {
      MY_VARIABLE: 'my-string',
      'process.env.MY_ENV_VAR': 'my-env-var',
    },
    defineServer: {
      MY_SERVER_VARIABLE: 'my-server-var',
    },
  },
}

ビルドライフサイクルフック

Next.js Compilerはビルドプロセス中の特定のポイントでカスタムコードを実行できるライフサイクルフックをサポートしています。現在、以下のフックがサポートされています:

runAfterProductionCompile

本番ビルドコンパイルの完了後、型チェックと静的ページ生成などのコンパイル後のタスクを実行する前に実行されるフック関数。このフックはプロジェクトディレクトリとビルド出力ディレクトリを含むプロジェクトメタデータにアクセスでき、サードパーティツールがソースマップなどのビルド出力を収集するのに役立ちます。

next.config.js
module.exports = {
  compiler: {
    runAfterProductionCompile: async ({ distDir, projectDir }) => {
      // カスタムコードはここに
    },
  },
}

フックは以下のプロパティを持つオブジェクトを受け取ります:

  • distDir:ビルド出力ディレクトリ(デフォルトは.next
  • projectDir:プロジェクトのルートディレクトリ

実験的機能

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プロパティの削除、レガシーデコレータ、Consoleの削除、jsxImportSourceのサポートを追加。
v12.0.0Next.js Compiler導入時期:v12