DevToolBoxGRATIS
Blog

Guía de Configuración Webpack 5: Loaders, Plugins, Code Splitting

13 minpor DevToolBox

Webpack 5 sigue siendo el bundler dominante para aplicaciones de produccion a gran escala. Esta guia cubre desde loaders basicos hasta tecnicas de optimizacion avanzadas.

Conceptos basicos de Webpack 5 y entry/output

El archivo webpack.config.js controla todo el comportamiento de 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,
  },
};

Loaders esenciales

Los loaders transforman archivos antes de agregarlos al grafo de dependencias.

// 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 y carga diferida

El code splitting es la caracteristica de optimizacion mas importante de 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
  },
};

Optimizacion de produccion

Las builds de produccion requieren optimizacion agresiva.

// 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),
};

Preguntas frecuentes

Cuando usar Webpack en lugar de Vite?

Elige Webpack para Module Federation, grandes codebases existentes o soporte IE11.

Como analizar el tamano del bundle Webpack?

Usa webpack-bundle-analyzer para visualizar que consume el tamano del bundle.

Que es Module Federation en Webpack 5?

Module Federation permite que multiples builds de Webpack compartan codigo en tiempo de ejecucion.

Por que mi build de Webpack es tan lenta?

Causas comunes: sin cache persistente, demasiados loaders, babel sin excluir node_modules.

Herramientas relacionadas

𝕏 Twitterin LinkedIn
¿Fue útil?

Mantente actualizado

Recibe consejos de desarrollo y nuevas herramientas.

Sin spam. Cancela cuando quieras.

Prueba estas herramientas relacionadas

{ }JSON FormatterJSJavaScript Minifier

Artículos relacionados

Desarrollo de Plugins Vite: Crear Plugins Personalizados desde Cero 2026

Aprender a crear plugins Vite personalizados 2026: hooks, API transform, módulos virtuales, HMR.

Webpack vs Vite 2026: ¿Cuál herramienta de build elegir?

Comparación completa de Webpack y Vite en 2026: rendimiento, ecosistema y estrategias de migración.

Herramientas Monorepo 2026: Turborepo vs Nx vs Lerna vs pnpm Workspaces

Comparación completa de herramientas monorepo 2026: Turborepo, Nx, Lerna y pnpm workspaces para elegir la correcta.