第262集:Vue 3 Rollup高级配置
概述
Rollup是Vite的底层构建工具,提供了强大的模块打包能力。Vue 3项目可以通过Rollup进行高级配置,实现代码分割、tree shaking、构建优化和多格式输出等功能。本集将深入探讨Vue 3 Rollup的高级配置,包括代码分割策略、tree shaking优化、构建性能优化、多格式输出配置以及与Vite的集成,帮助开发者掌握Rollup的高级用法,优化Vue 3项目的构建流程。
Rollup基础回顾
Rollup是一个JavaScript模块打包工具,它将小块代码编译成大块复杂的代码,如库或应用程序。Rollup的主要特点包括:
- ES模块支持:原生支持ES模块
- tree shaking:自动移除未使用的代码
- 代码分割:支持动态导入和代码分割
- 插件系统:丰富的插件生态
- 多格式输出:支持多种输出格式
代码分割策略
代码分割是将代码库分割成多个较小的文件,以便按需加载,减少初始加载时间。Rollup支持多种代码分割策略:
1. 自动代码分割
Rollup会自动检测动态导入,将代码分割成多个块:
// rollup.config.js
export default {
input: 'src/main.js',
output: {
dir: 'dist',
format: 'esm',
manualChunks: {
// 手动配置代码分割
vue: ['vue'],
'vue-router': ['vue-router'],
pinia: ['pinia']
}
}
}2. 手动代码分割
使用manualChunks选项手动配置代码分割:
// rollup.config.js
export default {
input: 'src/main.js',
output: {
dir: 'dist',
format: 'esm',
manualChunks: (id) => {
// 根据文件路径手动分割代码
if (id.includes('node_modules')) {
if (id.includes('vue')) {
return 'vue-vendor'
} else if (id.includes('vue-router')) {
return 'vue-router-vendor'
} else if (id.includes('pinia')) {
return 'pinia-vendor'
} else {
return 'other-vendors'
}
}
}
}
}3. 动态导入
使用动态导入实现按需加载:
// src/router/index.js
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
history: createWebHistory(),
routes: [
{
path: '/',
component: () => import('../views/Home.vue') // 动态导入
},
{
path: '/about',
component: () => import('../views/About.vue') // 动态导入
}
]
})4. 共享模块
Rollup会自动处理共享模块,避免重复打包:
// rollup.config.js
export default {
input: 'src/main.js',
output: {
dir: 'dist',
format: 'esm',
// 配置共享模块
manualChunks: {
shared: ['lodash-es']
}
}
}Tree Shaking优化
Tree shaking是Rollup的核心特性之一,它可以自动移除未使用的代码,减小打包体积。
1. 配置tree shaking
// rollup.config.js
export default {
input: 'src/main.js',
output: {
dir: 'dist',
format: 'esm'
},
// 启用tree shaking
treeshake: {
// 启用模块级别的tree shaking
moduleSideEffects: false,
// 启用函数级别的tree shaking
propertyReadSideEffects: false
}
}2. 标记副作用
在package.json中使用sideEffects字段标记有副作用的文件:
// package.json
{
"name": "my-vue-package",
"sideEffects": [
"*.css",
"src/side-effectful-module.js"
]
}3. 优化tree shaking
- 使用ES模块语法
- 避免使用
require()和module.exports - 避免使用动态导入中的变量
- 使用
/*#__PURE__*/标记纯函数调用
4. 验证tree shaking效果
使用rollup-plugin-visualizer插件查看tree shaking效果:
// rollup.config.js
import { visualizer } from 'rollup-plugin-visualizer'
export default {
input: 'src/main.js',
output: {
dir: 'dist',
format: 'esm'
},
plugins: [
visualizer({
open: true,
gzipSize: true,
brotliSize: true
})
]
}构建性能优化
1. 缓存机制
使用cache选项启用构建缓存:
// rollup.config.js
export default {
input: 'src/main.js',
output: {
dir: 'dist',
format: 'esm'
},
// 启用缓存
cache: true
}2. 并行构建
使用rollup-plugin-parallel插件实现并行构建:
// rollup.config.js
import parallel from 'rollup-plugin-parallel'
export default {
input: 'src/main.js',
output: {
dir: 'dist',
format: 'esm'
},
plugins: [
parallel({
// 配置并行构建选项
watch: true
})
]
}3. 增量构建
使用rollup-plugin-incremental插件实现增量构建:
// rollup.config.js
import incremental from 'rollup-plugin-incremental'
export default {
input: 'src/main.js',
output: {
dir: 'dist',
format: 'esm'
},
plugins: [
incremental()
]
}4. 优化插件使用
- 只在必要时使用插件
- 了解插件的执行顺序
- 避免在插件中执行耗时操作
- 使用缓存优化插件性能
多格式输出配置
Rollup支持多种输出格式,包括ES模块、CommonJS、UMD等。
1. 基本多格式输出
// rollup.config.js
export default {
input: 'src/main.js',
output: [
{
file: 'dist/bundle.cjs.js',
format: 'cjs'
},
{
file: 'dist/bundle.esm.js',
format: 'esm'
},
{
file: 'dist/bundle.umd.js',
format: 'umd',
name: 'MyLibrary'
}
]
}2. 针对不同环境的输出
// rollup.config.js
export default {
input: 'src/main.js',
output: [
{
file: 'dist/bundle.development.js',
format: 'umd',
name: 'MyLibrary',
sourcemap: true
},
{
file: 'dist/bundle.production.js',
format: 'umd',
name: 'MyLibrary',
plugins: [terser()]
}
]
}3. 多入口输出
// rollup.config.js
export default {
input: {
main: 'src/main.js',
admin: 'src/admin.js'
},
output: {
dir: 'dist',
format: 'esm'
}
}Rollup与Vite集成
Vite基于Rollup,因此可以通过Vite配置文件配置Rollup选项。
1. 在Vite中配置Rollup
// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
build: {
// Vite构建选项
outDir: 'dist',
sourcemap: true,
// Rollup配置
rollupOptions: {
input: {
main: 'index.html',
admin: 'admin.html'
},
output: {
manualChunks: {
vue: ['vue'],
'vue-router': ['vue-router'],
pinia: ['pinia']
}
}
}
}
})2. 在Vite中使用Rollup插件
// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { visualizer } from 'rollup-plugin-visualizer'
export default defineConfig({
plugins: [vue()],
build: {
rollupOptions: {
plugins: [
visualizer({
open: true,
gzipSize: true
})
]
}
}
})3. Vite中的Rollup钩子
在Vite插件中可以使用Rollup钩子:
// vite-plugin-custom.js
export default {
name: 'vite-plugin-custom',
// Rollup钩子
transform(code, id) {
if (id.endsWith('.vue')) {
// 转换Vue文件
return code
}
return code
},
// Vite特定钩子
configureServer(server) {
// 配置开发服务器
}
}Rollup高级插件
1. rollup-plugin-terser
用于压缩代码:
// rollup.config.js
import terser from '@rollup/plugin-terser'
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.min.js',
format: 'esm',
plugins: [terser()]
}
}2. rollup-plugin-dynamic-import-variables
支持动态导入中的变量:
// rollup.config.js
import dynamicImportVariables from '@rollup/plugin-dynamic-import-variables'
export default {
input: 'src/main.js',
output: {
dir: 'dist',
format: 'esm'
},
plugins: [dynamicImportVariables()]
}3. rollup-plugin-alias
用于路径别名配置:
// rollup.config.js
import alias from '@rollup/plugin-alias'
export default {
input: 'src/main.js',
output: {
dir: 'dist',
format: 'esm'
},
plugins: [
alias({
entries: [
{ find: '@', replacement: 'src' }
]
})
]
}4. rollup-plugin-replace
用于替换代码中的变量:
// rollup.config.js
import replace from '@rollup/plugin-replace'
export default {
input: 'src/main.js',
output: {
dir: 'dist',
format: 'esm'
},
plugins: [
replace({
__VERSION__: '1.0.0',
__BUILD_TIME__: new Date().toISOString(),
preventAssignment: true
})
]
}Rollup配置最佳实践
1. 分离开发和生产配置
// rollup.config.js
import { defineConfig } from 'rollup'
import vue from 'rollup-plugin-vue'
import terser from '@rollup/plugin-terser'
const baseConfig = {
input: 'src/main.js',
plugins: [vue()]
}
export default defineConfig([
// 开发配置
{
...baseConfig,
output: {
dir: 'dist/dev',
format: 'esm',
sourcemap: true
}
},
// 生产配置
{
...baseConfig,
output: {
dir: 'dist/prod',
format: 'esm',
plugins: [terser()]
}
}
])2. 使用配置文件拆分
将配置拆分为多个文件,提高可维护性:
// rollup.config.base.js
export default {
input: 'src/main.js',
plugins: [vue()]
}
// rollup.config.dev.js
import baseConfig from './rollup.config.base.js'
export default {
...baseConfig,
output: {
dir: 'dist/dev',
format: 'esm',
sourcemap: true
}
}
// rollup.config.prod.js
import baseConfig from './rollup.config.base.js'
import terser from '@rollup/plugin-terser'
export default {
...baseConfig,
output: {
dir: 'dist/prod',
format: 'esm',
plugins: [terser()]
}
}3. 使用环境变量
// rollup.config.js
import { defineConfig } from 'rollup'
import replace from '@rollup/plugin-replace'
const isProduction = process.env.NODE_ENV === 'production'
export default defineConfig({
input: 'src/main.js',
output: {
dir: 'dist',
format: 'esm',
plugins: isProduction ? [terser()] : []
},
plugins: [
replace({
__ENV__: JSON.stringify(process.env.NODE_ENV),
preventAssignment: true
})
]
})4. 配置sourcemap
// rollup.config.js
export default {
input: 'src/main.js',
output: {
dir: 'dist',
format: 'esm',
// 配置sourcemap
sourcemap: true,
sourcemapExcludeSources: true,
sourcemapPathTransform: (relativeSourcePath) => {
// 转换sourcemap路径
return `../src/${relativeSourcePath}`
}
}
}总结
Rollup是Vue 3项目的重要构建工具,通过高级配置可以实现代码分割、tree shaking、构建优化和多格式输出等功能。本集介绍了Rollup的代码分割策略、tree shaking优化、构建性能优化、多格式输出配置以及与Vite的集成,同时还介绍了一些常用的Rollup高级插件和配置最佳实践。
通过掌握Rollup的高级配置,开发者可以更好地优化Vue 3项目的构建流程,减小打包体积,提高加载速度,同时提高开发效率。Rollup与Vite的结合使用,可以充分发挥两者的优势,为Vue 3项目提供强大的构建支持。
在下一集中,我们将探讨Vue 3自定义构建流程,包括npm脚本配置、自定义构建脚本、CI/CD集成和构建优化等内容,进一步深入了解Vue 3的构建工具链。