create-react-app airbnb
react项目默认不给创建jsconfig.json文件,从以前写的vue项目中拿一个
- assets
- css
- img
- base-ui
- components
- hooks
- router
- store
- views
- utils
- services
vue项目初始化中,默认给配置好了别名,@就是src
react项目需要自己手动配置别名。
方案一:npm run eject(将react的配置文件暴露出去,暴露出去后就不能复原,不建议使用)
方案二:craco => create-react-app config(在外部生成一个新的配置文件,最后会合并进去,建议使用)
npm i @craco/craco -D
或 npm i @craco/craco@alpha -D
less也跟着一起配置了
npm i craco-less -D
或 npm i craco-less@2.1.0-alpha.0 -D
将package.json中scripts中的react-scripts改为craco
在项目根目录下创建一个名为craco.config.js的文件
// craco.config.js
const path = require('path')
const resolve = pathname => path.resolve(__dirname, pathname)
const CracoLessPlugin = require("craco-less")
module.exports = {
plugins: [
// less
{
plugin: CracoLessPlugin
}
],
// webpack
webpack: {
alias: {
"@": resolve("src"),
"components": resolve("src/components"),
"utils": resolve("src/utils")
}
}
}
安装normalize.css进行样式的初始化,npm i normalize.css
css文件夹下创建reset.css,variables.css,index.css
如果安装less,可以直接写less
// 在index.js中导入
import 'normalize.css'
import '@/assets/css/index.css'
npm i react-router-dom
// index.js
import { Suspense } from 'react'
import { HashRouter } from 'react-router-dom'
// 或
import { BrowserRouter } from 'react-router-dom'
// 因为用到了路由懒加载,所以要用Suspense进行包裹
<Suspense fallback='loading'>
<HashRouter>
<App />
</HashRouter>
</Suspense>
// router/index.js
import React from 'react'
import { Navigate } from 'react-router-dom'
const Home = React.lazy(() => import('@/views/home'))
const Detail = React.lazy(() => import('@/views/detail'))
const Entire = React.lazy(() => import('@/views/entire'))
const routes = [
{
path: '/',
element: <Navigate to='/home' />
},
{
path: '/home',
element: <Home />
},
{
path: '/detail',
element: <Detail />
},
{
path: '/entire',
element: <Entire />
}
]
export default routes
import { useRoutes } from 'react-router-dom'
import routers from './router'
// 占位
{useRoutes(routes)}
npm i @reduxjs/toolkit react-redux
// sotre/index.js
import { configureStore } from "@reduxjs/toolkit"
import homeReducer from "./modules/home"
const store = configureStore({
reducer: {
home: homeReducer
}
})
export default store
// index.js
import { Provider } from 'react-redux'
import store from './store'
<Provider store={store}>
<App />
</Provider>
// RTK方式
// store/modules/home.js
import { createSlice } from "@reduxjs/toolkit"
const homeReducer = createSlice({
name: 'home',
initialState: {},
reducers: {
foo: (state, { payload }) => {}
}
})
export const { foo } = homeReducer.actions
export default homeReducer.reducer
// 普通方式
// store/modules/entire/reducer.js
import { TYPE1 } from "./constants"
const initialState = {}
const reducer = (state = initialState, action) => {
switch(action.type) {
case TYPE1:
// 操作派发过来的操作
return
default:
return state
}
}
export default reducer
npm i axios
// services/request/index.js
import axios from "axios"
import { BASE_URL, TIMROUT } from "./config"
class Request {
constructor(baseURL, timeout = 5000) {
this.instance = axios.create({
baseURL,
timeout
})
this.instance.interceptors.request.use(config => {
return config
})
this.instance.interceptors.response.use(res => {
return res
}, err => {
return err
})
}
request(config) {
return this.instance.request(config)
}
get(url, config) {
return this.request({ ...config, url, method: 'get' })
}
post(url, config) {
return this.request({ ...config, url, method: 'post' })
}
}
const request = new Request(BASE_URL, TIMROUT)
export default request