从零开始构建一个现代化前端项目:我在实践中踩过的坑与经验总结

向量数据库猫
2025-06-26 00:08
阅读 756

开篇:为什么要重新思考“从零搭建”这件事?

去年年底,我接手了一个新的项目——为公司内部搭建一个全新的数据看板平台。这个项目没有历史包袱,完全是从零开始的。团队决定采用最前沿的技术栈,打造一个稳定、高效、可维护的系统。听起来挺理想化,但现实远比预期要复杂得多。

作为一名前端工程师,这并不是我第一次从零搭建项目,但这次的经历却格外深刻。从前端框架选择,到打包工具配置;从开发体验优化,到性能调优,每一个环节都充满了挑战和学习机会。

在这篇文章中,我会以第一人称的角度,分享这个项目从无到有的全过程。不只是告诉你“应该怎么做”,更重要的是我想让你知道,在真实工作中我们会遇到哪些问题、怎么解决它们,以及背后的一些决策逻辑。


问题描述:为什么说“从零开始”不是一件简单的事?

当我们说“从零开始”,很多人会下意识地想到创建一个 index.html 文件,然后引入几个 CDN 链接就开始开发了。但在企业级项目中,这种方式远远不够:

  • 代码结构混乱:随着功能变多,文件夹结构不清晰会导致协作困难
  • 开发效率低:缺乏模块化、热更新、代码校验等辅助工具
  • 构建流程缺失:无法压缩、拆包、按需加载等基本优化手段
  • 维护成本高:代码风格不一致、测试缺失,后续迭代变得痛苦

我们当时就面临着这些挑战。更棘手的是,项目需要支持 IE11(对,你没听错),同时又要兼顾移动端的响应式设计和良好的交互体验。技术选型必须在现代技术和兼容性之间取得平衡。


解决方案:选型与架构设计

1. 技术选型:Vue 还是 React?

最终我们选择了 Vue3 + TypeScript。理由如下:

  • Vue3 的 Composition API 让组件逻辑更加清晰,尤其适合中大型项目
  • Vue 官方生态相对完整(Vite、Vuex、Vue Router 等)
  • 团队成员已有一定的 Vue 使用经验,学习成本更低
  • Vue3 的 treeshaking 更彻底,有利于性能优化

TypeScript 是标配,它帮助我们在早期发现潜在错误,提高代码质量。

2. 构建工具选择:Vite vs Webpack

一开始想用 Webpack,毕竟它是老牌构建工具,社区成熟。但试了一圈之后发现启动慢、配置繁琐。特别是对于本地开发来说,每次启动都要等好几秒,严重影响效率。

后来我们果断切换到了 Vite。得益于 ES Modules 的原生支持,Vite 的本地开发服务器几乎是瞬时启动的,热更新速度也快很多。

3. 架构设计:项目目录结构

我们最终采用了类似这样的目录结构:

src/
├── assets/          // 静态资源
├── components/      // 公共组件
├── layouts/         // 页面布局
├── pages/           // 页面组件
├── router/          // 路由配置
├── store/           // Vuex 状态管理
├── services/        // 接口服务封装
├── utils/           // 工具函数
├── styles/          // 样式文件
├── App.vue
└── main.ts

这样的结构虽然看起来普通,但在实际开发中非常实用。比如,当你接手别人的页面时,只需要打开对应的 pages 文件夹就能找到所需的所有内容,大大降低了上手门槛。

前端性能优化图表-2


代码实践:关键代码片段与配置示例

1. Vite 配置示例(vite.config.ts)

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import tsconfigPaths from 'vite-tsconfig-paths'

export default defineConfig({
  plugins: [vue(), tsconfigPaths()],
  build: {
    outDir: 'dist',
    sourcemap: false,
    minify: true,
  },
  server: {
    port: 3000,
  },
})

2. ESLint + Prettier 配置(.eslintrc.js)

module.exports = {
  root: true,
  env: {
    browser: true,
    es2021: true,
    node: true,
  },
  extends: [
    'eslint:recommended',
    'plugin:vue/vue3-recommended',
    'plugin:@typescript-eslint/recommended',
    'prettier',
  ],
  parserOptions: {
    ecmaVersion: 2020,
    parser: '@typescript-eslint/parser',
    sourceType: 'module',
  },
  rules: {
    'vue/multi-word-component-names': 0,
    '@typescript-eslint/no-explicit-any': 0,
    'prefer-const': 1,
  },
}

3. 接口请求封装(services/request.ts)

import axios from 'axios'

const service = axios.create({
  baseURL: import.meta.env.VITE_API_URL as string,
  timeout: 5000,
})

service.interceptors.request.use(config => {
  const token = localStorage.getItem('token')
  if (token) {
    config.headers.Authorization = `Bearer ${token}`
  }
  return config
}, error => {
  Promise.reject(error)
})

service.interceptors.response.use(response => {
  if (response.data.code !== 200) {
    alert(response.data.message)
    return Promise.reject(new Error(response.data.message))
  }
  return response.data
}, error => {
  console.error('接口错误:', error)
  return Promise.reject(error)
})


![CSS动画效果展示-1](https://code-guide.oss.shanghai.autogptai.club/common/file/download?name=date2025062600/912e8ea8-28f7-4859-acc3-d7662ac834a1.jpg)


export default service

踩坑经验:那些年我们掉进去的坑

1. Vue3 + TypeScript 类型推断问题

在使用 Vue3 的 defineProps 时,如果我们不显式声明类型,TS 有时并不能正确推断出类型,导致 IDE 提示错误或者类型丢失。解决方案是在 .d.ts 文件中手动定义 interface 或者使用泛型方式明确指定类型。

// 错误写法
const props = defineProps({
  title: String,
})

// 正确写法
interface Props {
  title: string
}
const props = defineProps<Props>({
  title: String,
})

2. Vite 配置路径别名失效

这个问题让我一度怀疑人生。最后发现是忘记添加 tsconfig.json 中的 baseUrlpaths 设置,并且还需要安装插件 vite-tsconfig-paths 来启用路径解析。

{
  "compilerOptions": {
    "target": "ESNext",
    "useDefineForClassFields": true,
    "module": "ESNext",
    "lib": ["ESNext", "DOM"],
    "skipLibCheck": true,
    "outDir": "./dist",
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    }
  },
  "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
}

3. IE11 支持问题

虽然我们都想放弃 IE11,但在某些行业客户还在使用它。为了兼容 IE11,我们不得不引入额外的 polyfill 并修改 Babel 配置。

npm install --save @babel/polyfill regenerator-runtime core-js

Babel 配置:

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": {
          "ie": "11"
        },
        "useBuiltIns": "usage",
        "corejs": 3
      }
    ]
  ]
}

同时,Vue3 默认使用 Proxy,而 IE 不支持,所以我们还得加个 Polyfill:

import 'proxy-polyfill/proxy.min.js'

4. 打包体积过大

最初打包后的 vendor.js 居然有 6MB+!这明显不合理。通过使用 rollup-plugin-visualizer 分析后,我们发现主要问题是第三方库未被 Tree Shaking,如 moment、lodash 等。

最终我们做了以下优化:

  • moment 替换为轻量级的时间库 dayjs
  • lodash 使用按需引入
  • 开启 splitChunks 拆分 chunk
  • 添加 Gzip 压缩

优化后整体打包体积下降了 60% 以上。


效果总结:项目上线后的收获

经过两个多月的努力,项目终于上线了。用户反馈良好,后台数据显示首屏加载时间控制在 1.5 秒以内。代码结构清晰,团队协作顺畅,新同学入职也能很快上手。

回顾整个过程,最大的收益不是完成了一个项目,而是建立了一套可以复用的前端脚手架模板,包括:

  • 自动化的 CI/CD 流程
  • 统一的编码规范与代码检查机制
  • 完善的构建优化策略
  • 覆盖主流浏览器的兼容方案

这让之后的新项目起步变得异常轻松。


经验分享:给前端小伙伴的建议

如果你正准备从零开始搭建项目,这里是我的几点建议:

1. 不要急着写业务代码

前期花点时间把基础架构搭好,未来节省的时间可能远超你的想象。好的结构能支撑起长期维护,坏的结构会让你后悔当初偷懒。

2. 关注用户体验,不仅仅是功能

前端的本质是提供优秀的交互体验。哪怕是一个简单的按钮点击效果,也要考虑反馈是否自然,是否卡顿。细节做不到位,再高级的技术也救不了产品。

3. 合理评估技术选型的利弊

不要盲目追新。例如,Vue3 很好,但如果你的团队对它的 Composition API 不熟悉,那不如先从 Vue2 稳扎稳打开始。技术是为人服务的,不是用来炫技的。

4. 尽早接入自动化工具

  • Git Hooks 配合 lint-staged,确保每次提交的代码都有保障
  • 使用 Husky + Lint-staged 实现 commit 时自动格式化和代码校验
  • 配置 E2E 测试和单元测试,提升信心

5. 调试能力也是硬实力

掌握 Chrome DevTools 的各种技巧非常重要。比如:

  • Performance 面板分析加载瓶颈
  • Memory 面板排查内存泄漏
  • Source Map 映射源码调试
  • Network 面板查看接口请求状态

6. 保持开放心态,持续学习

前端技术变化太快,今天流行的明天可能就被淘汰。唯一不变的是我们解决问题的能力。建议每周至少抽出 1~2 小时,看看最新的技术文章或开源项目。


结语

这篇文章写了我不少深夜加班、抓耳挠腮的瞬间。但回头看,正是这些问题让我们变得更专业。希望我的经历对你有所帮助。

无论你是刚开始接触前端,还是已经工作多年的工程师,愿你在构建项目的道路上少走弯路,多些从容。

前端开发从来不只是写代码,更是理解需求、权衡取舍、持续迭代的艺术。共勉!

如果你觉得这篇文章对你有启发,欢迎点赞、转发或留言交流 👇

评论 0

最热最新
暂无评论
匿名用户Lv.1
0
影响力
0
文章
0
粉丝