前言
最近搭建了一套以react+typescript为主的项目,实现从0开始创建整个项目的流程,包括添加less,eslint,等以此为契机输出一篇流程文档
主要分为几个部分
- 技术栈
- 架构搭建
- 代码规范
- 提交规范
技术栈
- 编程语言: typescript
- 构建工具: webpack
- 前端框架: react
- 路由: react-router-dom
- 状体管理: useContext
- css预编译: less
- git hook: husky+ lint-staged
- 代码规范: EditorConfig + Prettier + ESLint + Airbnb JavaScript Style Guide
- 提交规范: commitizen + commitlint
架构搭建
项目基于 create-react-app 首先全局安装 npm install -g create-react-app
开始安装
npx create-react-app react-app --template typescript创建成功后,yarn start,启动项目
原始目录结构:
添加less预编译
-
yarn run eject(暴露webpack配置,根目录会出现config文件夹) -
yarn add less less-loader -
在 项目的根路径文件react-app-env.d.ts 下添加
declare module "*.less" { const less: any; export default less; } -
在config文件夹下的webpack.config内 增加less配置
由于cra脚手架内支持sass,所以全局搜索sass,相应的配置一套 less 即全局搜索 sassRegex 第一处下边配置上
const lessRegex = /\.less$/; const lessModuleRegex = /\.module\.less$/;第二处下配置
{ test: lessRegex, exclude: lessModuleRegex, use: getStyleLoaders( { importLoaders: 3, sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment, }, 'less-loader' ), sideEffects: true, }, { test: lessModuleRegex, use: getStyleLoaders( { importLoaders: 3, sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment, modules: { getLocalIdent: getCSSModuleLocalIdent, }, }, 'less-loader' ), },项目中把css改为less,启动项目,如果报错 含有
TypeError: this.getOptions is not a function则为less-loader版本过高,需要降级,yarn add --dev less-loader@5.0.0(6.0.0也可)
添加项目基础配置
-
添加绝对路径@
1.在config文件夹下的webpack.config内 搜索alias,在对象内配置一行
'@': path.resolve('src'),2.在 根目录的 tsconfig.json内 compilerOptions对象内配置一行
"paths": { "@/*": ["./src/*"] } -
添加globle.less
删掉index.css 替换为globle.less,放置基本的样式重置 body,ul等等, index.txs内引入globle.less
-
项目结构划分
在src内 新建 pages目录,放置基本(Home, PerCenter)页面,新建components 放各个页面通用的组件,一些header,footer等, App.tsx迁移到pages下,新建serve文件夹,放置api接口,utils公共工具等等,文章最后会放置项目整理结构以及github地址。
-
less形式的引入
页面内引用less 新建 index.module.less 在 index.tsx 内
import s from './index.module.less'index.tsx完整代码
import React from 'react' import Header from 'components/Header' import s from './index.module.less' const Home: React.FC<{}> = () => { return ( <div> <Header /> <div className={s.Home}>home333333</div> </div> ) } export default Home -
路由 使用 react-router-dom 的路由
yarn add react-router-domyarn add @types/react-router-dom添加路由后app.tsx内代码
import React, { Suspense, lazy } from 'react' import { HashRouter, Route } from 'react-router-dom' const Home = lazy(() => import('./Home')) const PerCenter = lazy(() => import('./PerCenter')) function App() { return ( <div className="App"> <HashRouter> <Suspense fallback={<div>Loading...</div>}> <Route path="/" component={Home} /> <Route path="/PerCenter" component={PerCenter} /> </Suspense> </HashRouter> </div> ) } export default App -
axios
yarn add axios在utils内添加 添加 request.js 可以针对项目对ajax进行二次封装,方便后续使用 -
antd按需加载
yarn add antdyarn add babel-plugin-import在package.json 内的babel,在persets同级添加
"plugins":[["import",{"libraryName": "antd", "style": "css"}]] -
useContext + useReducer 数据共享
相对于redux使用简单不繁琐, 详见:juejin.cn/post/701223…