Webpack Cheat Sheet¶
(Note: "Cheatsheet" is typically translated as "Hoja de referencia rápida")
Webpack - Static Module Bundler
Webpack es un empaquetador de módulos estáticos para aplicaciones JavaScript modernas. Cuando webpack procesa su aplicación, internamente construye un grafo de dependencias desde uno o más puntos de entrada y luego combina todos los módulos que su proyecto necesita en uno o más paquetes.
(This section appears to be empty in the original text)
Tabla de Contenidos¶
- Instalación
- Configuración Básica
- Puntos de Entrada
- Salida
- Cargadores
- Plugins
- Modo
- Servidor de Desarrollo
- División de Código
- Optimización
- Resolución de Módulos
- Reemplazo de Módulos en Caliente
- Variables de Entorno
- Compilación de Producción
- Configuración Avanzada
- Rendimiento
- Resolución de Problemas
- Mejores Prácticas
Would you like me to continue translating the rest of the document? If so, I'll need the specific text for sections 4-20 to provide accurate translations.```bash
Install webpack globally¶
npm install -g webpack webpack-cli
Check version¶
webpack --version
### Local Installation (Recommended)
```bash
# Initialize npm project
npm init -y
# Install webpack locally
npm install --save-dev webpack webpack-cli
# Install webpack dev server
npm install --save-dev webpack-dev-server
# Install common loaders and plugins
npm install --save-dev html-webpack-plugin css-loader style-loader file-loader url-loader
Package.json Scripts¶
{
"scripts": {
"build": "webpack --mode production",
"dev": "webpack --mode development",
"start": "webpack serve --mode development",
"watch": "webpack --mode development --watch"
}
}
Basic Configuration¶
Minimal webpack.config.js¶
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
}
};
Complete Basic Configuration¶
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.[contenthash].js',
path: path.resolve(__dirname, 'dist'),
clean: true
},
module: {
rules: [
{
test: /\.css$/i,
use: ['style-loader', 'css-loader']
},
{
test: /\.(png|svg|jpg|jpeg|gif)$/i,
type: 'asset/resource'
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
]
};
TypeScript Configuration¶
const path = require('path');
module.exports = {
entry: './src/index.ts',
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/
}
]
},
resolve: {
extensions: ['.tsx', '.ts', '.js']
},
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
}
};
Entry Points¶
Single Entry Point¶
Multiple Entry Points¶
Dynamic Entry Points¶
Entry with Dependencies¶
module.exports = {
entry: {
main: {
import: './src/index.js',
dependOn: 'shared'
},
admin: {
import: './src/admin.js',
dependOn: 'shared'
},
shared: 'lodash'
}
};
Output¶
Basic Output Configuration¶
const path = require('path');
module.exports = {
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
}
};
Multiple Entry Output¶
module.exports = {
entry: {
main: './src/index.js',
admin: './src/admin.js'
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
}
};
Output with Hashing¶
module.exports = {
output: {
filename: '[name].[contenthash].js',
path: path.resolve(__dirname, 'dist'),
clean: true
}
};
Public Path Configuration¶
module.exports = {
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
publicPath: '/assets/'
}
};
Library Output¶
module.exports = {
output: {
filename: 'my-library.js',
path: path.resolve(__dirname, 'dist'),
library: {
name: 'MyLibrary',
type: 'umd'
}
}
};
Loaders¶
CSS Loaders¶
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: ['style-loader', 'css-loader']
},
{
test: /\.s[ac]ss$/i,
use: ['style-loader', 'css-loader', 'sass-loader']
},
{
test: /\.less$/i,
use: ['style-loader', 'css-loader', 'less-loader']
}
]
}
};
JavaScript Loaders¶
module.exports = {
module: {
rules: [
{
test: /\.m?js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
},
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/
}
]
}
};
File Loaders¶
module.exports = {
module: {
rules: [
{
test: /\.(png|svg|jpg|jpeg|gif)$/i,
type: 'asset/resource'
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/i,
type: 'asset/resource'
},
{
test: /\.(csv|tsv)$/i,
use: ['csv-loader']
},
{
test: /\.xml$/i,
use: ['xml-loader']
}
]
}
};
Asset Modules¶
module.exports = {
module: {
rules: [
{
test: /\.png/,
type: 'asset/resource'
},
{
test: /\.html/,
type: 'asset/resource'
},
{
test: /\.txt/,
type: 'asset/source'
},
{
test: /\.jpg/,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 4 * 1024 // 4kb
}
}
}
]
}
};
Loader Options¶
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: true,
sourceMap: true
}
}
]
}
]
}
};
Plugins¶
HTML Webpack Plugin¶
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
filename: 'index.html',
inject: 'body'
})
]
};
Extract CSS Plugin¶
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, 'css-loader']
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name].[contenthash].css'
})
]
};
Define Plugin¶
const webpack = require('webpack');
module.exports = {
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production'),
'process.env.API_URL': JSON.stringify('https://api.example.com')
})
]
};
Copy Webpack Plugin¶
const CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = {
plugins: [
new CopyWebpackPlugin({
patterns: [
{ from: 'public', to: 'public' },
{ from: 'assets/images', to: 'images' }
]
})
]
};
Bundle Analyzer Plugin¶
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
plugins: [
new BundleAnalyzerPlugin({
analyzerMode: 'static',
openAnalyzer: false
})
]
};
Clean Webpack Plugin¶
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
plugins: [
new CleanWebpackPlugin()
]
};
Mode¶
Development Mode¶
Production Mode¶
Mode-specific Configuration¶
module.exports = (env, argv) => {
const isProduction = argv.mode === 'production';
return {
mode: argv.mode,
devtool: isProduction ? 'source-map' : 'eval-source-map',
optimization: {
minimize: isProduction
}
};
};
Development Server¶
Basic Dev Server¶
Advanced Dev Server Configuration¶
module.exports = {
devServer: {
static: {
directory: path.join(__dirname, 'dist')
},
compress: true,
port: 3000,
hot: true,
open: true,
historyApiFallback: true,
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}
}
}
};
HTTPS Dev Server¶
module.exports = {
devServer: {
https: true,
// or with custom certificates
https: {
key: fs.readFileSync('/path/to/server.key'),
cert: fs.readFileSync('/path/to/server.crt'),
ca: fs.readFileSync('/path/to/ca.pem')
}
}
};
Code Splitting¶
Entry Point Splitting¶
Dynamic Imports¶
// In your JavaScript code
import('./math.js').then(math => {
console.log(math.add(16, 26));
});
// Or with async/await
async function loadMath() {
const math = await import('./math.js');
return math.add(16, 26);
}
SplitChunks Plugin¶
module.exports = {
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all'
},
common: {
name: 'common',
minChunks: 2,
chunks: 'all',
enforce: true
}
}
}
}
};
Advanced Code Splitting¶
module.exports = {
optimization: {
splitChunks: {
chunks: 'all',
minSize: 20000,
maxSize: 244000,
cacheGroups: {
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true
},
vendor: {
test: /[\\/]node_modules[\\/]/,
priority: -10,
reuseExistingChunk: true
},
react: {
test: /[\\/]node_modules[\\/](react|react-dom)[\\/]/,
name: 'react',
chunks: 'all'
}
}
}
}
};
Optimization¶
Minification¶
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
compress: {
drop_console: true
}
}
})
]
}
};
CSS Optimization¶
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
module.exports = {
optimization: {
minimizer: [
new CssMinimizerPlugin()
]
}
};
```### Eliminación de Código Muerto (Tree Shaking)
```javascript
module.exports = {
mode: 'production',
optimization: {
usedExports: true,
sideEffects: false
}
};
```### Fragmento de Tiempo de Ejecución (Runtime Chunk)
```javascript
module.exports = {
optimization: {
runtimeChunk: 'single'
}
};
```### Concatenación de Módulos
```javascript
module.exports = {
optimization: {
concatenateModules: true
}
};
```## Resolución de Módulos
```javascript
const path = require('path');
module.exports = {
resolve: {
extensions: ['.js', '.jsx', '.ts', '.tsx', '.json'],
alias: {
'@': path.resolve(__dirname, 'src'),
'components': path.resolve(__dirname, 'src/components'),
'utils': path.resolve(__dirname, 'src/utils')
},
modules: [
'node_modules',
path.resolve(__dirname, 'src')
]
}
};
```### Configuración de Resolución
```javascript
module.exports = {
resolve: {
fallback: {
"fs": false,
"path": require.resolve("path-browserify"),
"crypto": require.resolve("crypto-browserify")
}
}
};
```### Resolución de Respaldo (Resolve Fallback)
```javascript
const webpack = require('webpack');
module.exports = {
devServer: {
hot: true
},
plugins: [
new webpack.HotModuleReplacementPlugin()
]
};
```## Reemplazo de Módulo Caliente (Hot Module Replacement)
```javascript
// In your JavaScript modules
if (module.hot) {
module.hot.accept('./library.js', function() {
console.log('Accepting the updated library module!');
// Re-render or update your app
});
}
```### Habilitar HMR
```javascript
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
module.exports = {
module: {
rules: [
{
test: /\.[jt]sx?$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
plugins: ['react-refresh/babel']
}
}
]
}
]
},
plugins: [
new ReactRefreshWebpackPlugin()
]
};
```### HMR en Código
```javascript
const webpack = require('webpack');
module.exports = {
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
'process.env.API_URL': JSON.stringify(process.env.API_URL || 'http://localhost:3000')
})
]
};
```### Recarga Caliente de React (React Hot Reload)
```javascript
module.exports = (env, argv) => {
const isProduction = argv.mode === 'production';
return {
mode: argv.mode,
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(argv.mode),
'process.env.API_URL': JSON.stringify(
isProduction ? 'https://api.production.com' : 'http://localhost:3000'
)
})
]
};
};
```## Variables de Entorno
```javascript
const Dotenv = require('dotenv-webpack');
module.exports = {
plugins: [
new Dotenv({
path: './.env',
safe: true,
systemvars: true
})
]
};
```### DefinePlugin para Variables de Entorno
```javascript
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
mode: 'production',
entry: './src/index.js',
output: {
filename: '[name].[contenthash].js',
path: path.resolve(__dirname, 'dist'),
clean: true
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader']
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
minify: {
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true
}
}),
new MiniCssExtractPlugin({
filename: '[name].[contenthash].css'
})
],
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
compress: {
drop_console: true
}
}
}),
new CssMinimizerPlugin()
],
splitChunks: {
chunks: 'all',
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all'
}
}
},
runtimeChunk: 'single'
}
};
```### Configuración Específica de Entorno
```json
{
"scripts": {
"build": "webpack --mode production",
"build:analyze": "webpack --mode production --env analyze",
"build:stats": "webpack --mode production --json > stats.json"
}
}
```### Plugin DotEnv
```javascript
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
home: './src/home.js',
about: './src/about.js',
contact: './src/contact.js'
},
plugins: [
new HtmlWebpackPlugin({
filename: 'home.html',
template: './src/home.html',
chunks: ['home']
}),
new HtmlWebpackPlugin({
filename: 'about.html',
template: './src/about.html',
chunks: ['about']
}),
new HtmlWebpackPlugin({
filename: 'contact.html',
template: './src/contact.html',
chunks: ['contact']
})
]
};
```## Compilación de Producción
```javascript
const ModuleFederationPlugin = require('@module-federation/webpack');
module.exports = {
plugins: [
new ModuleFederationPlugin({
name: 'shell',
remotes: {
mfe1: 'mfe1@http://localhost:3001/remoteEntry.js',
mfe2: 'mfe2@http://localhost:3002/remoteEntry.js'
}
})
]
};
```### Configuración de Producción
```javascript
const WorkboxPlugin = require('workbox-webpack-plugin');
module.exports = {
plugins: [
new WorkboxPlugin.GenerateSW({
clientsClaim: true,
skipWaiting: true
})
]
};
```### Scripts de Compilación
```javascript
// custom-loader.js
module.exports = function(source) {
// Transform the source
return `export default ${JSON.stringify(source)}`;
};
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.custom$/,
use: path.resolve(__dirname, 'custom-loader.js')
}
]
}
};
```## Configuración Avanzada
```javascript
class MyCustomPlugin {
apply(compiler) {
compiler.hooks.emit.tapAsync('MyCustomPlugin', (compilation, callback) => {
console.log('This is an example plugin!');
callback();
});
}
}
module.exports = {
plugins: [
new MyCustomPlugin()
]
};
```### Aplicación Multipágina
```javascript
module.exports = {
performance: {
maxAssetSize: 250000,
maxEntrypointSize: 250000,
hints: 'warning'
}
};
```### Configuración de Micro-frontends
```javascript
// Dynamic imports for lazy loading
const LazyComponent = React.lazy(() => import('./LazyComponent'));
// Webpack magic comments
import(
/* webpackChunkName: "my-chunk-name" */
/* webpackMode: "lazy" */
'./modules/my-module.js'
);
```### Prefetching and Preloading
```javascript
// Prefetch
import(
/* webpackPrefetch: true */
'./modules/LoginModal.js'
);
// Preload
import(
/* webpackPreload: true */
'./modules/ChartingLibrary.js'
);
```### Análisis de Bundle
```bash
# Generate stats file
webpack --profile --json > stats.json
# Analyze with webpack-bundle-analyzer
npx webpack-bundle-analyzer stats.json
# Use webpack-bundle-analyzer plugin
npm install --save-dev webpack-bundle-analyzer
```## Resolución de Problemas
### Problemas Comunes y Soluciones
#### Módulo No Encontrado
```javascript
// Check resolve configuration
module.exports = {
resolve: {
extensions: ['.js', '.jsx', '.ts', '.tsx'],
alias: {
'@': path.resolve(__dirname, 'src')
}
}
};
Problemas de Memoria¶
# Increase Node.js memory limit
node --max-old-space-size=4096 node_modules/.bin/webpack
# Or in package.json
{
"scripts": {
"build": "node --max-old-space-size=4096 node_modules/.bin/webpack"
}
}
Tiempos de Compilación Lentos¶
module.exports = {
// Use cache
cache: {
type: 'filesystem'
},
// Exclude node_modules from babel-loader
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: 'babel-loader'
}
]
},
// Use thread-loader for expensive loaders
module: {
rules: [
{
test: /\.js$/,
use: [
'thread-loader',
'babel-loader'
]
}
]
}
};
Problemas de Source Map¶
module.exports = {
// Different source map options
devtool: 'eval-source-map', // Development
devtool: 'source-map', // Production
devtool: 'cheap-module-source-map', // Faster builds
devtool: false // No source maps
};
Configuración de Depuración¶
module.exports = {
stats: {
colors: true,
modules: false,
children: false,
chunks: false,
chunkModules: false
}
};
Mejores Prácticas¶
Organización de Configuración¶
// webpack.common.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
]
};
// webpack.dev.js
const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');
module.exports = merge(common, {
mode: 'development',
devtool: 'eval-source-map',
devServer: {
static: './dist'
}
});
// webpack.prod.js
const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');
module.exports = merge(common, {
mode: 'production',
devtool: 'source-map'
});
Optimización de Rendimiento¶
- Usar modo de producción para optimizaciones
- Habilitar tree shaking para eliminar código muerto
- Dividir chunks para mejorar el caché
- Usar hash de contenido para caché a largo plazo
- Minimizar tamaño de bundle con loaders y plugins adecuados
Experiencia de Desarrollo¶
- Usar HMR para desarrollo más rápido
- Configurar source maps para depuración
- Configurar servidor de desarrollo con proxy para llamadas API
- Usar webpack-bundle-analyzer para entender la composición del bundle
Organización de Código¶
- Separar configuración para diferentes entornos
- Usar aliases para importaciones más limpias
- Organizar loaders por tipo de archivo
- Agrupar plugins relacionados
Resumen¶
Webpack es un potente y flexible module bundler que puede manejar requisitos de compilación complejos para aplicaciones web modernas. Características principales incluyen:
- Bundling de Módulos: Combina módulos en bundles optimizados
- Loaders: Transforman archivos durante el proceso de compilación
- Plugins: Extienden la funcionalidad de webpack
- Code Splitting: Divide código en chunks más pequeños para mejor rendimiento
- Hot Module Replacement: Actualiza módulos sin recargar la página
- Tree Shaking: Elimina código no utilizado de los bundles
- Gestión de Assets: Maneja diversos tipos de archivos y assets
Dominando la configuración de webpack y siguiendo mejores prácticas, puedes crear procesos de compilación eficientes que mejoran tanto la experiencia de desarrollo como el rendimiento de la aplicación.