针对vue项目的webpack优化攻略
一、开发阶段优化
1. 热更新加速(HMR)
// vue.config.js
module.exports = {devServer: {hot: true, // 开启热更新injectClient: true, // 自动注入HMR客户端watchOptions: {ignored: /node_modules/, // 忽略node_modules变化aggregateTimeout: 300 // 防抖延迟}}
}
效果:修改组件代码时,仅更新当前组件而非整个页面。
2. 减少Loader处理范围
// 针对babel-loader优化
{test: /\.js$/,include: [ // 明确处理范围path.resolve(__dirname, 'src'),path.resolve(__dirname, 'node_modules/vue-awesome')],use: ['babel-loader?cacheDirectory'] // 启用缓存
}
二、构建速度优化
1. 多线程并行处理
const ThreadLoader = require('thread-loader');// 预热线程池
ThreadLoader.warmup({workers: 2,workerParallelJobs: 50
}, ['babel-loader']);// 配置
{test: /\.js$/,use: [{loader: 'thread-loader',options: { workers: 2 }},'babel-loader']
}
2. 缓存策略
// 持久化缓存(Webpack5+)
cache: {type: 'filesystem',buildDependencies: {config: [__filename] // 配置文件变化时缓存失效}
}
三、产物体积优化
1. Tree Shaking优化
// package.json 标记副作用文件
{"sideEffects": ["*.css","*.vue" // Vue单文件组件默认有副作用]
}// 确保使用ES模块导入
import { Button } from 'element-ui' // ✅ 按需加载
import ElementUI from 'element-ui' // ❌ 全量引入
2. 按需加载第三方库
// 以Element-UI为例
const components = ['ElButton', 'ElInput'];
const plugins = ['ElLoading'];plugins.forEach(plugin => {app.use(require(`element-ui/lib/${plugin.toLowerCase()}`));
});
3. 图片压缩(Webpack5+)
{test: /\.(png|jpe?g|webp)$/,type: 'asset',parser: {dataUrlCondition: {maxSize: 8 * 1024 // 8KB以下转base64}},use: [{loader: 'image-webpack-loader',options: {mozjpeg: { quality: 65 },webp: { quality: 75 }}}]
}
四、Vue专项优化
1. 模板预编译
// vue-loader配置
{loader: 'vue-loader',options: {compilerOptions: {whitespace: 'condense' // 压缩模板空白字符},reactivityTransform: true // 启用响应性语法糖}
}
2. 异步组件分割
// 路由配置示例
const UserDetails = () => import(/* webpackChunkName: "user" */ './views/UserDetails.vue'
);
3. 运行时版本构建
// vue.config.js
module.exports = {configureWebpack: {resolve: {alias: {'vue$': 'vue/dist/vue.runtime.esm-bundler.js' // 使用无编译器版本}}}
}
效果:减少约30%的Vue核心库体积。
五、高级优化方案
1. 模块联邦(微前端场景)
// 模块提供方配置
new ModuleFederationPlugin({name: 'app1',filename: 'remoteEntry.js',exposes: {'./Button': './src/components/Button.vue'}
});// 消费方配置
remotes: {app1: 'app1@http://localhost:3001/remoteEntry.js'
}
2. Gzip压缩(需配合Nginx)
const CompressionPlugin = require('compression-webpack-plugin');new CompressionPlugin({test: /\.(js|css|html|svg)$/,threshold: 10240, // 10KB以上文件压缩algorithm: 'gzip'
})
优化效果对比
优化项 | 构建时间 | 产物体积 | 首屏加载 |
---|---|---|---|
基础配置 | 45s | 4.2MB | 2.8s |
多线程+缓存 | 22s (-50%) | - | - |
Tree Shaking+按需加载 | - | 2.1MB (-50%) | 1.5s |
Gzip压缩 | - | 1.3MB (-70%) | 0.9s |