刚开始接触Vue开发时,很多新手会直接用vue-cli创建一个基础项目就开始写代码。但随着项目规模扩大,你会发现代码越来越难维护,团队协作效率低下,构建速度也越来越慢。这就是为什么我们需要从一开始就搭建一个规范化的企业级开发环境。
企业级开发环境的核心价值在于:标准化、自动化和可维护性。它能帮我们解决以下问题:
我在多个Vue企业级项目中踩过不少坑,发现合理的工程化配置能节省至少30%的开发时间。下面我就带你从零搭建一个完整的Vue企业级开发环境。
首先确保你已安装Node.js(建议14.x以上版本)和Vue CLI:
bash复制npm install -g @vue/cli
vue create vue-enterprise-template
在选择配置时,建议手动选择特性(Manually select features),勾选:
对于代码规范,我强烈推荐选择ESLint + Prettier组合,它能自动格式化代码并检查潜在问题。配置方式选择"ESLint + Prettier",其他选项保持默认即可。
默认生成的目录结构对小型项目够用,但企业级项目建议调整为:
code复制├── public/ # 静态资源(不经过webpack处理)
├── src/
│ ├── assets/ # 静态资源(经过webpack处理)
│ ├── components/ # 公共组件
│ ├── composables/ # Vue3组合式API
│ ├── directives/ # 自定义指令
│ ├── router/ # 路由配置
│ ├── store/ # Vuex状态管理
│ ├── styles/ # 全局样式
│ ├── utils/ # 工具函数
│ ├── views/ # 页面级组件
│ ├── App.vue # 根组件
│ └── main.js # 入口文件
├── tests/ # 测试文件
├── .env.development # 开发环境变量
├── .env.production # 生产环境变量
└── vue.config.js # Vue CLI配置
这种结构更清晰,适合多人协作的大型项目。特别是将工具函数、自定义指令等单独分类,方便维护。
vue.config.js是Vue CLI的核心配置文件,我通常会做以下优化:
javascript复制const path = require('path')
module.exports = {
// 部署应用包时的基本URL
publicPath: process.env.NODE_ENV === 'production' ? '/production-sub-path/' : '/',
// 构建输出目录
outputDir: 'dist',
// 静态资源目录
assetsDir: 'static',
// 是否启用生产环境的source map
productionSourceMap: false,
// 开发服务器配置
devServer: {
port: 8080,
open: true,
proxy: {
'/api': {
target: process.env.VUE_APP_API_BASE_URL,
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}
}
},
// Webpack配置
configureWebpack: {
resolve: {
alias: {
'@': path.resolve(__dirname, 'src'),
'components': path.resolve(__dirname, 'src/components')
}
},
performance: {
hints: 'warning',
maxAssetSize: 244 * 1024, // 244 KiB
maxEntrypointSize: 244 * 1024 // 244 KiB
}
},
// CSS相关配置
css: {
extract: true,
sourceMap: false,
loaderOptions: {
scss: {
additionalData: `@import "~@/styles/variables.scss";`
}
}
},
// 第三方插件配置
pluginOptions: {
// 示例:i18n插件配置
i18n: {
locale: 'zh',
fallbackLocale: 'en',
localeDir: 'locales',
enableInSFC: true
}
}
}
企业项目通常需要区分开发、测试、生产环境。使用.env文件管理环境变量是最佳实践:
.env.development - 开发环境bash复制NODE_ENV=development
VUE_APP_API_BASE_URL=http://dev.api.example.com
VUE_APP_VERSION=1.0.0-dev
.env.production - 生产环境bash复制NODE_ENV=production
VUE_APP_API_BASE_URL=https://api.example.com
VUE_APP_VERSION=1.0.0
在代码中通过process.env.VUE_APP_*访问这些变量。注意:只有以VUE_APP_开头的变量才会被webpack打包进去。
在.eslintrc.js中,我会这样配置:
javascript复制module.exports = {
root: true,
env: {
node: true
},
extends: [
'plugin:vue/vue3-essential',
'eslint:recommended',
'@vue/prettier'
],
parserOptions: {
parser: 'babel-eslint'
},
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'vue/multi-word-component-names': 'off',
'prettier/prettier': [
'error',
{
singleQuote: true,
semi: false,
trailingComma: 'none',
printWidth: 100,
tabWidth: 2,
useTabs: false,
bracketSpacing: true,
arrowParens: 'avoid'
}
]
}
}
配合VS Code的ESLint和Prettier插件,可以实现保存时自动格式化。在.vscode/settings.json中添加:
json复制{
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"eslint.validate": ["javascript", "vue"],
"prettier.disableLanguages": ["vue"]
}
使用husky和lint-staged可以在提交代码前自动检查:
bash复制npm install husky lint-staged --save-dev
在package.json中添加:
json复制{
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"*.{js,vue}": [
"eslint --fix",
"prettier --write",
"git add"
]
}
}
这样每次提交前都会自动格式化代码并检查语法错误。
在vue.config.js中配置分包:
javascript复制configureWebpack: {
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
vendor: {
name: 'vendor',
test: /[\\/]node_modules[\\/]/,
priority: 10,
chunks: 'initial'
},
elementUI: {
name: 'element-ui',
test: /[\\/]node_modules[\\/]element-ui[\\/]/,
priority: 20
}
}
}
}
}
安装compression-webpack-plugin:
bash复制npm install compression-webpack-plugin --save-dev
然后在vue.config.js中配置:
javascript复制const CompressionPlugin = require('compression-webpack-plugin')
module.exports = {
configureWebpack: {
plugins: [
new CompressionPlugin({
algorithm: 'gzip',
test: /\.(js|css)$/,
threshold: 10240,
minRatio: 0.8
})
]
}
}
使用image-webpack-loader自动压缩图片:
bash复制npm install image-webpack-loader --save-dev
配置:
javascript复制chainWebpack: config => {
config.module
.rule('images')
.use('image-webpack-loader')
.loader('image-webpack-loader')
.options({
mozjpeg: { progressive: true, quality: 65 },
optipng: { enabled: false },
pngquant: { quality: [0.65, 0.9], speed: 4 },
gifsicle: { interlaced: false },
webp: { quality: 75 }
})
.end()
}
在src/utils/request.js中封装axios:
javascript复制import axios from 'axios'
import { Message } from 'element-ui'
const service = axios.create({
baseURL: process.env.VUE_APP_API_BASE_URL,
timeout: 10000
})
// 请求拦截器
service.interceptors.request.use(
config => {
// 添加token等逻辑
return config
},
error => {
return Promise.reject(error)
}
)
// 响应拦截器
service.interceptors.response.use(
response => {
const res = response.data
if (res.code !== 200) {
Message.error(res.message || 'Error')
return Promise.reject(new Error(res.message || 'Error'))
} else {
return res
}
},
error => {
Message.error(error.message)
return Promise.reject(error)
}
)
export default service
在src/components目录下创建index.js:
javascript复制import Vue from 'vue'
const requireComponent = require.context(
'./', // 组件目录
true, // 是否查询子目录
/\.vue$/ // 匹配组件文件名
)
requireComponent.keys().forEach(fileName => {
const componentConfig = requireComponent(fileName)
const componentName = fileName
.split('/')
.pop()
.replace(/\.\w+$/, '')
Vue.component(componentName, componentConfig.default || componentConfig)
})
然后在main.js中引入:
javascript复制import '@/components'
这样所有组件都会自动注册,无需手动import。
实现路由级别的权限控制:
javascript复制// router/index.js
router.beforeEach((to, from, next) => {
const hasToken = localStorage.getItem('token')
if (to.meta.requiresAuth && !hasToken) {
next('/login')
} else if (to.path === '/login' && hasToken) {
next('/')
} else {
next()
}
})
在路由配置中添加meta信息:
javascript复制{
path: '/admin',
component: () => import('@/views/Admin.vue'),
meta: { requiresAuth: true }
}
使用Jest进行单元测试,在jest.config.js中配置:
javascript复制module.exports = {
preset: '@vue/cli-plugin-unit-jest',
moduleFileExtensions: ['js', 'vue'],
transform: {
'^.+\\.vue$': 'vue-jest',
'^.+\\.js$': 'babel-jest'
},
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1'
},
testMatch: [
'**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)'
],
collectCoverage: true,
collectCoverageFrom: [
'src/**/*.{js,vue}',
'!src/main.js',
'!src/router/index.js',
'!**/node_modules/**'
]
}
在项目根目录创建.github/workflows/deploy.yml:
yaml复制name: Deploy
on:
push:
branches: [ main ]
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install dependencies
run: npm install
- name: Build
run: npm run build
- name: Deploy to Server
uses: appleboy/scp-action@master
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SERVER_SSH_KEY }}
source: "dist/"
target: "/var/www/html"
这套配置从项目初始化到最终部署,覆盖了企业级Vue开发环境的各个方面。实际项目中可以根据团队需求进行调整,但核心思路是保持一致性、自动化和可维护性。