メインコンテンツまでスキップ

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コンパイルの個々のプロパティを設定できます。

注: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 Compilerは、テストをトランスパイルし、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')

// 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,
},
},
}

Good to know: 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は対象外)。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倍速いです。

Good to know: 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オプションを使用すると、ビルド時にコード内の変数を静的に置き換えることができます。 このオプションは、キーと値のペアとしてオブジェクトを受け取り、キーは対応する値で置き換えられるべき変数です。

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 Minifierがデフォルトで有効になりました。
v12.3.0SWC Minifierが安定版になりました。
v12.2.0SWCプラグインの実験的サポートが追加されました。
v12.1.0Styled Components、Jest、Relay、Reactプロパティの削除、レガシーデコレータ、コンソールの削除、jsxImportSourceのサポートが追加されました。
v12.0.0Next.js Compilerが導入されました