从零搭建一个 React 应用
使用 Create React App 创建应用
Create React App 官网地址 create-react-app.bootcss.com
使用下面命令创建一个 React 应用,使用的是默认的模板。
npx create--react-app myapp
# or 使用 typescript 模板
npx create-react-app myapp --template typescript
可以通过 --template
可以指定我们想要下载的模板,这里我使用 typescript
模板,我们也可以使用我们自己创建的模板,模板开发可以参考 create-react-app.dev/docs/custom…
然后进入的项目目录下,执行 npm start
启动项目
cb myapp
npm install
配置 eslint
初始化 eslint
安装 eslint
npm init @eslint/config
选择下面配置
✔ How would you like to use ESLint? · problems
✔ What type of modules does your project use? · esm
✔ Which framework does your project use? · react
✔ Does your project use TypeScript? · Yes
✔ Where does your code run? · browser
✔ What format do you want your config file to be in? · JavaScript
这里没有使用 eslint 校验代码格式,因为 eslint 无法格式化我们的 jsx 代码片段,使用 prettier 可以格式化 tsx 文件中的所有代码
prettier
将 prettier 配置到 eslint 中
npm i prettier eslint-config-prettier eslint-plugin-prettier -D
编写 prettier 配置文件
module.exports = {
// 箭头函数只有一个参数的时候可以忽略括号
arrowParens: 'avoid',
// 括号内部不要出现空格
bracketSpacing: true,
// 行结束符使用 Unix 格式
endOfLine: 'lf',
// true: Put > on the last line instead of at a new line
jsxBracketSameLine: false,
// 行宽
printWidth: 100,
// 换行方式
proseWrap: 'preserve',
// 分号
semi: false,
// 使用单引号
singleQuote: true,
// 缩进
tabWidth: 2,
// 使用 tab 缩进
useTabs: false,
// 后置逗号,多行对象、数组在最后一行增加逗号
trailingComma: 'es5',
parser: 'typescript',
}
将 prettier 添加到 eslint 配置文件中。相关参考文档 prettier.io/docs/en/con…
/* eslint-env node */
module.exports = {
env: {
browser: true,
es2021: true,
},
extends: [
'eslint:recommended',
'plugin:react/recommended',
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended',
],
overrides: [],
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
},
plugins: ['react', '@typescript-eslint'],
rules: {},
}
eslint 相关配置参考文档 eslint.org/docs/latest…
编辑器配置(vscode)
配置 vscode
- 安装 eslint 插件
- 安装 prettier 插件
- 编辑器配置使用 prettier 格式化 ts、tsx 代码
// .vscode/settings.json
{
"editor.tabSize": 2,
"[tsx,ts]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"editor.formatOnSave": true
}
配置代理
开发过程中可能会遇到跨域问题,可以通过配置代理进行解决
方式一
方式就是直接在 package.json 文件中配置。任何没有意义的请求都会代理到指定的 proxy
{
"proxy": "http://localhost:3001",
}
但这种方式的缺点就不够灵活
方式二
npm i http-proxy-middleware
创建文件 src/setupProxy.js
const { createProxyMiddleware } = require('http-proxy-middleware')
module.exports = function (app) {
// 注册代理,可以注册多个代理
app.use(
'/api',
createProxyMiddleware({
target: 'http://localhost:3001',
changeOrigin: true,
})
)
// 注册代理
app.use(
'/api2',
createProxyMiddleware({
target: 'http://localhost:8001',
changeOrigin: true,
})
)
...
}
注意 这里不能只能使用 js 文件,不支持使用 ts 文件
Mock 数据
开发过程中,如果后端的接口还没有写好,我们不可能等到后端接口写好才开始写,这时,我们就需要 mock 数据了,在这之前,前后端需要约定好数据的格式。这里使用 mockjs,需要先了解下 mockjs 的使用。github.com/nuysoft/Moc…
这里我们使用 koa 搭建 mock 服务器,也可以使用 express 、 fastify 等。这里有一个使用 fastify 的例子 github.com/shibin-cli/…
npm init -y
npm i koa @koa/router mockjs koa-body typescript ts-node
tsc --init
使用 koa 搭建 mock 服务器
import Koa from 'koa'
import Router from '@koa/router'
import { koaBody } from 'koa-body'
import mocklist from './mock' // 我们准备的路由和mock数据
const app = new Koa()
const router = new Router({
prefix: '/api',
})
app.use(koaBody())
function sleep(second: number) {
return new Promise(resolve => {
setTimeout(resolve, 1000 * second)
})
}
mocklist.forEach(item => {
const { url, method, response } = item
router[method](url, async ctx => {
// 这里是为了测试前端的 loading 效果、重复点击等
await sleep(0.5)
ctx.body = response(ctx)
})
})
app.use(router.routes()).use(router.allowedMethods())
app.listen(3001)
准备我们的路由
import Mock from 'mockjs'
export interface MockItem {
method: Method
url: string
response: (ctx: Koa.ParameterizedContext<Koa.DefaultState, Koa.DefaultContext, any>) => MockRes
}
const Random = Mock.Random
const userMock: MockItem[] = [
{
url: '/user',
method: 'get',
response(ctx) {
const { user } = ctx.state
return {
errno: 0,
data: {
username: user.username,
id: user.id,
nickname: Random.cname(),
},
}
},
},
{
url: '/login',
method: 'post',
response(ctx) {
const { username } = ctx.request.body
return {
errno: 0,
data: {
token: Random.id(),
},
}
},
},
{
url: '/register',
method: 'post',
response() {
return {
errno: 0,
data: {
id: Random.id(),
},
}
},
},
]
export default userMock
转载自:https://juejin.cn/post/7219189313723793465