23 KiB
23 KiB
健身房管理系统前端工程化建设文档
文档编号: GYM-FE-ENG-001
版本: v1.0
日期: 2026-03-04
作者: 张翔
状态: 初稿
文档修订历史
| 版本 | 日期 | 作者 | 修订内容 |
|---|---|---|---|
| v1.0 | 2026-03-04 | 张翔 | 创建前端工程化建设文档 |
参考文档
- 《健身房管理系统前端技术架构详细设计》 GYM-FE-ARCH-001
- 《健身房管理系统前端开发规范》 GYM-FE-DEV-001
- Vite 官方文档
- GitHub Actions 文档
一、工程化概述
1.1 工程化目标
- 提高开发效率:自动化重复性工作,减少手动操作
- 保证代码质量:通过自动化检查和测试,确保代码质量
- 统一开发规范:通过工具强制执行代码规范
- 简化部署流程:自动化构建和部署,减少人为错误
- 提升团队协作:统一开发环境和工具链
1.2 工程化体系
┌─────────────────────────────────────────────────────────────────────────┐
│ 前端工程化体系 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ 开发工具链 │ │
│ ├─────────────────────────────────────────────────────────────────┤ │
│ │ • Node.js • npm/yarn • Git • VSCode │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ 构建工具 │ │
│ ├─────────────────────────────────────────────────────────────────┤ │
│ │ • Vite • TypeScript • ESLint • Prettier │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ 代码质量工具 │ │
│ ├─────────────────────────────────────────────────────────────────┤ │
│ │ • Husky • Commitlint • Lint-staged • Stylelint │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ 测试工具 │ │
│ ├─────────────────────────────────────────────────────────────────┤ │
│ │ • Vitest • Playwright • Coverage • Testing Library │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ CI/CD工具 │ │
│ ├─────────────────────────────────────────────────────────────────┤ │
│ │ • GitHub Actions • Docker • Nginx • CDN │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
二、构建工具配置
2.1 Vite配置
2.1.1 基础配置
// vite.config.ts
import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd())
return {
plugins: [vue()],
resolve: {
alias: {
'@': resolve(__dirname, 'src'),
'@components': resolve(__dirname, 'src/components'),
'@utils': resolve(__dirname, 'src/utils'),
'@api': resolve(__dirname, 'src/api'),
'@stores': resolve(__dirname, 'src/stores')
}
},
server: {
port: 5173,
host: true,
open: true,
proxy: {
'/api': {
target: env.VITE_API_BASE_URL,
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}
}
},
build: {
outDir: 'dist',
assetsDir: 'assets',
sourcemap: mode === 'development',
minify: 'terser',
terserOptions: {
compress: {
drop_console: mode === 'production',
drop_debugger: mode === 'production',
pure_funcs: mode === 'production' ? ['console.log', 'console.info'] : []
}
},
rollupOptions: {
output: {
manualChunks: {
'vue-vendor': ['vue', 'vue-router', 'pinia'],
'element-plus': ['element-plus'],
'utils': ['lodash-es', 'dayjs'],
'crypto': ['crypto-js', 'jsencrypt']
}
}
},
chunkSizeWarningLimit: 1000
},
css: {
preprocessorOptions: {
scss: {
additionalData: `@import "@/assets/styles/variables.scss";`
}
}
}
}
})
2.1.2 插件配置
// vite.config.ts
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import Compression from 'vite-plugin-compression'
import { visualizer } from 'rollup-plugin-visualizer'
export default defineConfig({
plugins: [
vue(),
AutoImport({
imports: ['vue', 'vue-router', 'pinia'],
dts: 'src/auto-imports.d.ts',
eslintrc: {
enabled: true
}
}),
Components({
resolvers: [ElementPlusResolver()],
dts: 'src/components.d.ts'
}),
Compression({
verbose: true,
disable: false,
threshold: 10240,
algorithm: 'gzip',
ext: '.gz'
}),
visualizer({
open: false,
gzipSize: true,
brotliSize: true
})
]
})
2.2 TypeScript配置
// tsconfig.json
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"module": "ESNext",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"skipLibCheck": true,
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "preserve",
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"baseUrl": ".",
"paths": {
"@/*": ["src/*"],
"@components/*": ["src/components/*"],
"@utils/*": ["src/utils/*"],
"@api/*": ["src/api/*"],
"@stores/*": ["src/stores/*"]
}
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
"references": [{ "path": "./tsconfig.node.json" }]
}
2.3 环境变量配置
// .env.development
VITE_APP_TITLE=健身房管理系统(开发环境)
VITE_API_BASE_URL=http://localhost:8080/api
VITE_UPLOAD_URL=http://localhost:8080/upload
VITE_WS_URL=ws://localhost:8080/ws
VITE_SENTRY_DSN=
VITE_CRYPTO_SECRET_KEY=your-secret-key-here
VITE_RSA_PUBLIC_KEY=your-rsa-public-key-here
// .env.production
VITE_APP_TITLE=健身房管理系统
VITE_API_BASE_URL=https://api.example.com/api
VITE_UPLOAD_URL=https://api.example.com/upload
VITE_WS_URL=wss://api.example.com/ws
VITE_SENTRY_DSN=https://xxx@sentry.io/xxx
VITE_CRYPTO_SECRET_KEY=your-production-secret-key-here
VITE_RSA_PUBLIC_KEY=your-production-rsa-public-key-here
// .env.staging
VITE_APP_TITLE=健身房管理系统(测试环境)
VITE_API_BASE_URL=https://staging-api.example.com/api
VITE_UPLOAD_URL=https://staging-api.example.com/upload
VITE_WS_URL=wss://staging-api.example.com/ws
VITE_SENTRY_DSN=https://xxx@sentry.io/xxx
VITE_CRYPTO_SECRET_KEY=your-staging-secret-key-here
VITE_RSA_PUBLIC_KEY=your-staging-rsa-public-key-here
三、代码规范工具
3.1 ESLint配置
// .eslintrc.json
{
"extends": [
"plugin:vue/vue3-recommended",
"plugin:@typescript-eslint/recommended",
"prettier",
"plugin:prettier/recommended"
],
"parser": "vue-eslint-parser",
"parserOptions": {
"ecmaVersion": "latest",
"parser": "@typescript-eslint/parser",
"sourceType": "module"
},
"plugins": ["vue", "@typescript-eslint", "prettier"],
"rules": {
"vue/multi-word-component-names": "off",
"vue/no-v-html": "warn",
"@typescript-eslint/no-explicit-any": "warn",
"@typescript-eslint/no-unused-vars": [
"error",
{
"argsIgnorePattern": "^_",
"varsIgnorePattern": "^_"
}
],
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"no-console": [
"warn",
{
"allow": ["warn", "error"]
}
],
"no-debugger": "error",
"prettier/prettier": "error"
}
}
3.2 Prettier配置
// .prettierrc
{
"semi": false,
"singleQuote": true,
"printWidth": 100,
"trailingComma": "es5",
"arrowParens": "avoid",
"endOfLine": "lf",
"tabWidth": 2,
"useTabs": false,
"bracketSpacing": true,
"jsxSingleQuote": false,
"proseWrap": "preserve"
}
3.3 Stylelint配置
// .stylelintrc.json
{
"extends": ["stylelint-config-standard", "stylelint-config-prettier"],
"rules": {
"selector-class-pattern": "^[a-z][a-zA-Z0-9-__]*$",
"selector-pseudo-class-no-unknown": [
true,
{
"ignorePseudoClasses": ["deep", "global"]
}
],
"selector-pseudo-element-no-unknown": [
true,
{
"ignorePseudoElements": ["v-deep", "v-global", "v-slotted"]
}
]
}
}
四、自动化工具
4.1 Husky配置
// package.json
{
"scripts": {
"prepare": "husky install",
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix",
"format": "prettier --write src/",
"lint:style": "stylelint \"src/**/*.{css,scss,vue}\" --fix"
}
}
# 初始化Husky
npx husky install
# 添加pre-commit钩子
npx husky add .husky/pre-commit "npx lint-staged"
# 添加commit-msg钩子
npx husky add .husky/commit-msg "npx commitlint --edit $1"
4.2 Lint-staged配置
// .lintstagedrc.json
{
"*.{js,jsx,ts,tsx,vue}": [
"eslint --fix",
"prettier --write"
],
"*.{css,scss,vue}": [
"stylelint --fix"
],
"*.{json,md}": [
"prettier --write"
]
}
4.3 Commitlint配置
// commitlint.config.js
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'type-enum': [
2,
'always',
['feat', 'fix', 'docs', 'style', 'refactor', 'perf', 'test', 'chore', 'ci']
],
'type-case': [2, 'always', 'lower-case'],
'type-empty': [2, 'never'],
'scope-case': [2, 'always', 'lower-case'],
'subject-case': [2, 'never', ['sentence-case', 'start-case', 'pascal-case', 'upper-case']],
'subject-empty': [2, 'never'],
'subject-full-stop': [2, 'never', '.'],
'header-max-length': [2, 'always', 100]
}
}
五、CI/CD流程
5.1 GitHub Actions配置
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run ESLint
run: npm run lint
- name: Run Prettier check
run: npm run format:check
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run unit tests
run: npm run test:unit
- name: Upload coverage
uses: codecov/codecov-action@v3
with:
files: ./coverage/coverage-final.json
fail_ci_if_error: true
build:
runs-on: ubuntu-latest
needs: [lint, test]
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
- name: Upload build artifacts
uses: actions/upload-artifact@v3
with:
name: dist
path: dist/
5.2 CD配置
# .github/workflows/cd.yml
name: CD
on:
push:
branches: [ main ]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
- name: Deploy to server
uses: easingthemes/ssh-deploy@v3
with:
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
REMOTE_HOST: ${{ secrets.REMOTE_HOST }}
REMOTE_USER: ${{ secrets.REMOTE_USER }}
TARGET: /var/www/gym-manage/frontend
SOURCE: dist/
六、项目脚手架
6.1 项目初始化
# 创建新项目
npm create vite@latest gym-manage-frontend -- --template vue-ts
# 进入项目目录
cd gym-manage-frontend
# 安装依赖
npm install
# 安装开发依赖
npm install -D \
@vitejs/plugin-vue \
unplugin-auto-import \
unplugin-vue-components \
sass \
eslint \
@typescript-eslint/parser \
@typescript-eslint/eslint-plugin \
eslint-plugin-vue \
prettier \
eslint-config-prettier \
eslint-plugin-prettier \
husky \
lint-staged \
@commitlint/cli \
@commitlint/config-conventional \
vitest \
@vue/test-utils \
@playwright/test \
rollup-plugin-visualizer \
vite-plugin-compression
# 安装生产依赖
npm install \
vue \
vue-router \
pinia \
axios \
dayjs \
lodash-es \
element-plus \
dompurify \
crypto-js \
jsencrypt \
web-vitals
6.2 目录结构初始化
# 创建目录结构
mkdir -p src/{api,assets/{images,icons,styles},components/{base,business,layout},composables,config,directives,hooks,layouts,router,stores,types,utils,views}
mkdir -p src/test/{unit,e2e}
mkdir -p public
# 创建配置文件
touch .env.development .env.production .env.staging
touch .eslintrc.json .prettierrc .stylelintrc.json
touch tsconfig.json tsconfig.node.json
6.3 基础文件创建
// src/main.ts
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import App from './App.vue'
import router from './router'
import './assets/styles/main.scss'
const app = createApp(App)
const pinia = createPinia()
app.use(pinia)
app.use(router)
app.use(ElementPlus)
app.mount('#app')
// src/App.vue
<template>
<router-view />
</template>
<script setup lang="ts">
</script>
<style>
#app {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
</style>
七、开发工具链
7.1 VSCode配置
// .vscode/settings.json
{
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true,
"source.fixAll.stylelint": true
},
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact",
"vue"
],
"typescript.tsdk": "node_modules/typescript/lib",
"volar.takeOverMode.enabled": true,
"[vue]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
}
// .vscode/extensions.json
{
"recommendations": [
"vue.volar",
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"stylelint.vscode-stylelint",
"bradlc.vscode-tailwindcss",
"eamodio.gitlens"
]
}
7.2 Git配置
# .gitignore
node_modules
dist
dist-ssr
*.local
.vscode/*
!.vscode/extensions.json
!.vscode/settings.json
.DS_Store
*.log
coverage
.nyc_output
.env.local
.env.*.local
7.3 NPM脚本
// package.json
{
"scripts": {
"dev": "vite",
"build": "vue-tsc && vite build",
"build:staging": "vue-tsc && vite build --mode staging",
"preview": "vite preview",
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix",
"lint:style": "stylelint \"src/**/*.{css,scss,vue}\" --fix",
"format": "prettier --write src/",
"format:check": "prettier --check src/",
"test": "vitest",
"test:unit": "vitest run",
"test:coverage": "vitest run --coverage",
"test:e2e": "playwright test",
"test:e2e:ui": "playwright test --ui",
"test:e2e:headed": "playwright test --headed",
"type-check": "vue-tsc --noEmit",
"prepare": "husky install"
}
}
八、最佳实践
8.1 依赖管理
8.1.1 依赖版本管理
// package.json
{
"dependencies": {
"vue": "^3.4.0",
"vue-router": "^4.2.0",
"pinia": "^2.1.0"
},
"devDependencies": {
"vite": "^5.0.0",
"typescript": "^5.0.0",
"eslint": "^8.56.0"
}
}
8.1.2 依赖安全检查
# 检查依赖漏洞
npm audit
# 自动修复依赖漏洞
npm audit fix
# 强制修复依赖漏洞
npm audit fix --force
8.2 性能监控
8.2.1 构建分析
# 生成构建分析报告
npm run build
# 查看分析报告
open stats.html
8.2.2 Bundle大小优化
// vite.config.ts
export default defineConfig({
build: {
rollupOptions: {
output: {
manualChunks: {
'vue-vendor': ['vue', 'vue-router', 'pinia'],
'element-plus': ['element-plus'],
'utils': ['lodash-es', 'dayjs']
}
}
},
chunkSizeWarningLimit: 500
}
})
8.3 文档管理
8.3.1 README文档
# 健身房管理系统前端
## 项目介绍
健身房管理系统前端项目,基于Vue3 + Vite + TypeScript构建。
## 技术栈
- Vue 3.4+
- TypeScript 5.0+
- Vite 5.0+
- Pinia 2.1+
- Element Plus 2.5+
## 快速开始
### 安装依赖
\`\`\`bash
npm install
\`\`\`
### 开发
\`\`\`bash
npm run dev
\`\`\`
### 构建
\`\`\`bash
npm run build
\`\`\`
### 测试
\`\`\`bash
npm run test
\`\`\`
## 项目结构
\`\`\`
src/
├── api/ # API接口
├── assets/ # 静态资源
├── components/ # 组件
├── composables/ # Composables
├── config/ # 配置
├── router/ # 路由
├── stores/ # 状态管理
├── types/ # 类型定义
├── utils/ # 工具函数
└── views/ # 页面
\`\`\`
## 开发规范
详见 [前端开发规范](./docs/design/前端开发规范.md)
## 许可证
MIT
8.3.2 CHANGELOG文档
# Changelog
## [1.0.0] - 2026-03-04
### Added
- 会员管理功能
- 课程预约功能
- 扫码签到功能
- 数据统计功能
### Changed
- 升级Vue到3.4版本
- 优化构建配置
### Fixed
- 修复预约时间冲突问题
- 修复签到记录显示问题
### Security
- 添加XSS防护
- 添加CSRF防护
九、总结
本文档详细描述了健身房管理系统前端的工程化建设,包括:
- 工程化概述:工程化目标、工程化体系
- 构建工具配置:Vite配置、TypeScript配置、环境变量配置
- 代码规范工具:ESLint配置、Prettier配置、Stylelint配置
- 自动化工具:Husky配置、Lint-staged配置、Commitlint配置
- CI/CD流程:GitHub Actions配置、CD配置
- 项目脚手架:项目初始化、目录结构初始化、基础文件创建
- 开发工具链:VSCode配置、Git配置、NPM脚本
- 最佳实践:依赖管理、性能监控、文档管理
通过遵循本文档的工程化建设指南,可以建立完善的前端工程化体系,提高开发效率、保证代码质量、简化部署流程。