Capítulo 445 de 456

Turbopack (overview)

Core Idea

Turbopack is Next.js's Rust-based incremental bundler, the default bundler since v16, offering a unified graph, incremental caching, and lazy bundling for much faster dev/build performance vs webpack.

Key Concepts

  • Unified Graph: single graph across client/server environments, avoiding the tedium of stitching multiple compilers' bundles.
  • Bundling vs Native ESM: Turbopack still bundles in dev (unlike native-ESM tools), but optimized to stay fast at scale.
  • Incremental Computation: caches results down to function level, parallelized across cores, persisted to disk between runs.
  • Lazy Bundling: only bundles what the dev server actually requests.
  • Supported platforms: macOS/Windows/Linux (glibc/musl) on x64/ARM64 via native bindings; unsupported platforms (FreeBSD, OpenBSD) fall back to WASM bindings (SWC compile/minify only, no Turbopack) — use --webpack there.
  • import.meta.env: Turbopack-only static env metadata (DEV, PROD, MODE, BASE_URL, SSR), statically analyzed for dead-branch elimination.
  • import.meta.glob(): Vite-compatible glob import API, Turbopack-only; supports lazy (default, thunks) or { eager: true } loading, import (named export selection), query, multiple patterns with ! negation, and TypeScript generics.
  • Magic comments: webpackIgnore, turbopackIgnore (Turbopack-only), turbopackOptional (Turbopack-only) control dynamic import/require bundling behavior.

Code Examples

if (import.meta.env.DEV) {
  console.log('development mode')
}
  • O que demonstra: leitura estática de import.meta.env.DEV, permitindo eliminação de branch morto pelo Turbopack.
const modules = import.meta.glob('./dir/*.js')
for (const path in modules) {
  const module = await modules[path]()
}
  • O que demonstra: glob import lazy (default), cada valor é uma thunk que retorna Promise do módulo.
module.exports = {
  turbopack: {
    resolveAlias: { '~*': '*' },
  },
}
  • O que demonstra: workaround pra sintaxe legacy ~ do Sass (não suportada pelo Turbopack) via alias.

Reference Tables

Feature suportada zero-configStatus
JS/TS, ESNext, CommonJS, ESMSupported
BabelSupported (auto-detectado desde Next.js 16 se houver config file)
JSX/TSX, Fast Refresh, RSCSupported
Root layout auto-criaçãoUnsupported (precisa criar manualmente)
CSS Modules, CSS Nesting, PostCSS, Sass/SCSSSupported
sassOptions.functions (custom Sass funcs)Not supported (Rust não executa JS)
LessPlanned via plugins
Path aliases (tsconfig paths/baseUrl)Supported
Webpack pluginsNot supported (loaders sim, plugins não)

Opções import.meta.glob: eager, import, query, base, caseSensitive.

Anti-patterns

  • Usar sintaxe ~ do Sass legacy (@import '~bootstrap/...'): não suportada; trocar por import sem ~ ou usar resolveAlias.
  • Depender de sassOptions.functions com Turbopack: não suportado, exige webpack.
  • Assumir mesma precisão decimal de CSS entre webpack e Turbopack: Lightning CSS usa 5 dígitos vs. 10 do webpack, pode gerar diffs visuais sutis (line-height, letter-spacing).
  • Confiar em ordenação arbitrária de CSS Modules: Turbopack segue ordem de import JS; se a app dependia de ordem diferente do webpack, ajustar via @import explícito.

Key Takeaways

  1. Turbopack virou bundler default no Next.js 16; use --webpack pra optar por webpack em vez disso.
  2. import.meta.env e import.meta.glob só existem com Turbopack, sem equivalente em webpack.
  3. Diferenças conhecidas vs. webpack: filesystem root restrito, ordem de CSS Modules por import JS, sem suporte a ~ do Sass, precisão decimal de CSS diferente, sem webpack plugins.
  4. next dev --internal-trace gera trace pra debug de performance/memória, útil pra reportar issues.

Connects To

  • turbopack (ch420): config detalhada de rules/resolveAlias/etc. referenciada aqui.
  • turbopackChunking (ch421): outra opção experimental complementar.
  • useLightningcss (ch424): Turbopack sempre usa Lightning CSS, fonte da diferença de precisão decimal.