دليل Webpack المختصر
Webpack - Static Module Bundler
Webpack هو أداة لتجميع الوحدات الثابتة للتطبيقات JavaScript الحديثة. عندما يعالج webpack تطبيقك، يبني داخليًا رسم بياني للاعتماديات من نقطة دخول واحدة أو أكثر، ثم يجمع كل الوحدات التي يحتاجها مشروعك في حزمة واحدة أو أكثر.
[No text to translate]جدول المحتويات
- التثبيت
- التكوين الأساسي
- نقاط الدخول
- المخرجات
- المحملات
- الإضافات
- الوضع
- خادم التطوير
- تقسيم الكود
- التحسين
- حل الوحدات
- استبدال الوحدة الساخن
- متغيرات البيئة
- بناء الإنتاج
- التكوين المتقدم
- الأداء
- استكشاف الأخطاء وإصلاحها
- أفضل الممارسات
Would you like me to continue with the remaining sections once you provide the specific text for sections 4-20?```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
module.exports = {
entry: './src/index.js'
};
Multiple Entry Points
module.exports = {
entry: {
main: './src/index.js',
vendor: './src/vendor.js'
}
};
Dynamic Entry Points
module.exports = {
entry: () => {
return {
main: './src/index.js',
admin: './src/admin.js'
};
}
};
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
module.exports = {
mode: 'development',
devtool: 'eval-source-map'
};
Production Mode
module.exports = {
mode: 'production',
devtool: 'source-map'
};
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
module.exports = {
devServer: {
static: './dist',
port: 3000,
open: true
}
};
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
module.exports = {
entry: {
main: './src/index.js',
vendor: './src/vendor.js'
}
};
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()
]
}
};
```### إزالة الشجرة (Tree Shaking)
```javascript
module.exports = {
mode: 'production',
optimization: {
usedExports: true,
sideEffects: false
}
};
```### كتلة وقت التشغيل (Runtime Chunk)
```javascript
module.exports = {
optimization: {
runtimeChunk: 'single'
}
};
```### تجميع الوحدات (Module Concatenation)
```javascript
module.exports = {
optimization: {
concatenateModules: true
}
};
```## حل الوحدات (Module Resolution)
```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')
]
}
};
```### تكوين الحل (Resolve Configuration)
```javascript
module.exports = {
resolve: {
fallback: {
"fs": false,
"path": require.resolve("path-browserify"),
"crypto": require.resolve("crypto-browserify")
}
}
};
```### الحل الاحتياطي (Resolve Fallback)
```javascript
const webpack = require('webpack');
module.exports = {
devServer: {
hot: true
},
plugins: [
new webpack.HotModuleReplacementPlugin()
]
};
```## استبدال الوحدة الساخنة (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
});
}
```### تمكين HMR (Enable 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 في الكود (HMR in Code)
```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')
})
]
};
```### إعادة التحميل الساخن لـ 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'
)
})
]
};
};
```## المتغيرات البيئية (Environment Variables)
```javascript
const Dotenv = require('dotenv-webpack');
module.exports = {
plugins: [
new Dotenv({
path: './.env',
safe: true,
systemvars: true
})
]
};
```### DefinePlugin للمتغيرات البيئية (DefinePlugin for Environment Variables)
```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'
}
};
```### تكوين خاص بالبيئة (Environment-specific Configuration)
```json
{
"scripts": {
"build": "webpack --mode production",
"build:analyze": "webpack --mode production --env analyze",
"build:stats": "webpack --mode production --json > stats.json"
}
}
```### DotEnv Plugin
```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']
})
]
};
```## البناء الإنتاجي (Production Build)
```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'
}
})
]
};
```### تكوين الإنتاج (Production Configuration)
```javascript
const WorkboxPlugin = require('workbox-webpack-plugin');
module.exports = {
plugins: [
new WorkboxPlugin.GenerateSW({
clientsClaim: true,
skipWaiting: true
})
]
};
```### سكريبتات البناء (Build Scripts)
```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')
}
]
}
};
```## التكوين المتقدم (Advanced Configuration)
```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()
]
};
```### تطبيق متعدد الصفحات (Multi-page Application)
```javascript
module.exports = {
performance: {
maxAssetSize: 250000,
maxEntrypointSize: 250000,
hints: 'warning'
}
};
```### تكوين الميكرو-واجهات الأمامية (Micro-frontends Configuration)
Would you like me to complete the translations with the full text content?```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'
);
```### الاسترداد المسبق والتحميل المسبق
```javascript
// Prefetch
import(
/* webpackPrefetch: true */
'./modules/LoginModal.js'
);
// Preload
import(
/* webpackPreload: true */
'./modules/ChartingLibrary.js'
);
```### تحليل الحزمة
```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
```## استكشاف المشكلات وحلها
```javascript
// Check resolve configuration
module.exports = {
resolve: {
extensions: ['.js', '.jsx', '.ts', '.tsx'],
alias: {
'@': path.resolve(__dirname, 'src')
}
}
};
```### المشكلات الشائعة والحلول
```bash
# 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"
}
}
```#### Module Not Found
```javascript
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'
]
}
]
}
};
```#### مشاكل الذاكرة
```javascript
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
};
```#### أوقات بناء بطيئة
```javascript
module.exports = {
stats: {
colors: true,
modules: false,
children: false,
chunks: false,
chunkModules: false
}
};
```#### مشاكل Source Map
```javascript
// 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'
});
```### تكوين التصحيح