Compilador de Next.js

El Compilador de Next.js, escrito en Rust utilizando SWC, permite a Next.js transformar y minificar tu código JavaScript para producción. Esto reemplaza a Babel para archivos individuales y a Terser para minificar los paquetes de salida.

La compilación con el Compilador de Next.js es 17 veces más rápida que Babel y está habilitada por defecto desde la versión 12 de Next.js. Si tienes una configuración existente de Babel o estás utilizando características no soportadas, tu aplicación no usará el Compilador de Next.js y continuará utilizando Babel.

¿Por qué SWC?

SWC es una plataforma extensible basada en Rust para la próxima generación de herramientas de desarrollo rápidas.

SWC puede usarse para compilación, minificación, empaquetado y más, y está diseñado para ser extendido. Es algo que puedes llamar para realizar transformaciones de código (ya sean integradas o personalizadas). La ejecución de esas transformaciones ocurre a través de herramientas de alto nivel como Next.js.

Elegimos construir sobre SWC por varias razones:

  • Extensibilidad: SWC puede usarse como un Crate dentro de Next.js, sin necesidad de bifurcar la biblioteca o sortear limitaciones de diseño.
  • Rendimiento: Logramos una actualización rápida (Fast Refresh) ~3 veces más rápida y builds ~5 veces más rápidos en Next.js al cambiar a SWC, con más optimizaciones aún en progreso.
  • WebAssembly: El soporte de Rust para WASM es esencial para admitir todas las plataformas posibles y llevar el desarrollo de Next.js a cualquier lugar.
  • Comunidad: La comunidad y el ecosistema de Rust son increíbles y siguen creciendo.

Características soportadas

Styled Components

Estamos trabajando para portar babel-plugin-styled-components al Compilador de Next.js.

Primero, actualiza a la última versión de Next.js: npm install next@latest. Luego, actualiza tu archivo next.config.js:

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

Para casos de uso avanzados, puedes configurar propiedades individuales para la compilación de styled-components.

Nota: Las transformaciones ssr y displayName son el requisito principal para usar styled-components en Next.js.

next.config.js
module.exports = {
  compiler: {
    // consulta https://styled-components.com/docs/tooling#babel-plugin para más información sobre las opciones.
    styledComponents: {
      // Habilitado por defecto en desarrollo, deshabilitado en producción para reducir el tamaño del archivo,
      // configurar esto anulará el valor por defecto para todos los entornos.
      displayName?: boolean,
      // Habilitado por defecto.
      ssr?: boolean,
      // Habilitado por defecto.
      fileName?: boolean,
      // Vacío por defecto.
      topLevelImportPaths?: string[],
      // Por defecto ["index"].
      meaninglessFileNames?: string[],
      // Habilitado por defecto.
      minify?: boolean,
      // Habilitado por defecto.
      transpileTemplateLiterals?: boolean,
      // Vacío por defecto.
      namespace?: string,
      // Deshabilitado por defecto.
      pure?: boolean,
      // Habilitado por defecto.
      cssProp?: boolean,
    },
  },
}

Jest

El Compilador de Next.js transpila tus pruebas y simplifica la configuración de Jest junto con Next.js incluyendo:

  • Auto mocking de imports .css, .module.css (y sus variantes .scss), e imports de imágenes
  • Configura automáticamente transform usando SWC
  • Carga .env (y todas sus variantes) en process.env
  • Ignora node_modules de la resolución y transformación de pruebas
  • Ignora .next de la resolución de pruebas
  • Carga next.config.js para flags que habilitan transformaciones experimentales de SWC

Primero, actualiza a la última versión de Next.js: npm install next@latest. Luego, actualiza tu archivo jest.config.js:

jest.config.js
const nextJest = require('next/jest')

// Proporcionando la ruta a tu aplicación Next.js lo que permitirá cargar next.config.js y archivos .env
const createJestConfig = nextJest({ dir: './' })

// Cualquier configuración personalizada que quieras pasar a Jest
const customJestConfig = {
  setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
}

// createJestConfig se exporta de esta manera para asegurar que next/jest pueda cargar la configuración de Next.js, que es asíncrona
module.exports = createJestConfig(customJestConfig)

Relay

Para habilitar soporte para Relay:

next.config.js
module.exports = {
  compiler: {
    relay: {
      // Esto debe coincidir con relay.config.js
      src: './',
      artifactDirectory: './__generated__',
      language: 'typescript',
      eagerEsModules: false,
    },
  },
}

Bueno saber: En Next.js, todos los archivos JavaScript en el directorio pages se consideran rutas. Por lo tanto, para relay-compiler necesitarás especificar la configuración de artifactDirectory fuera de pages, de lo contrario relay-compiler generará archivos junto al archivo fuente en el directorio __generated__, y este archivo será considerado una ruta, lo que romperá los builds de producción.

Eliminar propiedades de React

Permite eliminar propiedades JSX. Esto se usa comúnmente para testing. Similar a babel-plugin-react-remove-properties.

Para eliminar propiedades que coincidan con la regex por defecto ^data-test:

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

Para eliminar propiedades personalizadas:

next.config.js
module.exports = {
  compiler: {
    // Las regex definidas aquí se procesan en Rust por lo que la sintaxis es diferente a
    // los `RegExp` de JavaScript. Ver https://docs.rs/regex.
    reactRemoveProperties: { properties: ['^data-custom$'] },
  },
}

Eliminar Console

Esta transformación permite eliminar todas las llamadas console.* en el código de la aplicación (no en node_modules). Similar a babel-plugin-transform-remove-console.

Eliminar todas las llamadas console.*:

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

Eliminar salidas console.* excepto console.error:

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

Decoradores legacy

Next.js detectará automáticamente experimentalDecorators en jsconfig.json o tsconfig.json. Los decoradores legacy se usan comúnmente con versiones antiguas de bibliotecas como mobx.

Esta bandera solo se admite para compatibilidad con aplicaciones existentes. No recomendamos usar decoradores legacy en nuevas aplicaciones.

Primero, actualiza a la última versión de Next.js: npm install next@latest. Luego, actualiza tu archivo jsconfig.json o tsconfig.json:

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

importSource

Next.js detectará automáticamente jsxImportSource en jsconfig.json o tsconfig.json y lo aplicará. Esto se usa comúnmente con bibliotecas como Theme UI.

Primero, actualiza a la última versión de Next.js: npm install next@latest. Luego, actualiza tu archivo jsconfig.json o tsconfig.json:

{
  "compilerOptions": {
    "jsxImportSource": "theme-ui"
  }
}

Emotion

Estamos trabajando para portar @emotion/babel-plugin al Compilador de Next.js.

Primero, actualiza a la última versión de Next.js: npm install next@latest. Luego, actualiza tu archivo next.config.js:

next.config.js

module.exports = {
  compiler: {
    emotion: boolean | {
      // por defecto es true. Se deshabilitará cuando el tipo de build sea producción.
      sourceMap?: boolean,
      // por defecto es 'dev-only'.
      autoLabel?: 'never' | 'dev-only' | 'always',
      // por defecto es '[local]'.
      // Valores permitidos: `[local]` `[filename]` y `[dirname]`
      // Esta opción solo funciona cuando autoLabel está configurado como 'dev-only' o 'always'.
      // Te permite definir el formato de la etiqueta resultante.
      // El formato se define mediante una cadena donde las partes variables están encerradas en corchetes [].
      // Por ejemplo labelFormat: "my-classname--[local]", donde [local] será reemplazado por el nombre de la variable a la que se asigna el resultado.
      labelFormat?: string,
      // por defecto es undefined.
      // Esta opción te permite indicar al compilador qué imports debe
      // buscar para determinar qué debe transformar, así que si reexportas
      // exports de Emotion, aún puedes usar transformaciones.
      importMap?: {
        [packageName: string]: {
          [exportName: string]: {
            canonicalImport?: [string, string],
            styledBaseImport?: [string, string],
          }
        }
      },
    },
  },
}

Minificación

El compilador swc de Next.js se usa para minificación por defecto desde la v13. Esto es 7 veces más rápido que Terser.

Bueno saber: A partir de la v15, la minificación no puede personalizarse usando next.config.js. Se ha eliminado el soporte para la bandera swcMinify.

Transpilación de módulos

Next.js puede transpilar y empaquetar automáticamente dependencias de paquetes locales (como monorepos) o de dependencias externas (node_modules). Esto reemplaza al paquete next-transpile-modules.

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

Modularizar imports

Esta opción ha sido reemplazada por optimizePackageImports en Next.js 13.5. Recomendamos actualizar para usar la nueva opción que no requiere configuración manual de rutas de importación.

Define (Reemplazar variables durante el build)

La opción define te permite reemplazar variables en tu código estáticamente durante el build. La opción toma un objeto como pares clave-valor, donde las claves son las variables que deben ser reemplazadas con los valores correspondientes.

Usa el campo compiler.define en next.config.js para definir variables para todos los entornos (servidor, edge y cliente). O usa compiler.defineServer para definir variables solo para código del lado del servidor (servidor y edge):

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

Hooks del ciclo de vida del build

El Compilador de Next.js soporta hooks del ciclo de vida que te permiten ejecutar código personalizado en puntos específicos durante el proceso de build. Actualmente, se soporta el siguiente hook:

runAfterProductionCompile

Una función hook que se ejecuta después de que finaliza la compilación del build de producción, pero antes de ejecutar tareas posteriores a la compilación como la verificación de tipos y la generación de páginas estáticas. Este hook proporciona acceso a metadatos del proyecto incluyendo el directorio del proyecto y el directorio de salida del build, lo que lo hace útil para herramientas de terceros que recopilan salidas del build como sourcemaps.

next.config.js
module.exports = {
  compiler: {
    runAfterProductionCompile: async ({ distDir, projectDir }) => {
      // Tu código personalizado aquí
    },
  },
}

El hook recibe un objeto con las siguientes propiedades:

  • distDir: El directorio de salida del build (por defecto .next)
  • projectDir: El directorio raíz del proyecto

Características experimentales

Perfilado de trazas SWC

Puedes generar trazas internas de transformación de SWC en el formato trace event format de chromium.

next.config.js
module.exports = {
  experimental: {
    swcTraceProfiling: true,
  },
}

Una vez habilitado, swc generará trazas con el nombre swc-trace-profile-${timestamp}.json bajo .next/. El visor de trazas de chromium (chrome://tracing/, https://ui.perfetto.dev/), o un visor de flamegraph compatible (https://www.speedscope.app/) puede cargar y visualizar las trazas generadas.

Plugins SWC (experimental)

Puedes configurar la transformación de swc para usar el soporte experimental de plugins de SWC escrito en wasm para personalizar el comportamiento de transformación.

next.config.js
module.exports = {
  experimental: {
    swcPlugins: [
      [
        'plugin',
        {
          ...pluginOptions,
        },
      ],
    ],
  },
}

swcPlugins acepta un array de tuplas para configurar plugins. Una tupla para el plugin contiene la ruta al plugin y un objeto para la configuración del plugin. La ruta al plugin puede ser un nombre de paquete npm o una ruta absoluta al binario .wasm mismo.

Características no soportadas

Cuando tu aplicación tiene un archivo .babelrc, Next.js automáticamente volverá a usar Babel para transformar archivos individuales. Esto asegura compatibilidad hacia atrás con aplicaciones existentes que aprovechan plugins personalizados de Babel.

Si estás usando una configuración personalizada de Babel, comparte tu configuración. Estamos trabajando para portar tantas transformaciones comunes de Babel como sea posible, así como soportar plugins en el futuro.

Historial de versiones

VersiónCambios
v13.1.0Transpilación de módulos e Importaciones modularizadas estables.
v13.0.0Minificador SWC habilitado por defecto.
v12.3.0Minificador SWC estable.
v12.2.0Soporte experimental para Plugins SWC añadido.
v12.1.0Añadido soporte para Styled Components, Jest, Relay, Eliminar propiedades de React, Decoradores legacy, Eliminar console y jsxImportSource.
v12.0.0Compilador de Next.js introducido.