文章目录
- 打包体积减少 80%!Webpack 极致优化全攻略
打包体积减少 80%!Webpack 极致优化全攻略
1. Webpack 基础概念与核心价值
1.1 什么是 Webpack?
Webpack 是一个现代 JavaScript 应用程序的静态模块打包器,它能够将各种资源(JS、CSS、图片、字体等)转换为依赖图并进行优化打包。
1.2 核心概念
- Entry(入口):构建的起始点
- Output(输出):打包后文件的存放位置
- Loaders(加载器):处理非 JS 文件
- Plugins(插件):执行更广泛的任务
- Mode(模式):开发或生产环境
- Module(模块):项目中的每个文件都是模块
2. 环境搭建与第一个配置
2.1 安装与初始化
# 创建项目目录
mkdir webpack-project && cd webpack-project
# 初始化 package.json
npm init -y
# 安装 webpack
npm install --save-dev webpack webpack-cli webpack-dev-server
# 查看版本
npx webpack --version
2.2 基础项目结构
webpack-project/
├── src/
│ ├── index.js
│ ├── utils.js
│ └── styles/
├── public/
│ └── index.html
├── dist/
├── webpack.config.js
└── package.json
2.3 第一个配置文件
// webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
// 入口文件
entry: './src/index.js',
// 输出配置
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.[contenthash].js',
clean: true, // 清理输出目录
},
// 模式
mode: 'development',
// 开发服务器
devServer: {
static: './dist',
port: 3000,
hot: true,
open: true,
},
// 插件
plugins: [
new HtmlWebpackPlugin({
template: './public/index.html',
title: 'Webpack App',
}),
],
};
3. 核心配置深度解析
3.1 多入口配置
module.exports = {
entry: {
main: './src/index.js',
admin: './src/admin.js',
vendor: './src/vendor.js'
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash].bundle.js',
chunkFilename: '[name].[contenthash].chunk.js',
},
};
3.2 环境变量配置
// webpack.config.js
const webpack = require('webpack');
module.exports = (env, argv) => {
const isProduction = argv.mode === 'production';
return {
mode: isProduction ? 'production' : 'development',
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(argv.mode),
'process.env.API_URL': JSON.stringify(
isProduction ? 'https://api.prod.com' : 'https://api.dev.com'
),
}),
],
};
};
4. 加载器(Loaders)完全指南
4.1 常用 Loaders 配置
module.exports = {
module: {
rules: [
// JavaScript/TypeScript
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env', '@babel/preset-react'],
},
},
},
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/,
},
// 样式文件
{
test: /\.css$/i,
use: ['style-loader', 'css-loader', 'postcss-loader'],
},
{
test: /\.s[ac]ss$/i,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: true,
},
},
'sass-loader',
],
},
// 资源文件
{
test: /\.(png|jpg|jpeg|gif|svg)$/i,
type: 'asset/resource',
generator: {
filename: 'images/[name].[contenthash][ext]',
},
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/i,
type: 'asset/resource',
generator: {
filename: 'fonts/[name].[contenthash][ext]',
},
},
],
},
};
4.2 自定义 Loader 开发
// loaders/simple-loader.js
module.exports = function(source) {
console.log('Processing file:', this.resourcePath);
// 简单的字符串替换
const result = source.replace(/console\.log\(.*\);/g, '');
// 可以返回多个结果
this.callback(null, result, sourceMaps, ast);
// 或者直接返回
// return result;
};
5. 插件(Plugins)高级应用
5.1 常用插件配置
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');
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
module.exports = {
plugins: [
new HtmlWebpackPlugin({
template: './public/index.html',
minify: isProduction,
inject: 'body',
}),
new MiniCssExtractPlugin({
filename: 'css/[name].[contenthash].css',
chunkFilename: 'css/[id].[contenthash].css',
}),
// 打包分析
new BundleAnalyzerPlugin({
analyzerMode: 'static',
openAnalyzer: false,
}),
// 自定义插件示例
function() {
this.hooks.done.tap('CustomPlugin', (stats) => {
console.log('构建完成!');
});
},
],
optimization: {
minimizer: [
new TerserPlugin({
parallel: true,
terserOptions: {
compress: {
drop_console: true,
},
},
}),
new CssMinimizerPlugin(),
],
},
};
5.2 自定义插件开发
// plugins/simple-plugin.js
class SimpleWebpackPlugin {
constructor(options) {
this.options = options || {};
}
apply(compiler) {
compiler.hooks.compilation.tap('SimplePlugin', (compilation) => {
compilation.hooks.optimizeChunkAssets.tapAsync(
'SimplePlugin',
(chunks, callback) => {
console.log('开始优化 chunks...');
callback();
}
);
});
compiler.hooks.done.tap('SimplePlugin', (stats) => {
console.log('构建完成,耗时:', stats.endTime - stats.startTime, 'ms');
});
}
}
module.exports = SimpleWebpackPlugin;
6. 开发环境优化
6.1 热更新配置
module.exports = {
devServer: {
static: {
directory: path.join(__dirname, 'public'),
},
compress: true,
port: 3000,
hot: true,
liveReload: true,
historyApiFallback: true,
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true,
pathRewrite: { '^/api': '' },
},
},
client: {
overlay: {
errors: true,
warnings: false,
},
},
},
// Source Map 配置
devtool: 'eval-cheap-module-source-map',
// 缓存配置
cache: {
type: 'filesystem',
buildDependencies: {
config: [__filename],
},
},
};
6.2 模块热替换(HMR)
// src/index.js
if (module.hot) {
module.hot.accept('./app.js', function() {
console.log('接受 app.js 模块的更新');
// 执行更新逻辑
});
module.hot.dispose(function(data) {
// 清理工作
});
}
7. 生产环境构建优化
7.1 代码分割与优化
module.exports = {
optimization: {
// 代码分割
splitChunks: {
chunks: 'all',
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
priority: 10,
reuseExistingChunk: true,
},
common: {
name: 'common',
minChunks: 2,
priority: 5,
reuseExistingChunk: true,
},
},
},
// 运行时 chunk
runtimeChunk: {
name: 'runtime',
},
// 模块 ID 优化
moduleIds: 'deterministic',
chunkIds: 'deterministic',
},
};
7.2 Tree Shaking 配置
module.exports = {
// 启用 Tree Shaking
mode: 'production',
optimization: {
usedExports: true,
sideEffects: false,
},
// package.json 中标记副作用
// "sideEffects": [
// "*.css",
// "*.scss"
// ]
};
8. 性能优化高级技巧
8.1 构建性能优化
module.exports = {
// 解析优化
resolve: {
extensions: ['.js', '.jsx', '.ts', '.tsx'],
alias: {
'@': path.resolve(__dirname, 'src'),
'components': path.resolve(__dirname, 'src/components'),
},
modules: [path.resolve(__dirname, 'node_modules')],
},
// 排除大型库
externals: {
react: 'React',
'react-dom': 'ReactDOM',
lodash: '_',
},
// 并行处理
parallelism: 4,
// 缓存
cache: {
type: 'filesystem',
version: '1.0',
buildDependencies: {
config: [__filename],
},
},
};
8.2 运行时性能优化
// 预加载和预获取
import(/* webpackPreload: true */ 'ChartingLibrary');
import(/* webpackPrefetch: true */ 'LoginModal');
// 动态导入
const LazyComponent = lazy(() => import('./LazyComponent'));
9. 微前端与现代化架构
9.1 Module Federation 配置
// host-app/webpack.config.js
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');
module.exports = {
plugins: [
new ModuleFederationPlugin({
name: 'host',
remotes: {
app1: 'app1@http://localhost:3001/remoteEntry.js',
app2: 'app2@http://localhost:3002/remoteEntry.js',
},
shared: {
react: { singleton: true },
'react-dom': { singleton: true },
},
}),
],
};
// remote-app/webpack.config.js
new ModuleFederationPlugin({
name: 'app1',
filename: 'remoteEntry.js',
exposes: {
'./Button': './src/Button',
'./Widget': './src/Widget',
},
shared: {
react: { singleton: true },
'react-dom': { singleton: true },
},
});
10. 自定义扩展与最佳实践
10.1 多环境配置管理
// webpack.common.js
const commonConfig = {
// 通用配置
};
// webpack.dev.js
const { merge } = require('webpack-merge');
module.exports = merge(commonConfig, {
mode: 'development',
// 开发环境特定配置
});
// webpack.prod.js
module.exports = merge(commonConfig, {
mode: 'production',
// 生产环境特定配置
});
10.2 构建监控与分析
// 构建速度分析
const SpeedMeasurePlugin = require('speed-measure-webpack-plugin');
const smp = new SpeedMeasurePlugin();
module.exports = smp.wrap({
// webpack 配置
});
// 打包体积分析
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
module.exports = {
plugins: [
new BundleAnalyzerPlugin({
analyzerMode: 'server',
analyzerPort: 8888,
}),
],
};
🎯 最佳实践总结
开发阶段
- 使用合适的 source map
- 启用 HMR 提高开发效率
- 配置合理的缓存策略
- 使用 webpack-dev-server
生产构建
- 代码分割和懒加载
- Tree Shaking 消除死代码
- 资源压缩和优化
- 长期缓存策略
性能优化
- 并行处理提升构建速度
- 合理使用 externals
- 模块联邦实现微前端
- 持续监控和分析
维护建议
- 配置文件模块化
- 版本控制和文档
- 团队规范统一
- 定期依赖更新
通过系统学习 Webpack 的配置和优化技巧,你将能够构建高效、可维护的前端应用架构,应对各种复杂的业务场景。这份指南涵盖了从基础到高级的完整知识体系,建议结合实际项目实践来深入掌握。

1959

被折叠的 条评论
为什么被折叠?



