$ npm create vite@latest react-admin -- --template react-ts
$ npm install
- 项目根目录下创建
.editorconfig
文件 - 配置文件内容
root = true // 顶层配置
[*] // 所有文件
charset = utf-8 // 编码格式
indent_style = space // 缩进风格
indent_size = 2 // 缩进大小
end_of_line = lf // 换行符
insert_final_newline = true // 文件末尾插入新行
trim_trailing_whitespace = true // 删除行尾空格
[*.md] // 所有md文件
trim_final_newline = false // 不删除行尾空格
trim_trailing_whitespace = false // 不删除行尾空格
- 安装插件
- VS Code: EditorConfig for VS Code
- 安装依赖
$ npm install --save-dev prettier
- 项目根目录下创建
.prettierrc.cjs
文件 - 配置文件内容
module.exports = {
"printWidth": 120, // 每行代码长度(默认80)
"singleQuote": true, // 使用单引号(默认false)
"trailingComma": "none", // 末尾逗号(默认none)
"endOfLine": "auto", // 结尾是 \n \r \n\r auto
"semi": false, // 句尾添加分号(默认true)
"tabWidth": 2, // tab缩进大小(默认是2)
"useTabs": true, // 使用tab缩进(默认false)
"bracketSpacing": true, // 对象字面量的大括号间增加空格(默认true)
"jsxBracketSameLine": true, // jsx标签的反尖括号是否单独一行(默认false)
"arrowParens": "avoid", // 箭头函数参数为单个时是否省略括号(默认avoid)
}
- 安装插件
- VS Code: Prettier - Code formatter
- 局部保存格式化:项目根目录下创建
.vscode
文件
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
}
- 安装依赖eslint,prettier
$ npm install -D eslint prettier eslint-plugin-react @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint-config-prettier
- 项目根目录下创建
.eslintrc.cjs
文件 - 配置文件内容
module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: [
'eslint:recommended',// 推荐规则集
'plugin:@typescript-eslint/recommended', // 官方推荐的规则集
'plugin:react/recommended', // 官方推荐的react规则集
'plugin:react-hooks/recommended',// 官方推荐的react-hooks规则集
'plugin:prettier/recommended' // prettier推荐的规则集
],
ignorePatterns: ['dist', '.eslintrc.cjs'],
parser: '@typescript-eslint/parser',
plugins: ['react-refresh','react','@typescript-eslint','prettier'],
rules: {
"react/react-in-jsx-scope": "off",
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
},
}
- 项目根目录下创建
vite.config.ts
文件 - 安装依赖
$ npm install path
- 配置文件内容
import path from 'path'
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { fileURLToPath } from 'url'
import { dirname } from 'path'
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)
export default defineConfig({
plugins: [react()],
resolve: {
alias: {
'@': path.resolve(__dirname, './src')
}
}
})
- tsconfig.json 配置别名映射
"baseUrl": "src",
"paths": {
"@/*": ["*"]
}
::: tip 针对 ES Modules 引入__dirname 的解决方案 如果使用 "type": "module",改用以下方式:
import { fileURLToPath } from 'url';
import { dirname } from 'path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
:::
- api: 存放接口请求
- components: 存放公用组件
- config: 存放配置文件
- layout: 存放布局组件
- router: 存放路由配置
- store: 存放状态管理
- utils: 存放工具函数
- types: 存放类型定义
- hooks: 存放自定义hooks
- views: 存放页面组件
- 下载依赖
$ npm install antd
- 安装React-Router
$ npm install react-router-dom
- 项目根目录下创建
src/router/index.tsx
文件
import { useRoutes, RouteObject, Navigate } from 'react-router-dom'
import Login from '@/views/Login.tsx'
import NotFound from '@/views/NotFound.tsx'
import Home from '@/views/Home/index.tsx'
import Layout from '@/layout/index.tsx'
// 定义路由配置数组
const router: RouteObject[] = [
{
path: '/',
element: <Layout />,
children: [
{ path: 'home', element: <Home /> },
{ path: 'about', element: <div>about</div> }
]
},
{ path: '/login', element: <Login /> },
{ path: '/404', element: <NotFound /> },
{ path: '*', element: <Navigate to="/404" /> }
]
// 创建路由组件
function Router() {
return useRoutes(router)
}
export default Router
// 在App.tsx中使用
import { BrowserRouter } from 'react-router-dom'
import Router from './router'
// API+组件化创建的路由
function App() {
return (
<BrowserRouter>
<Router />
</BrowserRouter>
)
}
export default App
$ npm install axios
import axios from 'axios'
// 创建axios实例
const request = axios.create({
baseURL: '/api', // API的base_url
timeout: 5000, // 请求超时时间
})
// 请求拦截器
request.interceptors.request.use(
(config) => {
return config
},
(error) => {
Promise.reject(error)
}
)
// 响应拦截器
request.interceptors.response.use(
(response) => {
if (response.status === 200) {
return response.data
} else {
console.log('error')
}
},
(error) => {
return Promise.reject(error)
}
)
export default request
import request from '@/utils/request'
export function getUserInfo() {
return request.get('/user')
}
在vite.config.ts
中配置代理
export default defineConfig({
server: {
proxy: {
'/api': {
target: 'http://localhost:3000', // 目标服务器地址
changeOrigin: true, // 是否改变源
rewrite: (path) => path.replace(/^\/api/, ''), // 重写路径
logLevel: 'debug', // 日志级别
},
},
},
})
react-6-5