Next.js 15 Fullstack (App Router + Server Actions) · درس

تعمّق في إعدادات Turbopack والمترجم

اضبط Turbopack والتحويلات والمترجم المستند إلى SWC لتسريع عمليات البناء وتقليص المخرجات.

الدرس 2 من 413 خطوة

تعمّق في إعدادات Turbopack والمترجم درس مجاني في Next.js 15 Fullstack (App Router + Server Actions) على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Next.js 15 Fullstack (App Router + Server Actions)، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Next.js 15 Fullstack (App Router + Server Actions) 4 دروس في المجموع.

بعض أجزاء هذا الدرس لم تُترجم بعد وتظهر باللغة الإنجليزية.

Why Turbopack Exists

Next.js 15 ships Turbopack as the default bundler for next dev. It was built in Rust to replace the JavaScript-based Webpack pipeline that powered Next.js for years.

The core problem Webpack faced at scale: every file change triggered a JavaScript graph traversal and re-evaluation. At 10,000 modules, a single edit could take 8–15 seconds before HMR landed in the browser.

Turbopack solves this with three architectural bets:

  • Incremental computation — only the modules affected by a change are re-evaluated, not the whole graph.
  • Parallel compilation — Rust's fearless concurrency lets multiple CPU cores transform files simultaneously.
  • Persistent caching — transform results are stored on disk and survive process restarts.

The result: cold start times drop by roughly 50–75% on large apps, and HMR latency falls to single-digit milliseconds in most cases.

Enabling Turbopack in next.config.ts

In Next.js 15, next dev --turbopack is the recommended way to opt in during development. For production builds, Webpack remains the default until Turbopack reaches full parity, so you control the flag per command in package.json.

You can also embed Turbopack options directly inside next.config.ts under the experimental.turbo key (renamed to turbopack in the stable API).

Key points to keep in mind:

  • The turbopack key only affects next dev; production builds still use Webpack unless you pass --turbopack to next build (experimental in v15).
  • Options in turbopack are merged on top of Turbopack's built-in defaults — you never have to replicate the full config.
  • The TypeScript config file (next.config.ts) gives you full type safety for these options via the NextConfig type.
// next.config.ts
import type { NextConfig } from 'next';

const config: NextConfig = {
  turbopack: {
    // Turbopack-specific options go here
    // (rules, resolveAlias, resolveExtensions, etc.)
  },
};

export default config;

Turbopack Loaders: Replacing Webpack Rules

Webpack used module.rules with loaders like babel-loader or raw-loader. Turbopack has an equivalent called rules inside the turbopack config block.

Each rule maps a file-extension glob to one or more Turbopack-compatible loaders. Note that Webpack loaders are not directly compatible — Turbopack requires loaders that implement its own transform API, though many popular loaders (e.g. @svgr/webpack, @mdx-js/loader) have published Turbopack-compatible versions.

Anatomy of a rule:

  • test — a glob or regex string matching file paths
  • use — an array of loader objects, each with a loader package name and an optional options object

Loaders run right-to-left, exactly as in Webpack.

// next.config.ts
import type { NextConfig } from 'next';

const config: NextConfig = {
  turbopack: {
    rules: {
      // Transform .svg files into React components
      '*.svg': {
        loaders: ['@svgr/webpack'],
        as: '*.js',
      },
      // Transform raw .txt files into string modules
      '*.txt': {
        loaders: ['raw-loader'],
        as: '*.js',
      },
    },
  },
};

export default config;

Module Aliases with resolveAlias

Path aliases let you write import { Button } from '@ui/Button' instead of ../../components/ui/Button. Turbopack supports this via turbopack.resolveAlias, which mirrors Webpack's resolve.alias.

You should also keep your tsconfig.json paths in sync — the TypeScript compiler uses paths for type checking, while Turbopack uses resolveAlias for bundling. A mismatch causes "module not found" errors at build time even though types look correct in your editor.

Common pattern: define the canonical mapping in one place and derive both configs from it, or use next/jest which auto-reads tsconfig.json paths for Jest.

// next.config.ts
import type { NextConfig } from 'next';
import path from 'path';

const config: NextConfig = {
  turbopack: {
    resolveAlias: {
      '@ui': path.resolve(__dirname, 'src/components/ui'),
      '@lib': path.resolve(__dirname, 'src/lib'),
      '@server': path.resolve(__dirname, 'src/server'),
    },
  },
};

export default config;

// tsconfig.json (keep in sync)
// {
//   "compilerOptions": {
//     "paths": {
//       "@ui/*": ["./src/components/ui/*"],
//       "@lib/*": ["./src/lib/*"],
//       "@server/*": ["./src/server/*"]
//     }
//   }
// }

SWC: Next.js's Built-in Compiler

Alongside Turbopack, Next.js uses SWC (Speedy Web Compiler) as its code transformer. SWC is also written in Rust and handles TypeScript stripping, JSX transformation, minification, and optional syntax transforms.

Important distinction:

  • Turbopack is the bundler — it builds the module graph, resolves imports, and orchestrates code splitting.
  • SWC is the transformer — it converts individual files (TS → JS, JSX → React.createElement calls, etc.).

Both are active by default in Next.js 15. SWC replaces Babel for most projects; if you still have a .babelrc in your repo, Next.js will fall back to Babel and disable SWC — this is a common source of slow builds on migrated projects.

To confirm SWC is active, run next build and look for "SWC minify" in the output.

Configuring SWC Transforms in next.config.ts

SWC transforms are configured at the top level of NextConfig (not inside turbopack). The most commonly tuned options are:

  • compiler.styledComponents — enables the SWC plugin for styled-components, adding display names and deterministic class names.
  • compiler.emotion — same for the Emotion CSS-in-JS library.
  • compiler.removeConsole — strips console.* calls from production builds. You can whitelist specific methods (e.g. keep console.error).
  • compiler.reactRemoveProperties — removes custom React props (like data-testid) from production output, reducing HTML payload.

These transforms run on every file during compilation, so enabling only what you need keeps build times tight.

// next.config.ts
import type { NextConfig } from 'next';

const isProd = process.env.NODE_ENV === 'production';

const config: NextConfig = {
  compiler: {
    // Remove console.log but keep console.error in production
    removeConsole: isProd
      ? { exclude: ['error', 'warn'] }
      : false,

    // Strip data-testid attributes from JSX in production
    reactRemoveProperties: isProd
      ? { properties: ['^data-testid$'] }
      : false,

    // Enable styled-components SWC plugin
    styledComponents: true,
  },
};

export default config;

SWC Minification vs Terser

Next.js 15 uses SWC for minification by default (swcMinify: true is now the implicit default). This replaces Terser, the JavaScript-based minifier that was standard for years.

Benchmark comparison on a medium Next.js app (~300 modules):

  • Terser: ~18 seconds minification during next build
  • SWC minifier: ~3 seconds — roughly 6× faster

SWC minification is also scope-aware and performs dead-code elimination (DCE) at the module level. Combined with tree-shaking from the bundler, this means unused exports that Terser might have kept can be eliminated.

If you encounter an edge case where SWC minification produces incorrect output (rare but possible), you can opt back to Terser:

// next.config.ts — only needed if SWC minifier causes issues
import type { NextConfig } from 'next';

const config: NextConfig = {
  // Explicitly disable SWC minification and fall back to Terser
  swcMinify: false,
};

export default config;

// Alternatively, to tune SWC minification behavior:
// (no direct config exposed yet — SWC minifier config is internal)
// The recommended approach is to leave swcMinify: true (default)
// and report any correctness bugs to the Next.js GitHub repo.

Bundle Analyzer: Visualizing What You Ship

Before optimizing bundle size, you need to see it. The @next/bundle-analyzer package wraps webpack-bundle-analyzer and integrates it with Next.js builds.

After setup, running ANALYZE=true next build opens an interactive treemap in your browser showing every module and its contribution to each JS chunk.

What to look for:

  • Large node_modules — e.g. moment.js (>70 KB gzipped) when you only need date formatting. Replace with date-fns or native Intl.DateTimeFormat.
  • Duplicate packages — two versions of react or lodash appearing in the treemap signals a resolution conflict.
  • Server vs Client chunks — code that belongs on the server leaking into the client bundle (e.g. a DB client).

Note: bundle-analyzer currently works with the Webpack build (next build without --turbopack). A Turbopack-native analyzer is on the roadmap.

// next.config.ts
import type { NextConfig } from 'next';
import bundleAnalyzer from '@next/bundle-analyzer';

const withBundleAnalyzer = bundleAnalyzer({
  enabled: process.env.ANALYZE === 'true',
  openAnalyzer: true,
});

const config: NextConfig = {
  // ... your other config
};

export default withBundleAnalyzer(config);

// package.json script:
// "analyze": "ANALYZE=true next build"

Turbopack Persistent Cache Configuration

Turbopack's persistent cache stores transform and bundling artifacts in .next/cache/turbopack. On a second next dev run (or in CI after cache restoration), Turbopack reads from disk instead of recomputing — dramatically reducing cold-start time for CI pipelines.

Key behaviors to understand:

  • The cache is content-addressed: a file's cache key is a hash of its content plus the content of all its dependencies. You will never get a stale cache hit.
  • The cache directory can grow large over time. next dev has a built-in LRU eviction policy, but you can wipe it manually with rm -rf .next/cache/turbopack.
  • In CI, cache the .next/cache directory between runs. GitHub Actions example:
# .github/workflows/ci.yml (relevant excerpt)
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Restore Next.js cache
        uses: actions/cache@v4
        with:
          path: |
            ~/.npm
            ${{ github.workspace }}/.next/cache
          key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/*.ts','**/*.tsx') }}
          restore-keys: |
            ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-

      - run: npm ci
      - run: npm run build

Controlling Code Splitting and Chunk Strategy

Next.js automatically code-splits at the route level (each page gets its own JS chunk), but you can further influence splitting with two techniques:

1. Dynamic imports (next/dynamic) — lazily load heavy components so they are excluded from the initial page bundle. This is the primary tool for reducing First Load JS.

2. optimizePackageImports — a Next.js 15 config option that tells the compiler to tree-shake specific packages that don't have proper ESM exports. Libraries like lucide-react, @radix-ui/*, and icon packs often benefit from this.

Both techniques work with Turbopack and Webpack. optimizePackageImports is especially powerful because it requires zero changes to your import statements — it's purely a bundler hint.

// next.config.ts
import type { NextConfig } from 'next';

const config: NextConfig = {
  // Tell the compiler to tree-shake these packages
  // even if they lack proper ESM export maps
  experimental: {
    optimizePackageImports: [
      'lucide-react',
      '@radix-ui/react-icons',
      'recharts',
      '@heroicons/react',
    ],
  },
};

export default config;

// In your component — no change needed:
// import { ChevronRight, User } from 'lucide-react';
// Only ChevronRight and User are bundled, not the full icon library.

Measuring Build Performance with next build --profile

When build times spike unexpectedly, Next.js provides built-in profiling to pinpoint bottlenecks. Two flags are most useful:

  • next build --profile — emits a React profiler trace and a .cpuprofile file you can open in Chrome DevTools to see which transforms or plugins are consuming time.
  • NEXT_TELEMETRY_DEBUG=1 next build — prints detailed timing breakdowns per phase (compilation, type checking, static generation, etc.) to stdout.

For Turbopack specifically, the --turbopack flag surfaces compile times per route segment in the terminal output. A single route taking disproportionately long often indicates a missing resolveAlias causing Turbopack to traverse a deep relative path on every HMR cycle.

Practical workflow: run with profiling → identify the slowest phase → apply the relevant config change → re-measure. Never guess at optimizations on a complex bundler.

// scripts/build-perf.ts — a small helper to time build phases
// Run with: npx ts-node scripts/build-perf.ts

import { execSync } from 'child_process';

function timed(label: string, cmd: string): void {
  const start = Date.now();
  console.log(`\n>>> Starting: ${label}`);
  try {
    execSync(cmd, { stdio: 'inherit', env: { ...process.env } });
  } catch {
    console.error(`[FAILED] ${label}`);
    process.exit(1);
  }
  const elapsed = ((Date.now() - start) / 1000).toFixed(2);
  console.log(`<<< Done: ${label} in ${elapsed}s`);
}

timed('Type check', 'npx tsc --noEmit');
timed('Next.js build', 'npx next build');

Knowledge Check: Turbopack Loaders vs Webpack Loaders

Test your understanding of the key difference between Turbopack's loader system and Webpack's loader system in Next.js 15.

Lesson Recap: Turbopack and Compiler Configuration

In this lesson you explored the full compiler and bundler configuration stack in Next.js 15:

  • Turbopack architecture — incremental computation, parallel Rust workers, and persistent disk caching make it dramatically faster than Webpack for development workflows.
  • turbopack config block — use rules for file-level transforms, resolveAlias for module path shortcuts, and keep tsconfig.json paths in sync to avoid type/bundle mismatches.
  • SWC as the transformer — distinct from Turbopack (the bundler), SWC handles TS stripping, JSX, and minification. A .babelrc in your project silently disables SWC.
  • compiler options — removeConsole, reactRemoveProperties, and CSS-in-JS plugins are configured at the top-level compiler key, not inside turbopack.
  • Bundle analysis — use @next/bundle-analyzer to visualize chunk composition and catch large dependencies or server-code leaking into client bundles.
  • optimizePackageImports — a zero-touch hint that enables tree-shaking for packages with poor ESM export maps.
  • CI caching — cache .next/cache between runs to leverage Turbopack's persistent cache and cut CI build times significantly.

The key mental model: Turbopack owns the graph, SWC owns the files, and next.config.ts is the single control plane for both.

البدء مجانًا

تعلم TypeScript مع معلم ذكاء اصطناعي — مجانًا

اكتب وقم بتشغيل أكوادك الفعلية في المتصفح، واحصل على مساعدة فورية من معلم ذكاء اصطناعي متاح 24/7، واستمر من حيث توقفت على الويب أو في التطبيق.

الدورات
22
الدروس
88

الأسئلة الشائعة

هل درس «تعمّق في إعدادات Turbopack والمترجم» مجاني؟

نعم — نص درس «تعمّق في إعدادات Turbopack والمترجم» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Next.js 15 Fullstack (App Router + Server Actions)، انتقل إلى CoddyKit PRO. تتضمن دورة Next.js 15 Fullstack (App Router + Server Actions) 4 دروس في المجموع.

ماذا ستتعلم في «تعمّق في إعدادات Turbopack والمترجم»؟

اضبط Turbopack والتحويلات والمترجم المستند إلى SWC لتسريع عمليات البناء وتقليص المخرجات. تتمرن على Next.js 15 Fullstack (App Router + Server Actions) مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Next.js 15 Fullstack (App Router + Server Actions)؟

لا تُشترط خبرة سابقة. Next.js 15 Fullstack (App Router + Server Actions) على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.

كم من الوقت يستغرق درس «تعمّق في إعدادات Turbopack والمترجم»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Next.js 15 Fullstack (App Router + Server Actions) هذا؟

نعم. كل درس في Next.js 15 Fullstack (App Router + Server Actions) يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. تحليل حزمة العميل وتقليصها
  2. تعمّق في إعدادات Turbopack والمترجم
  3. حدود الوحدات باستخدام server-only وclient-only
  4. الاستيرادات الديناميكية وتقسيم الشيفرة والتحميل التدريجي
← العودة إلى Next.js 15 Fullstack (App Router + Server Actions)