- 查看 README 方式
vscode
打开此文件 -> F1 -> 搜索 markdown -> Markdown: 打开侧边栏预览
- 调试 & 构建
- 命令解释
dll:dev
把 React 编译成动态链接库文件,代码没压缩,用于开发调试时,提示/报错信息更友好dll:pro
把 React 编译成动态链接库文件,代码已压缩,用于提交打包发布start
本地开发调试,此命令已包含dll:dev
start:self
本地开发调试,此命令不包含dll:dev
build:self
打包构建,打包所得的文件中,代码已压缩,脚本文件名为chunk-[id]
,此命令不包含dll:*
build:pro
打包构建,打包所得的文件中,代码已压缩,脚本文件名为chunk-[id]
,此命令已包含dll:pro
- * 命令中以
:self
结尾表示:该命令每次都执行对应的 dll 命令,即使 dll 文件已存在。
- 本地调试:
- 命令:
npm start
(start
比较特殊,写法上:npm start
等价于npm run start
) - 如果 dll 文件已存在,建议使用命令
npm run start:self
- 命令:
- 打包代码:
- 用于正式打包发布(内网/预发布/外网)
- 命令:
npm run build
- 提交注意 提交注意 提交注意
- 普通 commit:不要提交你本地
dist
目录下的文件; - 构建 commit:执行了
npm run build
命令后,要发布到内网的情况,就需要连同dist
下的所有文件一并提交。
- 普通 commit:不要提交你本地
- SVN 提交时,根目录下的 .idea, .vscode, analysis, cache, node_modules 这些文件夹不需要提交。设置 svn ignore 方法:
- 右键选中需要忽略的文件/夹,TortoiseSVN > Add to ignore list > 递归或者不递归;
- 查看 ignore list:项目根目录右击空白,TortoiseSVN > Properties,即可看到。
- 命令解释
- 技术框架
- webpack@4+
- 按需加载分割点:
react.lazy
进一步分割点:[common-chunk]
- 资源路径别名设置:
webpack.config.main.base > resolve.alias
,省去'../../..'
层层翻越去查找资源
- 按需加载分割点:
- react@16+
lazy
配合Suspense
- react-router@4+
- 路由即组件,分散在自定义组件中
- react-redux
- 数据管理框架,用其中的
connect
方法将组件的state
和method
映射成props
- 数据管理框架,用其中的
- react-saga
- redux 中间件,管理有副作用的
action
- redux 中间件,管理有副作用的
- immutable
- 将
state
转成immutable
对象,防止开发者无意识修改state
- 将
- webpack@4+
- 目录结构
- 全局
Store
(src\store
)- | -
index
:暴露store
,react-redux
利用在项目模块入口文件 (src\index.jsx
) 中提供的Provider
将其作为全局引入 - | -
actionTypes
:全局action
类型常量,瘦action胖reducer,所以redux-saga
中不处理业务,业务逻辑放在reducer
中处理 - | -
reducer
:全局reducer
利用combineReducers
方法组合分散在每个组件内的reducer
- | -
hotelSaga
:全局Redux-saga
,用于处理副作用action
,本项目目前只作为异步请求处理,详见官网第一句话描述:https://redux-saga.js.org/ 简单地改变state
就不需要用redux-saga
处理了。redux-saga
处理的范围由文件中的Generator
函数:hotelSaga
定义
- | -
- 注意: 在引入
actionTypes
类型常量时,只有在hotelSaga
全部引入,而在每个组件中的actionCreator
只引入该组件使用到的常量 - 一个公用文件通常会暴露许多方法(如:methods.js)或常量(如:actionTypes.js),对其引入的方式需考虑:
- 全部引入方式:
import * as objectName from 'path/module'
- 按需引入方式:
import { name } from 'path/module'
- 按需引入的方式,打包构建时,没使用到代码的会被
webpack
自动treeshaking
除掉
- 全部引入方式:
- 每个组件中建议只包含如下文件和目录:
- | -
componentName.jsx
:视情况可拆分为 容器组件 和 UI组件,能用 纯函数 就用纯函数 - | -
componentName.less
:组件的样式,如需修改第三方库的样式,添加:global
包裹三方样式,注意,其子元素内相同类名的三方样式也会被改写。记住一点:如果有多个相同类名,元素会继承最近父元素类名的样式 书写格式如下:.usercont { min-height: 100px; :global(.ant-empty) { color: rgba(0, 0, 0, 0.45); :global(.ant-empty-image) { height: 40px; } } }
- | -
store
:关于组件的数据- | -
actionCreator.js
:创建组件的action
- | -
reducer.js
:业务逻辑处理
- | -
- | -
[descendant's component directory]
:子组件目录,如果有的话
- | -
- 全局
- npm 依赖
css-loader
:不要升级,升级后,样式模块化CSS Module
会报错babel-plugin-import
:作为antd
按需加载的依赖包@babel/plugin-syntax-dynamic-import
:给webpack
动态import
提供支持@babel/plugin-proposal-async-generator-functions
:支持新语法提案generator
与async await
混合@babel/plugin-transform-runtime
:给generator
函数运行时
- 项目要点
- 按需加载方案:
React.lazy
与@loadable/component
对比参见:https://www.smooth-code.com/open-source/loadable-components/docs/loadable-vs-react-lazy/react-loadable
不再推荐使用; React.lazy
目前只支持用于export / export default
导出的组件,这样能保证treeshaking
正常使用。对于第三方库的组件和方法,除了三方库本身的按需加载方案之外(如:antd),不建议按需加载,采用传统的import
写法引入即可,本项目的按需加载(React.lazy
)用于项目内的自定义组件;Eslint
参考规则及处理方式:Eslint
配置请参见:https://github.com/isChosen/webpack-onDemand-more/blob/master/README.mdEslint Rules
参见官网:https://eslint.org/Eslint React Rules
参见:https://github.com/yannickcr/eslint-plugin-react- 注意:遇到
Eslint
报错时,请到以上网站查找原因,如果需要修改规则,请先跟组内同事讨论决定。确定要改的话,在.eslintrc.js
中修改,务必加上注释,注释格式参考已有注释
- 进入页面方式,必须登录后才能打开页面,否则重定向回登录页面。即使是粘贴输入
URL
,权限路由AuthorizedRoute
会发送一个请求验证是否登录有效 - 输入
URL
打开页面,路径中必须有app
才允许进入页面,若路径中没有app
则重定向到/login
页面。如果路径中在app
后面的路由路径有误,可自定义跳转页面,如:404
,本项目没指定 - 本项目中,mock data 只适合
GET
请求,因为POST
被视为修改数据的请求类型,请在项目目录下的mocks/mockConf.js
中配置,另参见配置中的注释说明。因 mock 的接口权重较高,遇同名接口时会覆盖其他接口请求,项目进展至联调阶段后请修正为真实接口
- 按需加载方案:
- 测试功能点
- 登录页 | 顶层容器 app | 拦截器 为三大顶层组件
- 打开项目首先进入
/login
页面,登录后跳转/app
将其重定向至/home
,每次进入(或刷新)/app/**/*
页面都会发送一个请求验证是否登录有效,若无效则重定向至/login
。进入了/app/**/*
后切换路由达到页面变化,是不会发送请求验证登录是否有效的,登录名和密码:abc 123
- 主要在
/home
页面做测试,页面中的按钮 Toggle background 、 Change self bk 和 Change parent bk 测试不使用redux-saga
处理action
的情况,改变/home
及其子组件someone
各自的背景颜色和测试子组件改变父组件的背景颜色(组件间相互通信) /home
页面的按钮 Get a random 获取一个随机数- 测试
redux-saga
处理Side Effects
的action
情况 - 测试根据返回结果中的状态码为 3 时,拦截器拦截每次请求的
response
会触发拦截器组件ResponseInterc
以重定向至登录页/login
- 测试
- 样式模块化 参见
ProductB.jsx AntdTest.jsx
组件及其关联的less
样式文件
1. react-router 4.x,正常写法时报 warnings,如下:
<Route path="/" exact component="{Home}" />
<Route path="/product" component="{Product}" />
<Route path="/about" component="{About}" />
<Route path="/login" component="{Login}" />
Warning: Failed prop type: Invalid prop `component` of type `object` supplied to `Route`, expected `function`.
in Route (created by App)
in App
in Router (created by BrowserRouter)
in BrowserRouter
- Solution
- 解决办法参见 github issue:remix-run/react-router#6420
component
可以换成render
两者的区别:component
会强制刷新其下的子组件,不管子组件的shouldComponentUpdate
是否return false
render
表现正常,刷不刷新子组件由shouldComponentUpdate
返回结果决定,建议使用render
- 将其写成如下格式,即可 fix warning,如下:
<Route path="/" exact component={props => <Home {...props} />} /> <Route path="/product" component={props => <Product {...props} />} /> <Route path="/about" component={props => <About {...props} />} /> <Route path="/login" component={props => <Login {...props} />} />
2. react-router 4.x 刷新内嵌路由的页面报错,而刷新顶级路由没问题
- Solution
- 把
BrowserRouter
换成HashRouter
即可, 参见:https://blog.csdn.net/zwkkkk1/article/details/83411071
- 把