Vue多项目打包方案:环境变量与动态配置实践
1. Vue多项目打包方案概述
在大型前端工程实践中,经常会遇到需要基于同一套核心代码适配多个不同客户或场景的需求。传统做法是为每个项目单独维护代码分支,但这会导致维护成本呈指数级增长。通过Vue CLI的环境变量和构建配置,我们可以实现一套代码打包出多个定制化项目。
我最近在一个政府门户项目中实践了这套方案,需要为12个区县生成各自的门户网站。通过动态配置方案,我们将部署流程从原来的3天缩短到2小时,且实现了95%的代码复用率。下面分享具体实现方法。
2. 核心架构设计
2.1 环境变量分层管理
创建.env.[mode]文件是基础方案,但实际项目中需要更精细的控制:
.env # 全局默认配置 .env.development # 开发环境公共配置 .env.production # 生产环境公共配置 .env.[projectName] # 项目专属配置配置优先级规则:
- 项目专属配置 > 环境配置 > 全局配置
- 通过
--mode参数指定加载的配置文件
重要提示:永远不要在客户端代码中直接使用
process.env,应该通过VUE_APP_前缀暴露必要变量,其他敏感配置应该通过构建时注入。
2.2 动态Package.json策略
在monorepo中管理多项目时,package.json需要特殊处理:
// scripts/build.js const projects = ['projectA', 'projectB']; projects.forEach(project => { const packageJson = require(`./projects/${project}/package.json`); fs.writeFileSync('package.json', JSON.stringify({ ...baseConfig, ...packageJson, name: `${packageJson.name}-${project}` })); });这种方案在CI/CD流水线中特别有效,配合Jenkins的Matrix Job可以并行构建所有项目。
3. 完整实现步骤
3.1 初始化多环境配置
- 安装必要依赖:
npm install dotenv cross-env --save-dev- 创建环境文件示例:
# .env.projectA VUE_APP_API_BASE=https://api.projectA.com VUE_APP_TITLE=项目A VUE_APP_THEME=blue- 在vue.config.js中动态加载配置:
const env = require('dotenv').config({ path: `.env.${process.env.PROJECT_NAME}` });3.2 构建脚本优化
创建智能构建脚本build-all.js:
const { execSync } = require('child_process'); const projects = require('./projects-config.json'); projects.forEach(project => { console.log(`Building ${project.name}...`); execSync(`vue-cli-service build --mode ${project.env}`, { stdio: 'inherit' }); // 处理静态资源路径 fs.renameSync('dist', `dist-${project.name}`); });3.3 动态模板替换
对于差异较大的项目,可以使用EJS模板:
<!-- public/index.html --> <title><%= VUE_APP_TITLE %></title> <style> :root { --primary-color: <%= THEME_COLOR %>; } </style>在构建时通过插件处理:
// vue.config.js plugins: [ new HtmlWebpackPlugin({ templateParameters: { THEME_COLOR: process.env.VUE_APP_THEME_COLOR } }) ]4. 高级定制方案
4.1 按需加载组件
通过babel插件实现组件级定制:
// babel.config.js plugins: [ ['import', { libraryName: 'element-ui', customName: name => { if (process.env.VUE_APP_PROJECT === 'admin') { return `element-ui/lib/${name}`; } return `element-ui/lib/theme-chalk/${name}.css`; } }] ]4.2 运行时配置注入
对于需要动态切换的配置,可以使用public/config.js:
// 构建时生成 window.__APP_CONFIG__ = { apiBase: '<%= VUE_APP_API_BASE %>', features: { dashboard: <%= HAS_DASHBOARD %> } };在应用中通过axios.defaults.baseURL = window.__APP_CONFIG__.apiBase引用。
5. 常见问题解决方案
5.1 环境变量未生效
检查清单:
- 变量是否以
VUE_APP_开头 - 配置文件是否放在项目根目录
- 是否在
vue.config.js中正确加载 - 重启开发服务器(变量在启动时被固化)
5.2 样式污染问题
解决方案:
// 使用CSS Modules <style module> .container { /* 项目特有样式 */ } </style> // 或者使用scoped <style scoped> </style>5.3 构建产物过大
优化策略:
- 使用
--report参数分析包体积 - 配置splitChunks:
configureWebpack: { optimization: { splitChunks: { chunks: 'all', cacheGroups: { vendors: { test: /[\\/]node_modules[\\/]/, priority: -10 } } } } }6. 生产环境最佳实践
6.1 自动化部署流程
推荐使用Docker多阶段构建:
# 第一阶段:构建 FROM node:16 as builder ARG PROJECT_NAME COPY . . RUN npm install && npm run build -- --mode ${PROJECT_NAME} # 第二阶段:运行 FROM nginx:alpine COPY --from=builder /app/dist /usr/share/nginx/html COPY nginx.conf /etc/nginx/conf.d/default.conf6.2 版本控制策略
建议的目录结构:
projects/ ├── projectA/ │ ├── config/ │ ├── overrides/ ├── projectB/ │ ├── assets/ │ ├── locales/ shared/ ├── components/ ├── utils/使用git submodule或npm workspace管理公共依赖。
7. 性能优化技巧
7.1 构建缓存利用
配置持久化缓存:
// vue.config.js configureWebpack: { cache: { type: 'filesystem', buildDependencies: { config: [__filename] } } }7.2 差异化加载
根据项目特性动态加载polyfill:
// main.js if (process.env.VUE_APP_NEED_LEGACY) { import('@babel/polyfill').then(() => { initApp(); }); } else { initApp(); }8. 监控与维护
8.1 构建监控
在CI中添加检查:
# 检查包大小 npx bundlesize --max-size 500KB dist/*.js # 检查加载性能 npx lighthouse-ci --score=908.2 变更管理
建议使用变更日志:
## [1.2.0] - 2023-08-20 ### 新增 - 支持projectC的特殊主题配置 ### 变更 - 更新公共组件库到v2.3.1通过这套方案,我们成功将30多个政府门户网站的构建部署工作标准化。每个新项目的接入时间从原来的2周缩短到1天,且确保了核心功能的统一性。最大的收获是建立了可扩展的架构,能够快速响应各种定制化需求。