Saltar a contenido

Turbopack Cheatsheet

■h1 títuloTurbopack - The Incremental Bundler "Clase de inscripción" Turbopack es un paquete incremental optimizado para JavaScript y TypeScript, escrito en Rust. Creado por Vercel, está diseñado para ser el sucesor de Webpack con 10 actualizaciones más rápidas que Vite y 700x más rápido que Webpack. ▪/p] ■/div titulada

########################################################################################################################################################################################################################################################## Copiar todos los comandos
########################################################################################################################################################################################################################################################## Generar PDF seleccionado/button

■/div titulada ■/div titulada

Cuadro de contenidos

Introducción

¿Qué es Turbopack?

Turbopack es un paquete incremental optimizado para JavaScript y TypeScript, escrito en Rust por los creadores de Webpack y Next.js. Representa un cambio fundamental en cómo funcionan los usuarios, centrándose en la computación incremental para lograr una velocidad sin precedentes.

Características clave

  • Computación Incremental: Sólo procesos lo que ha cambiado
  • Rust Performance: Construido en Rust para velocidad máxima
  • Reemplazamiento del módulo de arranque: Actualizaciones instantáneas durante el desarrollo
  • Framework Agnostic: Funciona con cualquier marco JavaScript
  • Siguiente.js Integración: Apoyo de primera clase para aplicaciones Next.js
  • TypeScript Native: Soporte de tipoScript incorporado sin configuración

Parámetros de rendimiento

# Turbopack vs other bundlers (startup time)
Turbopack: ~1.8s
Vite: ~11.4s
Webpack: ~16.5s

# Hot updates
Turbopack: ~6ms
Vite: ~30ms
Webpack: ~612ms

Instalación

Next.js Integration (Recomendado)

# Create new Next.js app with Turbopack
npx create-next-app@latest my-app

# Navigate to project
cd my-app

# Start with Turbopack
npm run dev -- --turbo

Proyecto existente Next.js

# Update Next.js to latest version
npm install next@latest

# Start development with Turbopack
npm run dev -- --turbo

# Or update package.json scripts
{
  "scripts": {
    "dev": "next dev --turbo",
    "build": "next build",
    "start": "next start"
  }
}

Instalación independiente (Alpha)

# Install Turbopack CLI (experimental)
npm install -g @turbo/pack

# Or locally
npm install --save-dev @turbo/pack

Verificar la instalación

# Check Next.js version
npx next --version

# Verify Turbopack is working
npm run dev -- --turbo
# Look for "Turbopack" in the startup logs

Comienzo

Basic Next.js Configuración con Turbopack

# Create new project
npx create-next-app@latest my-turbo-app --typescript --tailwind --eslint --app

# Navigate to project
cd my-turbo-app

# Start with Turbopack
npm run dev -- --turbo

Estructura del proyecto

my-turbo-app/
├── app/                 # App Router (Next.js 13+)
   ├── globals.css
   ├── layout.tsx
   ├── page.tsx
   └── components/
├── public/              # Static assets
├── next.config.js       # Next.js configuration
├── package.json
├── tailwind.config.js
└── tsconfig.json

Configuración básica

// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    turbo: {
      // Turbopack configuration
      loaders: {
        '.svg': ['@svgr/webpack'],
      },
      resolveAlias: {
        '@': './src',
        '@components': './src/components',
      },
    },
  },
}

module.exports = nextConfig

Primer componente

// app/components/Counter.tsx
'use client'

import { useState } from 'react'

export default function Counter() {
  const [count, setCount] = useState(0)

  return (
    <div className="p-4 border rounded-lg">
      <h2 className="text-xl font-bold mb-4">Counter: {count}</h2>
      <div className="space-x-2">
        <button 
          onClick={() => setCount(count + 1)}
          className="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
        >
          Increment
        </button>
        <button 
          onClick={() => setCount(count - 1)}
          className="px-4 py-2 bg-red-500 text-white rounded hover:bg-red-600"
        >
          Decrement
        </button>
      </div>
    </div>
  )
}

Next.js Integration

App Router con Turbopack

// app/layout.tsx
import './globals.css'
import type { Metadata } from 'next'
import { Inter } from 'next/font/google'

const inter = Inter({ subsets: ['latin'] })

export const metadata: Metadata = {
  title: 'Turbopack App',
  description: 'Built with Next.js and Turbopack',
}

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body className={inter.className}>
        <main className="container mx-auto px-4 py-8">
          {children}
        </main>
      </body>
    </html>
  )
}
// app/page.tsx
import Counter from './components/Counter'
import Link from 'next/link'

export default function Home() {
  return (
    <div className="space-y-8">
      <h1 className="text-4xl font-bold text-center">
        Welcome to Turbopack
      </h1>

      <div className="grid grid-cols-1 md:grid-cols-2 gap-8">
        <div className="space-y-4">
          <h2 className="text-2xl font-semibold">Features</h2>
          <ul className="list-disc list-inside space-y-2">
            <li>⚡ Lightning fast HMR</li>
            <li>🦀 Built in Rust</li>
            <li>📦 Incremental bundling</li>
            <li>🔥 Hot module replacement</li>
          </ul>
        </div>

        <Counter />
      </div>

      <div className="text-center">
        <Link 
          href="/about" 
          className="text-blue-500 hover:text-blue-700 underline"
        >
          Learn more about Turbopack
        </Link>
      </div>
    </div>
  )
}

Pages Router con Turbopack

// pages/_app.tsx
import type { AppProps } from 'next/app'
import '../styles/globals.css'

export default function App({ Component, pageProps }: AppProps) {
  return <Component {...pageProps} />
}
// pages/index.tsx
import { useState } from 'react'
import Head from 'next/head'

export default function Home() {
  const [message, setMessage] = useState('Hello Turbopack!')

  return (
    <>
      <Head>
        <title>Turbopack Demo</title>
        <meta name="description" content="Turbopack demonstration" />
      </Head>

      <div className="container mx-auto px-4 py-8">
        <h1 className="text-4xl font-bold mb-8">{message}</h1>

        <button
          onClick={() => setMessage('Turbopack is fast!')}
          className="px-6 py-3 bg-green-500 text-white rounded-lg hover:bg-green-600"
        >
          Update Message
        </button>
      </div>
    </>
  )
}

API Routes

// app/api/hello/route.ts (App Router)
import { NextRequest, NextResponse } from 'next/server'

export async function GET(request: NextRequest) {
  return NextResponse.json({ 
    message: 'Hello from Turbopack API!',
    timestamp: new Date().toISOString()
  })
}

export async function POST(request: NextRequest) {
  const body = await request.json()

  return NextResponse.json({
    received: body,
    processed: true
  })
}
// pages/api/hello.ts (Pages Router)
import type { NextApiRequest, NextApiResponse } from 'next'

type Data = {
  message: string
  timestamp: string
}

export default function handler(
  req: NextApiRequest,
  res: NextApiResponse<Data>
) {
  res.status(200).json({ 
    message: 'Hello from Turbopack API!',
    timestamp: new Date().toISOString()
  })
}

Configuración

Configuración básica de Turbopack

// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    turbo: {
      // Enable Turbopack
      rules: {
        // Custom rules for file processing
        '*.svg': {
          loaders: ['@svgr/webpack'],
          as: '*.js',
        },
      },

      // Resolve aliases
      resolveAlias: {
        '@': './src',
        '@components': './src/components',
        '@utils': './src/utils',
        '@styles': './src/styles',
      },

      // Resolve extensions
      resolveExtensions: [
        '.mdx',
        '.tsx',
        '.ts',
        '.jsx',
        '.js',
        '.mjs',
        '.json',
      ],

      // Module resolution
      resolveModules: [
        'node_modules',
        './src',
      ],
    },
  },
}

module.exports = nextConfig

Configuración avanzada

// next.config.js
const nextConfig = {
  experimental: {
    turbo: {
      // Loader configuration
      loaders: {
        '.md': ['raw-loader'],
        '.svg': ['@svgr/webpack'],
        '.graphql': ['graphql-tag/loader'],
      },

      // Resolve configuration
      resolveAlias: {
        '@': './src',
        '@components': './src/components',
        '@hooks': './src/hooks',
        '@utils': './src/utils',
        '@types': './src/types',
        '@styles': './src/styles',
        '@public': './public',
      },

      // Memory optimization
      memoryLimit: 4096,

      // Experimental features
      useSwcLoader: true,
      optimizeCss: true,
    },

    // Other Next.js experimental features
    appDir: true,
    serverComponentsExternalPackages: ['@prisma/client'],
  },

  // Standard Next.js configuration
  images: {
    domains: ['example.com'],
  },

  env: {
    CUSTOM_KEY: process.env.CUSTOM_KEY,
  },
}

module.exports = nextConfig

Configuración TipoScript

// tsconfig.json
{
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "es6"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "bundler",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "incremental": true,
    "plugins": [
      {
        "name": "next"
      }
    ],
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"],
      "@components/*": ["./src/components/*"],
      "@utils/*": ["./src/utils/*"],
      "@types/*": ["./src/types/*"]
    }
  },
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
  "exclude": ["node_modules"]
}

Development Server

Start Development Server

# Start with Turbopack
npm run dev -- --turbo

# Custom port
npm run dev -- --turbo --port 3001

# Custom hostname
npm run dev -- --turbo --hostname 0.0.0.0

# Enable experimental features
npm run dev -- --turbo --experimental-https

Opciones de desarrollo del servidor

// package.json
{
  "scripts": {
    "dev": "next dev --turbo",
    "dev:debug": "next dev --turbo --inspect",
    "dev:port": "next dev --turbo --port 3001",
    "dev:https": "next dev --turbo --experimental-https",
    "build": "next build",
    "start": "next start"
  }
}

Reemplazamiento del módulo caliente

// components/LiveComponent.tsx
'use client'

import { useState, useEffect } from 'react'

export default function LiveComponent() {
  const [timestamp, setTimestamp] = useState(new Date().toLocaleTimeString())

  useEffect(() => {
    const interval = setInterval(() => {
      setTimestamp(new Date().toLocaleTimeString())
    }, 1000)

    return () => clearInterval(interval)
  }, [])

  return (
    <div className="p-4 border-2 border-dashed border-blue-300 rounded-lg">
      <h3 className="text-lg font-semibold mb-2">Live Component</h3>
      <p className="text-sm text-gray-600">
        Current time: {timestamp}
      </p>
      <p className="text-xs text-green-600 mt-2">
        ✅ This component updates instantly with Turbopack HMR
      </p>
    </div>
  )
}

Development Debugging

# Enable debugging
npm run dev -- --turbo --inspect

# Debug with specific port
npm run dev -- --turbo --inspect=9229

# Verbose logging
DEBUG=turbopack* npm run dev -- --turbo

Proceso de construcción

Producción

# Build for production
npm run build

# Build with analysis
npm run build -- --analyze

# Build with debug info
npm run build -- --debug

Configuración de construcción

// next.config.js
const nextConfig = {
  // Production optimizations
  compiler: {
    removeConsole: process.env.NODE_ENV === 'production',
  },

  // Output configuration
  output: 'standalone', // For Docker deployments

  // Image optimization
  images: {
    unoptimized: false,
    domains: ['example.com'],
  },

  // Experimental Turbopack for build (future)
  experimental: {
    turbo: {
      // Build-specific configuration
    },
  },
}

module.exports = nextConfig

Análisis de la construcción

# Install bundle analyzer
npm install --save-dev @next/bundle-analyzer

# Configure analyzer
# next.config.js
const withBundleAnalyzer = require('@next/bundle-analyzer')({
  enabled: process.env.ANALYZE === 'true',
})

module.exports = withBundleAnalyzer(nextConfig)

# Run analysis
ANALYZE=true npm run build

Guiones de construcción personalizados

// package.json
{
  "scripts": {
    "build": "next build",
    "build:analyze": "ANALYZE=true next build",
    "build:standalone": "next build && next export",
    "build:debug": "DEBUG=1 next build",
    "postbuild": "next-sitemap"
  }
}

Asset Handling

Activos estaticos

// components/ImageComponent.tsx
import Image from 'next/image'
import logo from '../public/logo.png'

export default function ImageComponent() {
  return (
    <div className="space-y-4">
      {/* Static import */}
      <Image
        src={logo}
        alt="Logo"
        width={200}
        height={100}
        priority
      />

      {/* Dynamic import */}
      <Image
        src="/images/hero.jpg"
        alt="Hero"
        width={800}
        height={400}
        className="rounded-lg"
      />
    </div>
  )
}

SVG Manejo

// next.config.js
const nextConfig = {
  experimental: {
    turbo: {
      rules: {
        '*.svg': {
          loaders: ['@svgr/webpack'],
          as: '*.js',
        },
      },
    },
  },
}
// components/IconComponent.tsx
import { ReactComponent as Icon } from '../assets/icon.svg'

export default function IconComponent() {
  return (
    <div className="flex items-center space-x-2">
      <Icon className="w-6 h-6 text-blue-500" />
      <span>SVG Icon</span>
    </div>
  )
}

Fuente

// app/layout.tsx
import { Inter, Roboto_Mono } from 'next/font/google'

const inter = Inter({
  subsets: ['latin'],
  display: 'swap',
})

const robotoMono = Roboto_Mono({
  subsets: ['latin'],
  display: 'swap',
  variable: '--font-roboto-mono',
})

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en" className={`${inter.className} ${robotoMono.variable}`}>
      <body>{children}</body>
    </html>
  )
}

Importaciones dinámicas

// components/DynamicComponent.tsx
import dynamic from 'next/dynamic'
import { Suspense } from 'react'

const HeavyComponent = dynamic(() => import('./HeavyComponent'), {
  loading: () => <p>Loading...</p>,
  ssr: false,
})

const ChartComponent = dynamic(() => import('./Chart'), {
  suspense: true,
})

export default function DynamicComponent() {
  return (
    <div className="space-y-8">
      <HeavyComponent />

      <Suspense fallback={<div>Loading chart...</div>}>
        <ChartComponent />
      </Suspense>
    </div>
  )
}

CSS Apoyo

Tailwind CSS

# Install Tailwind CSS
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
// tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    './pages/**/*.{js,ts,jsx,tsx,mdx}',
    './components/**/*.{js,ts,jsx,tsx,mdx}',
    './app/**/*.{js,ts,jsx,tsx,mdx}',
  ],
  theme: {
    extend: {
      colors: {
        primary: '#3b82f6',
        secondary: '#64748b',
      },
    },
  },
  plugins: [],
}
/* app/globals.css */
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer components {
  .btn-primary {
    @apply px-4 py-2 bg-primary text-white rounded-lg hover:bg-blue-600 transition-colors;
  }
}

CSS Módulos

/* components/Button.module.css */
.button {
  padding: 0.5rem 1rem;
  border: none;
  border-radius: 0.375rem;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s;
}

.primary {
  background-color: #3b82f6;
  color: white;
}

.primary:hover {
  background-color: #2563eb;
}

.secondary {
  background-color: #64748b;
  color: white;
}
// components/Button.tsx
import styles from './Button.module.css'
import { ReactNode } from 'react'

interface ButtonProps {
  children: ReactNode
  variant?: 'primary' | 'secondary'
  onClick?: () => void
}

export default function Button({ 
  children, 
  variant = 'primary', 
  onClick 
}: ButtonProps) {
  return (
    <button 
      className={`${styles.button} ${styles[variant]}`}
      onClick={onClick}
    >
      {children}
    </button>
  )
}

Componentes de estilo

# Install styled-components
npm install styled-components
npm install -D @types/styled-components
// components/StyledButton.tsx
'use client'

import styled from 'styled-components'

const StyledButton = styled.button<{ variant: 'primary' | 'secondary' }>`
  padding: 0.5rem 1rem;
  border: none;
  border-radius: 0.375rem;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s;

  background-color: ${props => 
    props.variant === 'primary' ? '#3b82f6' : '#64748b'
  };
  color: white;

  &:hover {
    background-color: ${props => 
      props.variant === 'primary' ? '#2563eb' : '#475569'
    };
  }
`

export default function Button({ 
  children, 
  variant = 'primary',
  ...props 
}: {
  children: React.ReactNode
  variant?: 'primary' | 'secondary'
  onClick?: () => void
}) {
  return (
    <StyledButton variant={variant} {...props}>
      {children}
    </StyledButton>
  )
}

Sass/SCSS Apoyo

# Install Sass
npm install -D sass
// styles/components.scss
$primary-color: #3b82f6;
$secondary-color: #64748b;
$border-radius: 0.375rem;

@mixin button-base {
  padding: 0.5rem 1rem;
  border: none;
  border-radius: $border-radius;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s;
}

.btn {
  @include button-base;

  &--primary {
    background-color: $primary-color;
    color: white;

    &:hover {
      background-color: darken($primary-color, 10%);
    }
  }

  &--secondary {
    background-color: $secondary-color;
    color: white;

    &:hover {
      background-color: darken($secondary-color, 10%);
    }
  }
}

Soporte TipoScript

Configuración TipoScript

// tsconfig.json
{
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "es6"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "bundler",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "incremental": true,
    "plugins": [
      {
        "name": "next"
      }
    ],
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"],
      "@components/*": ["./src/components/*"],
      "@utils/*": ["./src/utils/*"],
      "@types/*": ["./src/types/*"],
      "@hooks/*": ["./src/hooks/*"]
    }
  },
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
  "exclude": ["node_modules"]
}

Definición

// src/types/index.ts
export interface User {
  id: string
  name: string
  email: string
  avatar?: string
  createdAt: Date
  updatedAt: Date
}

export interface Post {
  id: string
  title: string
  content: string
  author: User
  published: boolean
  tags: string[]
  createdAt: Date
  updatedAt: Date
}

export interface ApiResponse<T> {
  data: T
  message: string
  status: 'success' | 'error'
}

export type Theme = 'light' | 'dark' | 'system'

export interface AppConfig {
  apiUrl: string
  theme: Theme
  features: {
    auth: boolean
    analytics: boolean
    notifications: boolean
  }
}

Componentes clasificados

// components/UserCard.tsx
import { User } from '@/types'
import Image from 'next/image'

interface UserCardProps {
  user: User
  showEmail?: boolean
  onEdit?: (user: User) => void
  className?: string
}

export default function UserCard({ 
  user, 
  showEmail = false, 
  onEdit,
  className = ''
}: UserCardProps) {
  return (
    <div className={`p-4 border rounded-lg ${className}`}>
      <div className="flex items-center space-x-3">
        {user.avatar && (
          <Image
            src={user.avatar}
            alt={user.name}
            width={40}
            height={40}
            className="rounded-full"
          />
        )}

        <div>
          <h3 className="font-semibold">{user.name}</h3>
          {showEmail && (
            <p className="text-sm text-gray-600">{user.email}</p>
          )}
        </div>
      </div>

      {onEdit && (
        <button
          onClick={() => onEdit(user)}
          className="mt-3 text-blue-500 hover:text-blue-700"
        >
          Edit User
        </button>
      )}
    </div>
  )
}
```_

### Ganchos personalizados con TipoScript
```typescript
// hooks/useApi.ts
import { useState, useEffect } from 'react'
import { ApiResponse } from '@/types'

interface UseApiOptions {
  immediate?: boolean
}

export function useApi<T>(
  url: string, 
  options: UseApiOptions = {}
) {
  const [data, setData] = useState<T | null>(null)
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState<string | null>(null)

  const fetchData = async () => {
    setLoading(true)
    setError(null)

    try {
      const response = await fetch(url)
      const result: ApiResponse<T> = await response.json()

      if (result.status === 'success') {
        setData(result.data)
      } else {
        setError(result.message)
      }
    } catch (err) {
      setError(err instanceof Error ? err.message : 'An error occurred')
    } finally {
      setLoading(false)
    }
  }

  useEffect(() => {
    if (options.immediate !== false) {
      fetchData()
    }
  }, [url])

  return { data, loading, error, refetch: fetchData }
}

Medio ambiente

Configuración del medio ambiente

# .env.local
NEXT_PUBLIC_API_URL=http://localhost:3001/api
NEXT_PUBLIC_APP_NAME=Turbopack App
DATABASE_URL=postgresql://user:password@localhost:5432/mydb
SECRET_KEY=your-secret-key
# .env.production
NEXT_PUBLIC_API_URL=https://api.production.com
NEXT_PUBLIC_APP_NAME=Production App
DATABASE_URL=postgresql://user:password@prod-db:5432/mydb
SECRET_KEY=production-secret-key

Utilización de variables ambientales

// lib/config.ts
export const config = {
  apiUrl: process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3001/api',
  appName: process.env.NEXT_PUBLIC_APP_NAME || 'My App',
  isDevelopment: process.env.NODE_ENV === 'development',
  isProduction: process.env.NODE_ENV === 'production',
}

// Server-side only
export const serverConfig = {
  databaseUrl: process.env.DATABASE_URL!,
  secretKey: process.env.SECRET_KEY!,
}
// components/ApiExample.tsx
'use client'

import { config } from '@/lib/config'
import { useEffect, useState } from 'react'

export default function ApiExample() {
  const [data, setData] = useState(null)

  useEffect(() => {
    fetch(`${config.apiUrl}/hello`)
      .then(res => res.json())
      .then(setData)
  }, [])

  return (
    <div className="p-4 border rounded-lg">
      <h3 className="font-semibold mb-2">API Response</h3>
      <p className="text-sm text-gray-600 mb-2">
        API URL: {config.apiUrl}
      </p>
      <pre className="text-xs bg-gray-100 p-2 rounded">
        {JSON.stringify(data, null, 2)}
      </pre>
    </div>
  )
}
```_

### Configuración de tiempo de ejecución
```javascript
// next.config.js
const nextConfig = {
  env: {
    CUSTOM_KEY: process.env.CUSTOM_KEY,
    BUILD_TIME: new Date().toISOString(),
  },

  publicRuntimeConfig: {
    // Available on both server and client
    apiUrl: process.env.API_URL,
  },

  serverRuntimeConfig: {
    // Only available on server
    secretKey: process.env.SECRET_KEY,
  },
}

module.exports = nextConfig

Plugins

Soporte de plugin actual

// next.config.js
const nextConfig = {
  experimental: {
    turbo: {
      // Loader configuration (limited plugin support)
      loaders: {
        '.svg': ['@svgr/webpack'],
        '.md': ['raw-loader'],
        '.graphql': ['graphql-tag/loader'],
      },

      // Rules for file processing
      rules: {
        '*.svg': {
          loaders: ['@svgr/webpack'],
          as: '*.js',
        },
      },
    },
  },
}

Plugins Webpack (Fallback)

// next.config.js
const nextConfig = {
  webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
    // Custom webpack configuration for features not yet supported in Turbopack
    config.plugins.push(
      new webpack.DefinePlugin({
        __BUILD_ID__: JSON.stringify(buildId),
      })
    )

    return config
  },

  experimental: {
    turbo: {
      // Turbopack configuration
    },
  },
}

Future Plugin System

// Future Turbopack plugin API (conceptual)
const nextConfig = {
  experimental: {
    turbo: {
      plugins: [
        // Future plugin system
        '@turbopack/plugin-sass',
        '@turbopack/plugin-postcss',
        ['@turbopack/plugin-custom', { options: {} }],
      ],
    },
  },
}

Ejecución

Parámetros de rendimiento

# Development server startup
Turbopack: ~1.8s (10x faster than Vite)
Vite: ~11.4s
Webpack: ~16.5s

# Hot Module Replacement
Turbopack: ~6ms (5x faster than Vite)
Vite: ~30ms
Webpack: ~612ms (100x slower)

# Large codebase (30k modules)
Turbopack: ~1.2s startup
Webpack: ~30s startup

Supervisión de la ejecución

// components/PerformanceMonitor.tsx
'use client'

import { useEffect, useState } from 'react'

export default function PerformanceMonitor() {
  const [metrics, setMetrics] = useState<any>(null)

  useEffect(() => {
    if (typeof window !== 'undefined' && 'performance' in window) {
      const navigation = performance.getEntriesByType('navigation')[0] as PerformanceNavigationTiming

      setMetrics({
        domContentLoaded: navigation.domContentLoadedEventEnd - navigation.domContentLoadedEventStart,
        loadComplete: navigation.loadEventEnd - navigation.loadEventStart,
        firstPaint: performance.getEntriesByName('first-paint')[0]?.startTime,
        firstContentfulPaint: performance.getEntriesByName('first-contentful-paint')[0]?.startTime,
      })
    }
  }, [])

  if (!metrics) return null

  return (
    <div className="p-4 bg-gray-100 rounded-lg">
      <h3 className="font-semibold mb-2">Performance Metrics</h3>
      <div className="grid grid-cols-2 gap-2 text-sm">
        <div>DOM Content Loaded: {metrics.domContentLoaded?.toFixed(2)}ms</div>
        <div>Load Complete: {metrics.loadComplete?.toFixed(2)}ms</div>
        <div>First Paint: {metrics.firstPaint?.toFixed(2)}ms</div>
        <div>First Contentful Paint: {metrics.firstContentfulPaint?.toFixed(2)}ms</div>
      </div>
    </div>
  )
}

Bundle Analysis

# Install bundle analyzer
npm install --save-dev @next/bundle-analyzer

# Analyze bundle
ANALYZE=true npm run build
// next.config.js
const withBundleAnalyzer = require('@next/bundle-analyzer')({
  enabled: process.env.ANALYZE === 'true',
})

const nextConfig = {
  experimental: {
    turbo: {
      // Turbopack configuration
    },
  },
}

module.exports = withBundleAnalyzer(nextConfig)

Migración

De Webpack a Turbopack

# Update Next.js to latest version
npm install next@latest

# Update package.json scripts
{
  "scripts": {
    "dev": "next dev --turbo",
    "build": "next build",
    "start": "next start"
  }
}

Lista de control de migración

  • Actualizar Next.js a la versión 13.5+
  • Añadir --turbo_ flag to dev script
  • Prueba todas las características en el desarrollo
  • Actualizar configuración de webpack personalizado
  • Verificar todos los cargadores funcionan correctamente
  • Prueba de sustitución del módulo caliente
  • Comprobar compatibilidad del proceso de construcción

Cuestiones de migración comunes

// Issue: Custom webpack loaders not supported
// Solution: Use Turbopack loader configuration
const nextConfig = {
  experimental: {
    turbo: {
      loaders: {
        '.custom': ['custom-loader'],
      },
    },
  },

  // Fallback to webpack for unsupported features
  webpack: (config) => {
    // Custom webpack configuration
    return config
  },
}

Migración gradual

// next.config.js
const nextConfig = {
  experimental: {
    turbo: {
      // Enable Turbopack for development only
    },
  },

  // Keep webpack configuration for production builds
  webpack: (config, { dev }) => {
    if (!dev) {
      // Production webpack configuration
    }
    return config
  },
}

Solución de problemas

Cuestiones comunes

Turbopack no empieza

# Check Next.js version
npx next --version

# Ensure version 13.5+
npm install next@latest

# Clear cache
rm -rf .next
npm run dev -- --turbo

Cuestiones relativas a la resolución del módulo

// next.config.js
const nextConfig = {
  experimental: {
    turbo: {
      resolveAlias: {
        '@': './src',
        '@components': './src/components',
      },
      resolveExtensions: ['.tsx', '.ts', '.jsx', '.js'],
    },
  },
}

Recarga caliente no funciona

# Check file watching limits (Linux)
echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

# Restart development server
npm run dev -- --turbo

Errores de construcción

# Enable verbose logging
DEBUG=turbopack* npm run dev -- --turbo

# Check for unsupported features
npm run build

Configuración de depuración

// next.config.js
const nextConfig = {
  experimental: {
    turbo: {
      // Enable debug mode
      logLevel: 'debug',

      // Memory limit
      memoryLimit: 4096,
    },
  },

  // Enable source maps
  productionBrowserSourceMaps: true,
}

Buenas prácticas

Estructura del proyecto

# Recommended structure for Turbopack projects
src/
├── app/                 # App Router pages
   ├── globals.css
   ├── layout.tsx
   ├── page.tsx
   └── (routes)/
├── components/          # Reusable components
   ├── ui/             # Basic UI components
   ├── forms/          # Form components
   └── layout/         # Layout components
├── hooks/              # Custom hooks
├── lib/                # Utility libraries
├── types/              # TypeScript types
├── styles/             # Global styles
└── utils/              # Utility functions

Prácticas óptimas de rendimiento

  • Use Turbopack para el desarrollo para obtener beneficios de máxima velocidad
  • Ejecución de código adecuado con importaciones dinámicas
  • Optimizar imágenes con el componente Next.js Imagen
  • Use TipoScript para una mejor experiencia de desarrollo
  • ** Tamaño del paquete de monitor** con analizador de paquetes

Development Best Practices

  • Empieza con la bandera __CODE_BLOCK_66_ para el desarrollo
  • Use importaciones absolutas con alias de ruta
  • **Implement proper error boundaries* *
  • Use React DevTools para depurar
  • El mejor hot reload funcionalidad regularmente

Producción Buenas Prácticas

  • Test construye antes del despliegue
  • Rendimiento del monitor métricas
  • Utilizar variables de entorno para la configuración
  • Estrategias de caché adecuadas
  • ** Tamaño del paquete de monitor** y rendimiento

-...

Resumen

Turbopack representa el futuro de la agrupación de JavaScript con su enfoque incremental y el rendimiento de Rust. Las características principales incluyen:

  • Incremental Bundling # Sólo los procesos cambiaron archivos para la velocidad máxima

  • Rust Performance: Construido en Rust para 10 actualizaciones más rápidas que Vite
  • Siguiente.js Integración: Apoyo de primera clase para aplicaciones Next.js
  • Reemplazamiento del módulo de arranque: Actualizaciones instantáneas durante el desarrollo
  • TypeScript Native: Soporte de tipoScript incorporado sin configuración
  • Framework Agnostic: Funciona con cualquier marco JavaScript
  • Future-Proof: Diseñado para reemplazar Webpack como el paquete estándar

Mediante la adopción de Turbopack, puede mejorar significativamente su experiencia de desarrollo con construcciones más rápidas, recargas calientes instantáneas y un flujo de trabajo de desarrollo más sensible.

" copia de la funciónToClipboard() {} comandos const = document.querySelectorAll('code'); que todos losCommands = '; comandos. paraCada(cmd = confianza allCommands += cmd.textContent + '\n'); navigator.clipboard.writeText(allCommands); alerta ('Todos los comandos copiados a portapapeles!'); }

función generaPDF() { ventana.print(); } ■/script título