项目基础配置篇
-
初步构建:react-app 脚手架搭建 并使用ts模板
yarn create react-app myproject --template typescript -
使用
# Ant Design of Reactul库yarn add antd -
配置antd 按需加载 得通过 babel-plugin-import 是一个用于按需加载组件代码和样式的 babel 插件,后面在
config-overrides.js配置,覆盖webpack配置yarn add babel-plugin-import --dev fixBabelImports( 'import', { libraryName: 'antd', libraryDirectory: 'es', style: true, // 设置为true 使用less } ) -
使用
less必须带上less-loaderyarn add less less-loader --dev 配置loader 同上 在配置文件中覆盖 lessOptions: { javascriptEnabled: true, modifyVars: { '@primary-color': '#40A9FF' }, //修改antd 主题色 } -
插件:progress-bar-webpack-plugin 可以看到构建进度,启动的时候,构建的进度条
yarn add progress-bar-webpack-plugin --dev -
插件:hard-source-webpack-plugin 可以打包缓存,加载缓存,优化性能
yarn add hard-source-webpack-plugin --dev -
插件:react-app-rewire-hot-loader 可以进行局部的热更新,对webpack 的热更新进一步优化,
官方: Because who wants their app, state, and styles automatically reloading all the time?
yarn add react-app-rewire-hot-loader --dev 依赖包: yarn add react-hot-loader --dev yarn add react-app-rewired //后续也会需要,这里安装了,一会儿就不用安装 -
使用customize-cra 进行webpack配置,
customize-cra依赖react-app-rewired的config-overrides.js文件。通过导入customize-cra功能和出口几个函数调用包在我们的override功能,你可以很容易地修改底层配置对象(webpack,webpack-dev-server,babel等)组成create-react-app,依赖react-app-rewiredyarn add customize-cra react-app-rewired --dev安装了react-app-rewired 修改webpack.json
/* package.json */ "scripts": { - "start": "react-scripts start", + "start": "react-app-rewired start", - "build": "react-scripts build", + "build": "react-app-rewired build", - "test": "react-scripts test", + "test": "react-app-rewired test", "eject": "react-scripts eject" }配置添加
config-overrides.js与package同一级别``` const path = require('path') const { override, fixBabelImports, //babel的配置 addLessLoader, //所有的loader 在这里重构, addWebpackPlugin, //所有的插件重写 addWebpackAlias //添加别名 } = require("customize-cra"); const ProgressBarPlugin = require('progress-bar-webpack-plugin') const HardSourceWebpackPlugin = require('hard-source-webpack-plugin') const rewireReactHotLoader = require('react-app-rewire-hot-loader') module.exports = override( fixBabelImports('import', { libraryName: 'antd', libraryDirectory: 'es', style: true, // or css true 表示使用less }), addLessLoader({ lessOptions: { javascriptEnabled: true, modifyVars: { '@primary-color': '#40A9FF' }, //对antd 定制主题色 }, }), addWebpackPlugin( new ProgressBarPlugin(), //项目启动构建进度 new HardSourceWebpackPlugin() // 打包缓存,优化性能 ), addWebpackAlias({ '@': path.resolve(__dirname, 'src'), // 路径重定向 @ 代替 别名 可增加多个 }), (config, env) => { if (env === 'production') { config.devtool = false //如果是成产环境,工具不启动 } config = rewireReactHotLoader(config, env) //配置局部热更新 return config }, )
注意事项
使用antd 组件的时候报错,error:this.getOptions is not function 是less-loader 版本太高了
降低一下版本:
yarn add less-loader@6.0.0 --dev
结构配置篇幅
按照目录结构生成对应目录
.
├── api
├── asset // 本地静态资源
├── components // 业务通用组件
├── hooks // 自定义hooks
├── layouts // 通用布局
├── models // 模型
├── pages // 页面
├── router // 路由
├── service // 接口
├── utils // 工具库
├── App.tsx
├── global.less // 全局样式
└── index.tsx // 主入口
路由配置篇: 使用路由懒加载依赖包:@loadable/component @types/loadable__component 路由包:react-router-dom
yarn add @loadable/component
yarn add @types/loadable__component
yarn add react-router-dom
router 文件夹目录结构:
├── index.tsx
├── NestedRoute.tsx
├── useRouteNavigation.tsx 路由导航 这里就不做介绍,根据业务自定义
index.tsx 代码:
import NestedRoute from './NestedRoute'
export interface RouterProps {
path: string;
component: string;
title?: string;
exact?: boolean;
routes?: RouterProps[];
}
const routes: RouterProps[] = [
{
path: '/home',
component: 'pages/Home',
}
]
export default routes
export { NestedRoute }
NestedRoute.tsx 代码:
import React from 'react'
import { Route } from 'react-router-dom'
import loadable from '@loadable/component'
import Loading from '@/components/Loading'
import { RouterProps } from './index'
const AsyncPage = loadable(
(props: RouterProps) => {
document.title = props?.title || 'PBL智能专家辅助系统'
return import(/* webpackChunkName: '[request]' */ `@/${props.component}`)
},
{
fallback: <Loading />,
},
)
const NestedRoute = (route: any) => (
<Route
path={route.path}
exact={route.exact}
render={() => (
<AsyncPage {...route}>
{
route?.routes?.map((item: any) => (
<NestedRoute key={`route-${item.path}`} {...item} />)
)
}
</AsyncPage>
)}
/>
)
export default NestedRoute