目录
Webpack简介
Webpack是现代JavaScript应用程序的静态模块打包工具。当Webpack处理应用程序时,它会在内部构建一个依赖图,映射项目所需的每个模块,然后生成一个或多个bundle。
为什么需要Webpack
- 模块化开发支持
- 资源处理能力
- 开发效率提升
- 生产环境优化
Webpack与其他构建工具的对比
工具 | 特点 | 适用场景 |
---|---|---|
Webpack | 功能全面、生态丰富 | 中大型项目 |
Vite | 开发启动快、热更新快 | 现代化项目 |
Rollup | 打包体积小、配置简单 | 库开发 |
Parcel | 零配置、开箱即用 | 小型项目 |
安装与基础配置
安装Webpack
bash
# 本地安装webpack和webpack-cli
npm install webpack webpack-cli --save-dev
基础配置文件
webpack.config.js:
javascript
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
mode: 'development'
};
项目结构示例
my-webpack-project/
├── node_modules/
├── src/
│ ├── index.js
│ └── utils.js
├── dist/
├── webpack.config.js
└── package.json
核心概念
入口(Entry)
指定webpack开始构建的起点:
javascript
module.exports = {
entry: './src/index.js'
};
多入口配置:
javascript
module.exports = {
entry: {
app: './src/app.js',
admin: './src/admin.js'
}
};
输出(Output)
配置打包结果的输出位置和命名方式:
javascript
module.exports = {
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash].js'
}
};
模式(Mode)
设置开发环境或生产环境:
javascript
module.exports = {
mode: 'development' // 或 'production'
};
模块(Module)和解析规则
javascript
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: 'babel-loader'
}
]
},
resolve: {
extensions: ['.js', '.jsx', '.json']
}
};
Loader详解
Loader用于转换特定类型的模块,如将ES6转为ES5、将CSS转为JavaScript可用的格式等。
常用Loader
JavaScript处理
javascript
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}
样式处理
javascript
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
文件处理
javascript
{
test: /\.(png|jpg|gif|svg)$/,
use: {
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'images/'
}
}
}
高级用法:链式Loader
javascript
{
test: /\.scss$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: true
}
},
'sass-loader'
]
}
Plugin系统
插件用于执行范围更广的任务,如打包优化、资源管理、环境变量注入等。
常用Plugin
HtmlWebpackPlugin
javascript
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
filename: 'index.html'
})
]
};
MiniCssExtractPlugin
javascript
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
plugins: [
new MiniCssExtractPlugin({
filename: '[name].[contenthash].css'
})
],
module: {
rules: [
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader'
]
}
]
}
};
DefinePlugin
javascript
const { DefinePlugin } = require('webpack');
module.exports = {
plugins: [
new DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production'),
'API_URL': JSON.stringify('https://api.example.com')
})
]
};
代码分割与懒加载
代码分割配置
javascript
module.exports = {
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all'
}
}
}
}
};
动态导入与懒加载
javascript
// 在用户点击按钮时才加载模块
button.addEventListener('click', () => {
import(/* webpackChunkName: "chart" */ './chart').then(module => {
const chart = module.default;
chart.init('container');
});
});
性能优化策略
体积优化
- 代码分割
- Tree Shaking
- 压缩代码
- 图片优化
javascript
module.exports = {
optimization: {
usedExports: true,
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
compress: {
drop_console: true,
},
},
}),
],
}
};
速度优化
- 缓存
- 多线程构建
- 减少解析范围
javascript
module.exports = {
cache: {
type: 'filesystem',
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: 'thread-loader',
options: {
workers: 4,
},
},
'babel-loader'
]
}
]
}
};
开发环境配置
开发服务器
javascript
module.exports = {
devServer: {
contentBase: './dist',
hot: true,
port: 3000,
proxy: {
'/api': {
target: 'http://localhost:8080',
pathRewrite: { '^/api': '' },
},
},
},
};
Source Maps
javascript
module.exports = {
devtool: 'eval-cheap-module-source-map',
};
热模块替换(HMR)
javascript
const webpack = require('webpack');
module.exports = {
devServer: {
hot: true,
},
plugins: [
new webpack.HotModuleReplacementPlugin()
]
};
生产环境部署
环境分离
javascript
// webpack.common.js - 公共配置
const commonConfig = {...};
// webpack.dev.js - 开发环境配置
const { merge } = require('webpack-merge');
const devConfig = merge(commonConfig, {
mode: 'development',
devtool: 'eval-cheap-module-source-map',
// 其他开发配置
});
// webpack.prod.js - 生产环境配置
const prodConfig = merge(commonConfig, {
mode: 'production',
optimization: {
// 生产环境优化配置
}
});
资源压缩与优化
javascript
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
optimization: {
minimizer: [
new CssMinimizerPlugin(),
new TerserPlugin()
]
}
};
常见部署策略
- CDN分发
- Gzip压缩
- 按需加载
- 预加载关键资源
实战案例
多页应用配置
javascript
module.exports = {
entry: {
home: './src/home.js',
about: './src/about.js',
contact: './src/contact.js'
},
output: {
filename: '[name].[contenthash].js',
path: path.resolve(__dirname, 'dist')
},
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']
})
]
};
React项目配置示例
javascript
module.exports = {
entry: './src/index.js',
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env',
'@babel/preset-react'
],
plugins: [
'@babel/plugin-transform-runtime'
]
}
}
},
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
}
]
},
resolve: {
extensions: ['.js', '.jsx']
}
};
微前端配置
javascript
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');
module.exports = {
plugins: [
new ModuleFederationPlugin({
name: 'app1',
filename: 'remoteEntry.js',
exposes: {
'./Header': './src/components/Header',
'./Footer': './src/components/Footer'
},
shared: ['react', 'react-dom']
})
]
};
结语
Webpack作为前端工程化的核心工具,通过其强大的模块打包能力,帮助开发者构建高效、可维护的前端项目。掌握Webpack不仅能够优化开发流程,还能提升应用性能,为用户提供更好的体验。