DevToolBoxFREE
BlogAdvertise

Guida alla Configurazione Webpack 5: Loaders, Plugin, Code Splitting

13 mindi DevToolBox

Webpack 5 rimane il bundler dominante per applicazioni di produzione su larga scala. Questa guida copre dai loader di base alle tecniche di ottimizzazione avanzate.

Basi di Webpack 5 ed entry/output

Il file webpack.config.js controlla tutto il comportamento di bundling.

// webpack.config.js โ€” Complete Production Config

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
const TerserPlugin = require('terser-webpack-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');

const isDev = process.env.NODE_ENV !== 'production';

module.exports = {
  mode: isDev ? 'development' : 'production',

  entry: {
    main: './src/index.tsx',
    // Multiple entry points for different pages
    // admin: './src/admin/index.tsx',
  },

  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: isDev ? '[name].js' : '[name].[contenthash:8].js',
    chunkFilename: isDev ? '[name].chunk.js' : '[name].[contenthash:8].chunk.js',
    assetModuleFilename: 'assets/[hash:8][ext][query]',
    clean: true,   // Remove old files on each build
    publicPath: '/',
  },

  resolve: {
    extensions: ['.tsx', '.ts', '.js', '.jsx', '.json'],
    alias: {
      '@': path.resolve(__dirname, 'src'),
      '@components': path.resolve(__dirname, 'src/components'),
    },
  },

  // Persistent filesystem cache โ€” huge speed improvement for incremental builds
  cache: {
    type: 'filesystem',
    buildDependencies: {
      config: [__filename], // Invalidate cache when config changes
    },
  },

  devServer: {
    port: 3000,
    hot: true,
    historyApiFallback: true,
    compress: true,
  },
};

Loader essenziali

I loader trasformano i file prima che vengano aggiunti al grafo delle dipendenze.

// Essential Webpack Loaders Configuration

module.exports = {
  module: {
    rules: [
      // 1. TypeScript/JavaScript with Babel
      {
        test: /\.(ts|tsx|js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: [
              ['@babel/preset-env', { targets: '>0.25%, not dead' }],
              ['@babel/preset-react', { runtime: 'automatic' }],
              '@babel/preset-typescript',
            ],
            // Cache Babel results for faster rebuilds
            cacheDirectory: true,
            cacheCompression: false,
          },
        },
      },

      // 2. CSS / SCSS / PostCSS
      {
        test: /\.module\.(css|scss)$/,  // CSS Modules
        use: [
          isDev ? 'style-loader' : MiniCssExtractPlugin.loader,
          {
            loader: 'css-loader',
            options: { modules: true, importLoaders: 2 },
          },
          'postcss-loader',
          'sass-loader',
        ],
      },
      {
        test: /(?!\.module)\.(css|scss)$/,  // Global CSS
        use: [
          isDev ? 'style-loader' : MiniCssExtractPlugin.loader,
          'css-loader',
          'postcss-loader',
          'sass-loader',
        ],
      },

      // 3. Images and fonts (Webpack 5 Asset Modules โ€” no loader needed)
      {
        test: /\.(png|jpg|jpeg|gif|webp)$/i,
        type: 'asset',  // Auto-chooses between inline and resource
        parser: {
          dataUrlCondition: { maxSize: 10 * 1024 }, // Inline if < 10KB
        },
      },
      {
        test: /\.svg$/,
        use: ['@svgr/webpack'],  // Import SVGs as React components
      },
      {
        test: /\.(woff|woff2|eot|ttf|otf)$/i,
        type: 'asset/resource',
      },
    ],
  },
};

Code splitting e lazy loading

Il code splitting รจ la funzione di ottimizzazione piรน importante di Webpack.

// Code Splitting and Lazy Loading

// 1. Dynamic imports (automatic code splitting)
// React.lazy creates a separate chunk for each lazy component
import React, { lazy, Suspense } from 'react';
import { Routes, Route } from 'react-router-dom';

const Dashboard = lazy(() => import('./pages/Dashboard'));
const Settings = lazy(() => import('./pages/Settings'));
const Analytics = lazy(() => import('./pages/Analytics'));

function App() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <Routes>
        <Route path="/dashboard" element={<Dashboard />} />
        <Route path="/settings" element={<Settings />} />
        <Route path="/analytics" element={<Analytics />} />
      </Routes>
    </Suspense>
  );
}

// 2. Manual chunk naming with magic comments
const HeavyChart = lazy(
  () => import(/* webpackChunkName: "charts" */ './components/HeavyChart')
);

// 3. Webpack SplitChunksPlugin configuration
module.exports = {
  optimization: {
    splitChunks: {
      chunks: 'all',
      cacheGroups: {
        // Vendor chunk: node_modules
        vendor: {
          test: /[\\/]node_modules[\\/]/,
          name: 'vendors',
          chunks: 'all',
          priority: 20,
        },
        // Separate React from other vendors
        react: {
          test: /[\\/]node_modules[\\/](react|react-dom|react-router)[\\/]/,
          name: 'react-vendor',
          chunks: 'all',
          priority: 30,
        },
        // Shared chunks used by 2+ modules
        common: {
          name: 'common',
          minChunks: 2,
          priority: 10,
          reuseExistingChunk: true,
        },
      },
    },
    runtimeChunk: 'single',  // Separate runtime chunk
  },
};

Ottimizzazione per la produzione

Le build di produzione richiedono un'ottimizzazione aggressiva.

// Production Optimization Configuration
module.exports = {
  optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin({
        parallel: true,  // Use all CPU cores
        terserOptions: {
          compress: {
            drop_console: true,    // Remove console.log in production
            drop_debugger: true,
            pure_funcs: ['console.log'],
          },
          format: { comments: false },
        },
      }),
      new CssMinimizerPlugin(),
    ],
    // Tree shaking โ€” only include used exports
    usedExports: true,
    sideEffects: true,  // Respect package.json sideEffects field
  },

  plugins: [
    new MiniCssExtractPlugin({
      filename: 'css/[name].[contenthash:8].css',
    }),
    new HtmlWebpackPlugin({
      template: './public/index.html',
      minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeAttributeQuotes: true,
      },
    }),
    // Only add analyzer when needed: ANALYZE=true npm run build
    process.env.ANALYZE && new BundleAnalyzerPlugin(),
  ].filter(Boolean),
};

Domande frequenti

Quando usare Webpack invece di Vite?

Scegli Webpack per Module Federation, codebase grandi esistenti, o supporto IE11.

Come analizzare le dimensioni del bundle Webpack?

Usa webpack-bundle-analyzer per visualizzare cosa consuma la dimensione del bundle.

Cos'รจ Module Federation in Webpack 5?

Module Federation permette a piรน build Webpack di condividere codice a runtime per i micro-frontend.

Perchรฉ la mia build Webpack รจ cosรฌ lenta?

Cause comuni: nessuna cache persistente, troppi loader, babel senza escludere node_modules.

Strumenti correlati

รˆ stato utile?

Stay Updated

Get weekly dev tips and new tool announcements.

No spam. Unsubscribe anytime.

Partner Picks

Sponsor this article

Place your product next to this developer topic with tracked clicks.

Ask about article sponsorship

Prova questi strumenti correlati

This site uses cookies for analytics and to display ads. By continuing to browse, you agree. Privacy Policy