Webpack 构建优化以及打包优化

本文讲解 Webpack 的核心优化策略。

目录


1. Webpack 打包原理

1.1 打包过程

入口文件 → 依赖分析 → 模块打包 → 代码分割 → 输出资源

1.2 核心概念

概念 说明
Entry 入口,构建起点
Output 输出,打包后的位置
Module 模块,处理的基本单位
Chunk 代码块,多个模块组合
Bundle 打包后的最终文件

2. 代码分割

2.1 为什么需要代码分割?

所有代码打包成一个文件,用户需要下载所有代码,即使只用其中一小部分。

2.2 配置示例

module.exports = { optimization: { splitChunks: { chunks: 'all', cacheGroups: { vendors: { test: /[\\/]node_modules[\\/]/, name: 'vendors' }, common: { name: 'common', minChunks: 2 } } } } }

2.3 动态导入

// 方式一 const loadAbout = () => import('./About.vue') // 方式二 const loadHome = () => import(/* webpackChunkName: "home" */'./Home.vue') // Vue Router const routes = [ { path: '/', component: () => import('./views/Home.vue') } ]

3. Tree Shaking

3.1 原理

通过静态分析移除未使用的代码。

3.2 前提条件

  • 使用 ESM 的 import/export
  • package.json 标记无副作用
  • production 模式自动开启

3.3 配置副作用

// package.json { "sideEffects": false // 整个包无副作用 } // 或指定某些文件 { "sideEffects": ["*.css", "*.scss"] }

4. 懒加载

4.1 作用

只在需要时才加载代码,提升首屏加载速度。

4.2 实现方式

// 箭头函数 const loadComponent = () => import('./Component.vue') // 预加载 import(/* webpackPrefetch: true */'./NextPage.js')

5. 缓存优化

5.1 构建缓存

module.exports = { cache: { type: 'filesystem', buildDependencies: { config: [__filename] } } }

5.2 浏览器缓存

module.exports = { output: { filename: '[name].[contenthash:8].js' } }
哈希类型 说明
[hash] 项目级别,任何变化都变
[chunkhash] chunk 级别
[contenthash] 文件内容级别

6. 压缩优化

6.1 JavaScript 压缩

const TerserPlugin = require('terser-webpack-plugin') module.exports = { optimization: { minimize: true, minimizer: [ new TerserPlugin({ terserOptions: { compress: { drop_console: true } } }) ] } }

6.2 Gzip 压缩

const CompressionPlugin = require('compression-webpack-plugin') module.exports = { plugins: [ new CompressionPlugin({ algorithm: 'gzip', test: /\.(js|css|html)$/, threshold: 10240 }) ] }

7. 构建速度优化

7.1 缩小构建范围

module.exports = { module: { rules: [ { test: /\.js$/, include: path.resolve(__dirname, 'src'), exclude: /node_modules/ } ] } }

7.2 多进程构建

const HappyPack = require('happypack') module.exports = { plugins: [ new HappyPack({ threads: 4 }) ] }

8. 实战配置

const isProd = process.env.NODE_ENV === 'production' module.exports = { mode: isProd ? 'production' : 'development', output: { filename: isProd ? '[name].[contenthash:8].js' : '[name].js', publicPath: '/' }, resolve: { alias: { '@': path.resolve(__dirname, 'src') } }, optimization: { minimize: isProd, splitChunks: { chunks: 'all', cacheGroups: { vendors: { test: /[\\/]node_modules[\\/]/, name: 'vendors' } } } }, plugins: isProd ? [ new TerserPlugin({ parallel: true }), new CompressionPlugin() ] : [] }

总结

优化方向 策略 效果
代码分割 SplitChunks、动态导入 减少首次加载
Tree Shaking 移除未使用代码 减小体积
懒加载 路由级、组件级 提升首屏速度
缓存优化 构建缓存、contenthash 加快二次构建
压缩优化 Terser、Gzip 减小文件大小
构建速度 多进程、缩小范围 加快构建

先用 BundleAnalyzer 分析,再针对性优化。