3. 移动端项目初始化:从零搭建你的React移动端工程
好,咱们直接进入正题。项目初始化这事儿,看着简单,但坑其实不少。我见过太多同学一上来就 npx create-react-app my-app,然后就开始写代码,结果到后面发现配置改不动、打包体积大、热更新慢……说白了,就是一开始没选对工具。
今天我就带你走一遍,从脚手架选择到目录规划,再到配置文件详解,把移动端项目的底子打扎实。
3.1 选哪个?Create React App 还是 Vite?
这个问题我经常被问到。我的建议很直接:新项目首选 Vite。
为什么?你想想看,CRA(Create React App)当年确实是神器,但它的开发服务器启动慢,热更新也慢。尤其是移动端项目,你经常要改一点样式就刷新看效果,CRA 那几秒钟的等待真的很磨人。
Vite 就不一样了。它基于 ES Module,开发时按需编译,启动速度几乎是秒开。我在一个中型移动端项目里做过对比,CRA 冷启动要 8 秒,Vite 只要 1.2 秒。这差距,你感受一下。
- Vite:新项目、追求开发体验、需要快速迭代 → 首选
- CRA:老项目维护、团队习惯 CRA、需要零配置 → 可以保留
- 自己搭 Webpack:除非你有特殊需求,否则别折腾
嗯,这里要注意一点:Vite 对 Node.js 版本有要求,建议 16+。我之前有个同事用 Node 14 跑 Vite,报了一堆错,查了半天才发现是版本问题。
3.2 用 Vite 初始化项目
咱们直接上手。打开终端,执行:
npm create vite@latest my-mobile-app -- --template react-ts
这里我用了 TypeScript 模板。为什么?移动端项目逻辑复杂,类型系统能帮你省掉很多调试时间。我个人习惯是,只要不是特别小的 demo,都用 TS。
初始化完成后,进入目录安装依赖:
cd my-mobile-app
npm install
然后启动:
npm run dev
看到终端里出现 Local: http://localhost:5173,就说明成功了。
vite.config.ts 里加 server: { port: 3000 }。
3.3 目录结构规划:移动端项目的骨架
项目初始化完了,但目录结构还是空的。我见过很多项目,一开始不规划目录,写到后面就变成一锅粥。组件、工具函数、页面全混在一起,找文件得靠猜。
下面是我在多个移动端项目中沉淀下来的目录结构,你可以直接拿来用:
src/
├── assets/ # 静态资源(图片、字体、SVG)
│ ├── images/
│ └── fonts/
├── components/ # 通用组件
│ ├── common/ # 基础组件(Button、Input、Modal)
│ └── business/ # 业务组件(ProductCard、UserAvatar)
├── hooks/ # 自定义 Hooks
│ ├── useDebounce.ts
│ ├── useThrottle.ts
│ └── useViewport.ts
├── pages/ # 页面组件
│ ├── Home/
│ ├── Detail/
│ └── User/
├── router/ # 路由配置
│ └── index.tsx
├── store/ # 状态管理
│ └── index.ts
├── styles/ # 全局样式
│ ├── reset.css
│ ├── variables.css
│ └── mixins.css
├── utils/ # 工具函数
│ ├── request.ts # 网络请求封装
│ ├── format.ts # 格式化函数
│ └── storage.ts # 本地存储封装
├── types/ # TypeScript 类型定义
│ └── index.d.ts
├── App.tsx
└── main.tsx
这个结构有几个好处:
- 职责清晰:每个文件夹只做一件事,不会互相污染
- 便于扩展:新页面来了,直接在
pages下加文件夹就行 - 团队协作友好:大家知道什么东西该放哪里,不用问来问去
我曾经在一个项目里看到有人把网络请求直接写在组件里,结果换了个页面想复用,只能复制粘贴。后来我强制要求所有请求都封装到 utils/request.ts 里,代码质量瞬间提升。
3.4 移动端项目配置文件详解
好,目录结构搭好了,接下来咱们看看几个关键的配置文件。这些文件决定了你的项目能不能在移动端跑得顺畅。
3.4.1 vite.config.ts:Vite 的核心配置
这个文件是 Vite 的入口配置。对于移动端项目,有几个配置项特别重要:
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import path from 'path'
export default defineConfig({
plugins: [react()],
resolve: {
alias: {
'@': path.resolve(__dirname, 'src')
}
},
server: {
port: 3000,
host: '0.0.0.0', // 允许局域网访问,方便真机调试
proxy: {
'/api': {
target: 'http://your-api-server.com',
changeOrigin: true
}
}
},
build: {
rollupOptions: {
output: {
manualChunks: {
vendor: ['react', 'react-dom'],
ui: ['antd-mobile']
}
}
}
}
})
这里我重点说几个:
resolve.alias:配置路径别名,以后写@/components/Button比../../components/Button舒服多了server.host: '0.0.0.0':这个一定要开!不然你手机连不上电脑的本地服务,没法真机调试build.rollupOptions.output.manualChunks:把第三方库拆成独立 chunk,这样用户访问时可以利用浏览器缓存,不用每次都下载 React 全家桶
server.host,或者用环境变量控制。我之前有个项目忘了关,上线后 API 地址暴露了,还好及时发现。
3.4.2 tsconfig.json:TypeScript 配置
移动端项目用 TypeScript,配置上要特别注意路径别名和严格模式:
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
}
},
"include": ["src"]
}
这里 paths 要和 vite.config.ts 里的 alias 保持一致,不然 IDE 会报错说找不到模块。
3.4.3 postcss.config.js:移动端适配的关键
移动端适配,说白了就是让页面在不同屏幕尺寸下都能正常显示。我推荐用 postcss-px-to-viewport 这个插件,它能把 px 自动转成 vw 单位:
export default {
plugins: {
'postcss-px-to-viewport': {
viewportWidth: 375, // 设计稿宽度(iPhone 6/7/8)
unitPrecision: 5, // 转换后保留的小数位数
viewportUnit: 'vw', // 转换后的单位
selectorBlackList: ['.ignore', '.hairlines'], // 不转换的类名
minPixelValue: 1, // 小于 1px 不转换
mediaQuery: false // 是否允许在媒体查询中转换
}
}
}
为什么用 375?因为大多数移动端设计稿都是基于 iPhone 6/7/8 的 375px 宽度。你写 width: 100px,它会自动转成 width: 26.66667vw,在不同屏幕上都按比例缩放。
1px 的边框,结果 postcss-px-to-viewport 把它转成了 0.26667vw,在有些手机上边框直接消失了。后来我在 selectorBlackList 里加了 '.hairlines',专门处理 1px 边框的场景。
3.4.4 .env 文件:环境变量管理
移动端项目通常有开发、测试、生产三个环境,环境变量要分开管理:
// .env.development
VITE_API_BASE_URL=http://localhost:3000/api
VITE_APP_TITLE=移动端项目(开发环境)
// .env.production
VITE_API_BASE_URL=https://api.your-domain.com
VITE_APP_TITLE=移动端项目
在代码里用 import.meta.env.VITE_API_BASE_URL 就能拿到对应的值。注意 Vite 的环境变量必须以 VITE_ 开头,不然不会暴露给前端代码。
3.5 初始化后的第一件事:验证移动端适配
项目搭好了,配置写完了,别急着写业务代码。先验证一下移动端适配是否生效:
- 在
App.tsx里写一个div,宽度设为 375px - 启动项目,用 Chrome DevTools 模拟 iPhone 6/7/8
- 检查元素,看宽度是不是变成了
100vw - 切换到 iPhone X(375px 宽度),看布局是否正常
- 用手机真机访问,看效果是否一致
这一步走通了,后面写页面就只管按设计稿写 px,剩下的交给 postcss 去处理。
- 新项目用 Vite,开发体验好太多
- 目录结构提前规划,别等代码多了再重构
- 配置文件要理解每个选项的作用,别照抄
- 移动端适配用 postcss-px-to-viewport,省心省力
好了,项目初始化就到这里。下一章咱们会深入移动端适配的细节,包括 rem、vw、媒体查询这些方案的对比,以及我在实际项目中踩过的坑。到时候见。