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

Next.js コンパイラ

SWC を使用してRustで記述されたNext.jsコンパイラにより、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内でクレートとして使用できます。
  • パフォーマンス: SWCに切り替えることで、Next.jsの高速リフレッシュが約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のコンパイルに個別のプロパティを設定できます。

注: `ssr`と`displayName`の変換は、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コンパイラは、テストをトランスパイルし、以下を含む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')
 
// 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では、pagesの外部にartifactDirectory構成設定を指定する必要があります。そうでない場合、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$'] },
  },
}

コンソールの削除
next.config.js
module.exports = {
  compiler: {
    removeConsole: true,
  },
}

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

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

レガシーデコレータ
{
  "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倍高速です。

何らかの理由で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'],
}

モジュール化インポート optimizePackageImportsに取って代わられました。インポートパスの手動設定を必要としない新しいオプションを使用するためにアップグレードすることをお勧めします。

実験的機能 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プラグイン(実験的)
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、Remove React Properties、Legacy Decorators、Remove Console、jsxImportSourceのサポートが追加されました。
v12.0.0Next.jsコンパイラーが導入されました。