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

Next.js コンパイラー

Rustで記述され、SWCを使用している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内でCrateとして使用でき、ライブラリのフォークや設計制約の回避を必要としません
  • パフォーマンス: SWCに切り替えることで、Next.jsで約3倍速いFast Refreshと約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コンパイル用の個別のプロパティを構成できます。

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

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'],
}

// 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`sとは異なる構文です。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 | {
// デフォルトはtrueです。ビルドタイプがproductionの場合、無効になります。
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倍速くなっています。

何らかの理由で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に置き換えられました。インポートパスの手動設定を必要としない新しいオプションへのアップグレードをお勧めします。

定義(ビルド時に変数を置き換える)

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

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

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

実験的機能

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

chromiumのtrace event formatとして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 プラグイン(実験的)

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