从零开始构建一个现代化前端项目:试用期菜鸟的血泪踩坑实录
大家好,我是小林,刚入职杭州一家中型互联网公司不到一个月,目前还在试用期瑟瑟发抖中。之前在一家传统软件公司混了两年,技术栈基本停留在 jQuery + Bootstrap 的“上古时代”。来这边面试的时候,HR说我们团队技术氛围浓厚、拥抱前沿,我以为就是客套话——结果入职第一天,看到同事都在聊 Vite、TypeScript、微前端、Web Vitals,我当场瞳孔地震。
上周五,我的 mentor(带教导师)老张丢给我一个任务:“下周三前,搭个新项目的脚手架,要能跑起来,还要符合咱们团队的规范。” 我内心OS:不是有 create-react-app 吗?直接开干不就完了?结果老张微微一笑:“CRA?那是2018年的玩具了,现在谁还用那个?”
行吧,被现实狠狠教育了。为了保住这份离阿里网易都很近、薪资还不错的工作(毕竟杭州房租真不便宜),我硬着头皮从零开始搞起了这个“现代化前端项目”。今天这篇教程,就是记录我这三天踩过的坑、熬过的夜、以及差点被产品经理气到砸 Mac 的瞬间。如果你也刚入行,或者像我一样技术有点落伍,希望这篇能帮你少走点弯路。
起因:为什么不能直接用现成的脚手架?
其实一开始我也想偷懒。但老张说,现在大厂(包括我们这种“准大厂”)对前端工程化要求很高,光会写组件不够,得懂整个构建流程、性能监控、CI/CD 集成。而且我们项目要支持 SSR(服务端渲染)和 PWA(渐进式 Web 应用),CRA 根本搞不定。
更扎心的是,他说:“你要是连基础配置都看不懂,以后怎么 debug 构建问题?线上白屏了怎么办?等着运维大哥半夜打电话骂你吗?”
好吧,道理我都懂。那就从 npm init 开始吧!
第一步:初始化项目 & 选择核心工具链
首先,我新建了一个空文件夹:
mkdir modern-frontend-starter
cd modern-frontend-starter
npm init -y
然后安装几个核心依赖。这里我参考了团队内部的文档(其实是偷偷看了隔壁组的 GitHub 仓库):
- Vite:新一代构建工具,快如闪电,开发服务器秒启动
- React 18:团队主技术栈(虽然我个人更喜欢 Vue,但人在屋檐下……)
- TypeScript:必须上!JS 写大型项目太容易翻车
- ESLint + Prettier:代码风格统一,避免 PR 时被同事喷
- Husky + lint-staged:提交前自动格式化,杜绝脏代码入库
npm install -D vite @vitejs/plugin-react typescript @types/react @types/react-dom
npm install react react-dom
npm install -D eslint prettier husky lint-staged
💡 小贴士:
-D是--save-dev的简写,只在开发环境用。
接着,我创建了 vite.config.ts:
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
server: {
port: 3000,
open: true // 自动打开浏览器
},
build: {
outDir: 'dist'
}
})
简单吧?但别小看这几行,它背后是 Webpack 时代几十行配置的简化版。Vite 利用原生 ES 模块(ESM)直接在浏览器运行代码,开发时几乎零编译,真的香!
第二步:配置 TypeScript 和代码规范
为了让 TS 正常工作,我加了 tsconfig.json:
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
"esModuleInterop": false,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
},
"include": ["src"]
}
然后是 ESLint + Prettier 联合配置。这里我踩了个大坑:两个工具默认规则冲突,导致保存时格式化完,ESLint 又报错。最后用了社区推荐的 .eslintrc.cjs + .prettierrc 组合:
// .eslintrc.cjs
module.exports = {
env: {
browser: true,
es2021: true
},
extends: [
'eslint:recommended',
'plugin:react/recommended',
'plugin:@typescript-eslint/recommended'
],
parser: '@typescript-eslint/parser',
plugins: ['react', '@typescript-eslint'],
rules: {
'react/react-in-jsx-scope': 'off' // React 17+ 不需要显式导入
},
settings: {
react: {
version: 'detect'
}
}
}
// .prettierrc
{
"semi": false,
"tabWidth": 2,
"singleQuote": true,
"printWidth": 80,
"trailingComma": "es5"
}
最后用 Husky 搞个 pre-commit 钩子:
npx husky-init && npm install
npx husky add .husky/pre-commit "npx lint-staged"
并在 package.json 中添加:
{
"lint-staged": {
"*.{js,jsx,ts,tsx}": ["eslint --fix", "prettier --write"]
}
}
搞定!现在每次 git commit,代码都会自动格式化 + 检查。再也不用担心被 code review 时被嘲讽“缩进不对”了 😅
第三步:目录结构 & 基础页面搭建
我们团队有个不成文的规定:src 目录必须清晰分层。于是我按以下结构组织:
src/
├── assets/ # 静态资源
├── components/ # 通用组件
├── hooks/ # 自定义 Hook
├── pages/ # 页面级组件
├── utils/ # 工具函数
├── App.tsx
└── main.tsx
写了个超简单的首页:
// src/pages/Home.tsx
import React from 'react'
const Home = () => {
return (
<div className="container">
<h1>欢迎来到现代化前端世界!</h1>
<p>当前时间:{new Date().toLocaleTimeString()}</p>
</div>
)
}
export default Home
然后在 App.tsx 里引入。注意:虽然现在没用路由,但提前按页面拆分,以后加 React Router 也方便。
第四步:性能优化 & 用户体验细节
作为“用户体验至上”的团队,老张特别强调:首屏加载速度必须快,交互必须流畅。
1. 资源压缩与缓存
Vite 默认在 build 时做代码分割和压缩。但我们加了额外配置:
// vite.config.ts
import { splitVendorChunkPlugin } from 'vite'
export default defineConfig({
plugins: [
react(),
splitVendorChunkZone() // 将 node_modules 拆成 vendor chunk
],
build: {
sourcemap: true, // 生产环境也保留 sourcemap,方便排查线上错误
rollupOptions: {
output: {
manualChunks: {
vendor: ['react', 'react-dom']
}
}
}
}
})
2. 浏览器兼容性
我们目标用户主要是移动端,所以最低支持到 iOS 12 / Android 10。Vite 默认使用现代浏览器特性,但通过 @vitejs/plugin-legacy 可以生成兼容版本:
npm install -D @vitejs/plugin-legacy
// vite.config.ts
import legacy from '@vitejs/plugin-legacy'
export default defineConfig({
plugins: [
react(),
legacy({
targets: ['iOS >= 12', 'Android >= 10']
})
]
})
这样构建后会多出 legacy-polyfill-*.js 和对应的 HTML 文件,老设备也能跑。
3. Lighthouse 评分优化
我在本地跑 Lighthouse,发现“最佳实践”只有 70 分。原因有几个:
- 缺少
<meta name="viewport"> - 没有设置
lang属性 - 图片没加
alt
于是赶紧补全 index.html:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Modern Frontend Starter</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
再跑一次,92 分!老张看了直点头:“不错,有产品sense。”
第五步:集成 GitHub Actions 实现自动化
既然是现代化项目,怎么能少了 CI/CD?我们用 GitHub 托管代码,所以自然选 GitHub Actions。
我在 .github/workflows/ci.yml 里写了:
name: CI
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
test-and-build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
- run: npm ci
- run: npm run lint
- run: npm run build
对应 package.json 脚本:
{
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0"
}
}
现在每次 push 到 main 或提 PR,GitHub 都会自动跑 lint 和 build。如果失败,PR 会被 block —— 再也不用担心有人把 console.log 提到生产环境了(说的就是上周那个实习生……)。
踩坑总结:那些让我想砸 Mac 的瞬间
TSX 文件被 ESLint 忽略
原因:.eslintignore里误加了*.tsx。删掉就好。Vite 开发服务器 HTTPS 报错
因为公司内网要求所有服务走 HTTPS。解决方案:在server配置里加https: true,并生成自签名证书(或让运维给个测试证书)。PWA 离线缓存失效
一开始用workbox配置错了,缓存策略没生效。后来改用vite-plugin-pwa,一行配置搞定。Mac 和 Windows 路径大小写问题
我在 Mac 上写import MyComponent from './mycomponent',但实际文件叫MyComponent.tsx。Mac 不区分大小写能跑,但 Windows 测试机直接崩。从此养成严格命名习惯。
最终效果 & 心得体会
周三早上,我把项目链接发到群里。老张试了一下,说:“加载速度不错,Lighthouse 90+,代码也规范,可以 merge 了。” 那一刻,我感觉试用期稳了!
这个项目虽然简单,但它让我真正理解了“现代化前端”不只是用新框架,而是工程化思维 + 用户体验 + 自动化流程的结合。以前我觉得这些是“花架子”,现在明白:没有这些,项目大了就是灾难。
顺便,我把整个项目开源到了 GitHub:github.com/lin-coder/modern-frontend-starter(名字是我瞎起的)。里面有详细注释和 README,新手可以直接 clone 下来玩。欢迎 star & 提 issue!
给新手的建议
| 事项 | 推荐做法 | 避坑提醒 |
|---|---|---|
| 构建工具 | 优先选 Vite | Webpack 配置复杂,新手慎入 |
| 语言 | TypeScript 必上 | JS 在大型项目维护成本高 |
| 代码规范 | ESLint + Prettier + Git Hooks | 不要等到项目大了才加 |
| 性能 | 从第一天关注 Lighthouse | 别等上线了用户投诉才优化 |
| 自动化 | 尽早集成 CI/CD | 手动部署迟早出事 |
最后,送一句我们团队墙上的话:“前端不止是切图仔,更是用户体验的守门人。”
共勉!下次再分享如何接入微前端和埋点监控。对了,如果你们公司也在招人(坐标杭州,偏爱 Mac 用户),可以私信我~(试用期结束前先给自己留条后路,狗头保命)
本文纯属个人经验分享,如有雷同,那说明你也正在经历试用期的煎熬。加油,打工人!

评论 0