从一次真实项目重构说起:如何从零开始构建一个现代化前端项目
开篇:为什么我要写这篇文章?

大家好,我是一名在一线干了五年的前端工程师。这五年里,我经历过初创团队的“敏捷狂奔”,也体验过大型企业的规范体系。但印象最深的一次,是前年我接手一个全新的项目——说是新项目,其实更像是个半成品改造工程。
客户给了我们一段老旧的 Vue2 代码库,功能基本跑通了,但结构混乱、性能差、维护困难。我们的任务是从头开始重建这个系统,目标不仅是提升用户体验,还要为未来的持续迭代打下基础。
这篇文章就围绕那次重构经历展开。希望通过我的个人视角和真实工作场景,带你了解一个现代前端项目究竟是怎么一步步搭起来的。
问题描述:项目初期面临的挑战


我们接收到的原始项目,存在几个明显的问题:
- 技术栈落后:基于 Vue2 + Webpack3,部分依赖版本陈旧,升级难度大。
- 代码结构混乱:所有组件都放在一起,没有清晰的分层设计。
- 缺乏工程化支持:没有统一的 lint 规范、测试覆盖、构建流程。
- 用户体验差:首屏加载慢、交互响应延迟,页面抖动严重。
- 协作困难:多人开发时容易产生冲突,代码风格不一致。
这些痛点让整个团队举步维艰。项目上线时间紧迫,我们只能边开发边重构,压力山大。
解决方案:选择合适的技术栈与架构设计


首先,我们明确了技术选型的方向:
技术栈升级
- 主框架切换为 Vue3(Composition API)
- 比起 Options API 更易维护,适合中大型项目
- 配合 TypeScript 使用更爽(后文详细说)
- 构建工具换为 Vite
- 开发服务器启动快,热更新秒级响应
- 支持开箱即用的 TS、JSX、CSS预处理器等
- 状态管理采用 Pinia 替代 Vuex
- API简洁,模块化自然,TS友好
- UI库选用 Element Plus
- 官方支持 Vue3,社区活跃
- 样式方案使用 Sass + BEM + CSS Modules 混合策略
- 组件内样式隔离,全局变量统一管理
架构设计思路
我们将项目划分为以下几个核心层级:
src/
├── assets/ # 图片、字体等资源
├── components/ # 可复用的基础 UI 组件
├── layouts/ # 页面布局组件,如 Header、Sidebar 等
├── pages/ # 路由页面组件
├── router/ # Vue Router 配置文件
├── services/ # 接口服务层,封装 axios 请求
├── stores/ # Pinia 存储定义
├── utils/ # 工具类方法
├── views/ # 页面模板目录(早期习惯叫法)
└── App.vue & main.ts # 入口文件
这种分层方式让职责划分清晰,每个角色都能快速定位到自己的工作区域。
代码实践:关键配置与代码片段分享
初始化项目结构
使用 Vite 快速创建项目:
npm create vite@latest my-project --template vue-ts
cd my-project
npm install
安装常用依赖:
npm install -D sass sass-loader autoprefixer postcss cssnano pinia element-plus unplugin-vue-components @vitejs/plugin-vue @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint prettier eslint-config-prettier husky lint-staged
配置 ESLint + Prettier + Husky
在 eslint 和 prettier 的配合上,我们做了一些取舍,最终选择了这样的 .eslintrc.js:
// .eslintrc.js
module.exports = {
root: true,
env: {
browser: true,
es2021: true,
node: true
},
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'prettier'
],
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint', 'vue'],
rules: {
// 自定义一些规则,例如:
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
}
};
结合 husky 和 lint-staged,我们配置了 commit 前自动格式化并校验代码,极大提升了代码质量。
路由 + 布局设计
在 Vue Router 中,我们采用了懒加载的方式引入路由组件,并按模块组织路由:
// src/router/modules/user.ts
export default {
path: '/user',
name: 'User',
component: () => import('@/layouts/AdminLayout.vue'),
children: [
{
path: 'list',
name: 'UserList',
component: () => import('@/pages/user/ListPage.vue')
}
]
}
这种方式可以让我们在后续扩展更多模块时,保持结构整洁。
异常处理机制
针对接口请求失败的情况,我们统一封装了一个拦截器:
// src/services/request.ts
import axios from 'axios'
const service = axios.create({
baseURL: import.meta.env.VITE_API_BASE_URL || '/api',
timeout: 10000
})
service.interceptors.response.use(
response => {
const { data } = response
if (data.code !== 200) {
// 这里可以抛出错误或者调用全局提示
console.error(data.message)
return Promise.reject(new Error(data.message))
}
return data
},
error => {
// 处理网络错误或超时
console.error('API Error:', error.message)
return Promise.reject(error)
}
)
export default service
踩坑经验:那些让人崩溃又成长的瞬间
1. 升级带来的 Typescript 类型问题
当我们从 Vue2 切换到 Vue3 + TypeScript 后,第一关就是类型定义。
比如以前随便写的组件 props,现在都需要写明 interface。刚开始大家都抱怨:“又要加类型?好麻烦!”
但我们坚持下来,反而发现好处多多:
- 编译阶段就能捕获潜在的 bug
- IDE 自动补全更好用了
- 接口文档可以直接从类型推导出来
所以我的建议是:拥抱 TypeScript,别怕前期的学习成本。
2. 生产环境打包体积爆炸问题
Vite 默认的打包策略对于复杂项目来说可能会生成非常大的 bundle 文件。
我们在部署时发现首次加载超过 5MB,加载时间感人。
后来我们做了几件事情:
- 使用
rollup的手动分包配置,在vite.config.ts中增加:
build: {
rollupOptions: {
output: {
manualChunks(id) {
if (id.includes('node_modules')) {
return id.toString().split("node_modules/")[1].split("/")[0]
}
}
}
}
}
- 对第三方库进行按需导入,借助
unplugin-auto-import和unplugin-vue-components实现按需自动导入组件和 API。
优化后首屏 JS 打包到 400KB 左右,速度快了不少。
3. 开发环境本地代理配置踩坑
Vite 提供了代理配置功能,但是刚接入的时候经常遇到代理失效的问题。
最后发现是因为 vite.config.js 里的 proxy 设置只对 /api 开头的路径生效,而某些接口请求路径是 /rest/login,没有走代理,导致跨域报错。
解决办法是在请求拦截器中判断当前环境动态拼接 URL。
效果总结:重构后的成果与收益
经过两个月的集中开发和重构,项目终于上线,效果远超预期:
- 首屏加载时间从原来的 4s+ 缩短到 1.2s
- 构建效率从 8min 缩短到 1.5min
- 团队协作顺畅,代码 review 时间减少一半
- 用户反馈卡顿情况大幅下降
- 支持未来新增模块变得轻松
更重要的是,我们建立了一套完整的工程化流程,包括:
- Git Commit Hooks 校验
- GitHub Actions CI 流程
- 包含 E2E 测试的自动化测试体系(未完全展开)
- 微前端集成能力预留
经验分享:给读者的几点建议
如果你也在准备搭建一个现代化前端项目,这里是一些实用的小建议:
✅ 选好骨架很重要
- Vue3 + Vite 是目前主流组合,值得投入
- 技术选型要综合考虑团队熟悉度、生态成熟度和长期维护能力
- 尽早加入 TypeScript,避免后期反向适配
🧱 重视项目结构设计
- 不要一开始就盲目追求“高内聚低耦合”,但要有清晰的层次感
- 可以模仿流行的开源项目(如 Ant Design Pro、Vite + Vue3 官方模板)
🔍 性能优化不是上线后的事
- 从第一天就要关注加载速度、包大小、渲染效率
- 使用 Lighthouse、Performance 工具定期评估
- 能懒加载的尽量懒加载,非必要内容推迟加载
🛠️ 工具链决定效率上限
- 熟悉 Vite 插件系统,掌握常见插件的用法(比如自动导入、图标库、mock)
- 善于利用 DevTools 调试技巧,节省排查 bug 时间
- 提前配置好自动化测试(推荐 Cypress / Playwright 做 E2E)
👩💻 团队协作才是长久之计
- 制定统一的编码规范,接入 EditorConfig + Prettier + ESLint
- 合理使用 Git hooks 避免垃圾代码进入仓库
- 写文档不要怕烦,特别是组件说明、API 接口定义
结语:构建一个项目,就像搭建一座房子
这次重构项目的过程,对我而言不仅是一个技术上的挑战,更是一种认知的升级。前端开发早已不再只是“写 JS 和 CSS”,而是一个涉及工程化、性能、用户体验、安全等多维度的综合性工程。
希望这篇带着个人实战经验的文章,能够帮你少走一点弯路。毕竟我们每天面对的不是完美的理想世界,而是一个个充满现实问题的业务需求。而这,也正是前端开发的魅力所在吧。
如果你也在做类似的项目,欢迎留言交流,一起进步!

评论 0