生产环境下的Rollup打包流程
生产环境下的Rollup打包流程
Rollup作为现代前端构建工具,在Vite生产环境打包中扮演核心角色。相比开发环境,生产构建需要更严格的代码优化和资源处理。以下是完整的生产级Rollup配置示例:
// vite.config.js
import { defineConfig } from 'vite'
import legacy from '@vitejs/plugin-legacy'
export default defineConfig({
build: {
rollupOptions: {
input: {
main: 'src/main.js',
admin: 'src/admin-panel.js'
},
output: {
manualChunks: (id) => {
if (id.includes('node_modules')) {
return 'vendor'
}
},
chunkFileNames: 'assets/[name]-[hash].js',
entryFileNames: 'assets/[name]-[hash].js',
assetFileNames: 'assets/[name]-[hash][extname]'
}
},
minify: 'terser',
terserOptions: {
compress: {
drop_console: true
}
}
},
plugins: [
legacy({
targets: ['defaults', 'not IE 11']
})
]
})
多入口配置策略
生产环境通常需要处理多个入口点。在Rollup中通过input
对象配置:
rollupOptions: {
input: {
app: 'src/app.js',
dashboard: 'src/dashboard/main.js',
settings: 'src/user/settings.js'
}
}
对应的输出目录结构会自动生成:
dist/
├── assets/
│ ├── app-abc123.js
│ ├── dashboard-xyz456.js
│ └── settings-def789.js
└── index.html
代码分割最佳实践
有效的代码分割能显著提升加载性能。以下是常见策略:
- 手动分块:
manualChunks: {
lodash: ['lodash'],
react: ['react', 'react-dom'],
charting: ['echarts', 'd3']
}
- 动态导入自动分块:
// 在业务代码中使用
const module = await import('./heavy-module.js')
- CSS分块配置:
output: {
assetFileNames: (assetInfo) => {
if (assetInfo.name.endsWith('.css')) {
return 'css/[name]-[hash][extname]'
}
return 'assets/[name]-[hash][extname]'
}
}
高级优化技巧
Tree-shaking深度配置
treeshake: {
moduleSideEffects: (id) => !/\.css$/.test(id),
propertyReadSideEffects: false,
tryCatchDeoptimization: false
}
预编译依赖处理
optimizeDeps: {
include: [
'vue',
'vue-router',
'pinia',
'axios'
],
exclude: ['vue-demi']
}
性能调优实战
- 并行处理配置:
build: {
chunkSizeWarningLimit: 2000,
reportCompressedSize: false,
rollupOptions: {
maxParallelFileOps: 4,
output: {
sourcemap: false
}
}
}
- 缓存策略:
cacheDir: 'node_modules/.vite',
persistentCache: true
- 构建分析工具集成:
import visualizer from 'rollup-plugin-visualizer'
plugins: [
visualizer({
filename: 'bundle-analysis.html',
open: process.env.NODE_ENV !== 'CI'
})
]
安全加固措施
- 内容安全策略(CSP)处理:
server: {
headers: {
"Content-Security-Policy": "default-src 'self'"
}
}
- 依赖漏洞扫描:
npx vite-plugin-inspect
- 敏感信息过滤:
define: {
__API_KEY__: JSON.stringify(process.env.HIDDEN_API_KEY)
}
部署适配方案
CDN路径处理
base: 'https://cdn.example.com/assets/',
build: {
assetsInlineLimit: 4096
}
不同环境差异化配置
// vite.config.js
export default ({ mode }) => {
const env = loadEnv(mode, process.cwd())
return defineConfig({
define: {
__APP_ENV__: JSON.stringify(env.APP_ENV)
}
})
}
监控与日志
- 构建耗时分析:
import { timing } from 'vite-plugin-timing'
plugins: [
timing()
]
- 错误追踪集成:
rollupOptions: {
onwarn: (warning, warn) => {
if (warning.code === 'CIRCULAR_DEPENDENCY') {
trackBuildWarning(warning)
}
warn(warning)
}
}
现代浏览器特性利用
build: {
target: 'es2020',
polyfillModulePreload: false,
cssTarget: 'chrome80'
}
对应的browserslist配置:
{
"production": [
"last 2 Chrome versions",
"last 2 Safari versions",
"last 2 Firefox versions",
"edge >= 16"
]
}
自定义插件开发示例
实现一个简单的资源指纹插件:
import { createHash } from 'node:crypto'
export default function assetFingerprint() {
return {
name: 'asset-fingerprint',
generateBundle(options, bundle) {
for (const [fileName, asset] of Object.entries(bundle)) {
if (fileName.endsWith('.js')) {
const hash = createHash('sha256')
.update(asset.source)
.digest('hex')
.slice(0, 8)
asset.fileName = asset.fileName.replace(
/\.js$/,
`.${hash}.js`
)
}
}
}
}
}
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:前端编码规范