react-demo

React 示例项目 · 简易留言板。本项目拥有完善的文档说明与注释,让您快速上手 React 开发 SPA。Webpack / ES6 + Babel / Redux / React Router —— An Excellent React Starter,可能是东半球最佳的 React Starter,基于 Vue Cli 二次开发

React 示例项目 · 简易留言板 + 待办事项

应用截图 > ###写在前面 > 一直以来,我都相当纳闷:为什么 React 的那些 starter kit 都构建得那么恶心? > 能不能像 Vue Cli 生成的项目架构般优雅?说干就干,本项目就改自 Vue Demo > > ### 更新 > 2016/8/28   引入 cross-env 解决跨平台问题,新增优化项 DedupePlugin > 2016/8/29   重命名 makeContainer / makeReducer.js => createContainer / createReducer.js > 2016/9/10   重构 src/redux/ > 2016/10/15   同步 Vue Demo 的改动 > 2016/10/16   改进:仅在开发模式下引入 React Hot Loader

目录

§ 技术栈

§ 快速开始

  • 安装

  • 启动

    § 项目架构

  • 目录结构

  • 特色

    § 开发

  • Webpack 配置

  • 规范

  • 性能

    § 测试

    § 部署

    § 参考

    ****

    § 技术栈

    详情可参阅 package.json

  • React 15.3.0

  • Redux

  • React Router

  • Ajax 请求库(Superagent / jQuery-Ajax / …)

  • Webpack

  • ES6 + Babel

  • jQuery + BootStrap (UI) ***

    § 快速开始

    在开始前,希望您已通读如下资料

  • React 文档

  • Redux 文档(看完后懵逼的请转看 Redux 莞式教程

  • React Router 文档 同时您还需要熟悉 ES6。例如,请把如下代码 const foo = ({ hello: { world: bar } }) => ({ bar }) 转译成 ES5(答案请自行到 Babel REPL 在线编译验证)

    ⊙ 安装

    推荐升级到 node 5.x/6.x + npm 3.x 环境,强烈推荐使用 cnpm 安装依赖或手动 切换到淘宝 npm 源:npm set registry https://registry.npm.taobao.org/ (经测试,cnpm 对于 node-sass 等问题多多的 Package 拥有秒杀能力) 本示例项目需要结合 简易留言板 RESTful API 模拟前后端分离开发(还为了与 Vue Demo 共用) 请分别 git clone,打开两个命令窗口( Windows 下推荐使用 Cygwin / Git Bash分别切换到两者的目录下 分别敲下 npm install 安装依赖(为避免 Windows 下 npm 2.x 的软链接问题,可加上 --no-bin-link 完全解构所有依赖) 最后需要全局安装跨平台环境变量配置器:npm i cross-env -g

    ⊙ 启动

    先后在 msg-board-apireact-demo 的命令窗口下,敲下 npm start 如无意外,默认浏览器就会自动打开 localhost:9090,您立即可以看到效果 若浏览器没有自动弹出,则请自行手动访问 P.S. 如果您还不清楚如何安装与启动,请看这个 issue ***

    § 项目架构

    ⊙ 目录结构

    . ├─ build/ # Webpack 配置目录 ├─ dist/ # build 生成的生产环境下的项目 ├─ src/ # 源码目录(开发都在这里进行) │ ├─ assets/ # 放置需要经由 Webpack 处理的静态文件 │ ├─ components/ # 组件(COMPONENT) │ ├─ redux/ # Redux 一箩筐 │ │ ├─ actions/ # (ACTION) │ │ ├─ reducers/ # (REDUCER) │ │ ├─ store/ # (STORE) │ ├── routes/ # 路由(ROUTE) │ ├── services/ # 服务(SERVICE,用于统一管理 XHR 请求,这是从 Vue Demo 中直接复制过来的) │ ├── utils/ # 工具库(UTIL) │ │ ├─ HoC/ # 高阶组件(HOC,全称 Higher Order Component) │ │ ├─ mixins/ # 混合(MIXIN) │ ├── views/ # 路由视图基页(VIEW) │ │ ├─ layout/ # 全局布局 │ ├── app.js # 启动文件 │ ├── index.html # 静态基页 ├── static/ # 放置无需经由 Webpack 处理的静态文件 ├── .babelrc # Babel 转码配置 ├── .eslintignore # (配置)ESLint 检查中需忽略的文件(夹) ├── .eslintrc # ESLint 配置 ├── .gitignore # (配置)需被 Git 忽略的文件(夹) ├── package.json # (这个就不用多解释了吧) 在这里您可能会问:怎么没有 containers/ 目录? 在本项目中,木偶组件与智能组件最大的差别在于: 前者的状态是通过父组件传入获得,而后者是直接连接state 获得 亦即:若一个木偶组件直接连接state,那么它就是一个所谓的智能组件 (详见 src/utils/createContainer.js 中对 react-reduxconnect 函数的封装) 本示例项目唯一在组件的定义中自行使用 connect 函数的是 Navbar 组件(且用到了 ES7 的装饰器) 有关木偶组件与智能组件更为精确的论述,推荐 Redux 作者 Dan 的这篇文章,避免教条主义 您可以根据业务需求改动目录结构。若目录使用频繁,建议配置 路径别名 默认的路径别名见上面目录结构注释中大写形式的常量

    ⊙ 特色

  • 本示例项目秉承最佳实践,高度洁癖地实现代码分离/复用

  • 优化目录结构,更好的模块分离,更接近 Vue 的开发模式

  • Redux DevTools,可选 Chrome 插件形式(默认) 或 内嵌页面的组件形式

  • Redux Logger 打印动作及前后状态变化

  • why-did-you-update 检测不必要的组件重渲染(默认关闭)

  • 引入服务层统一管理 XHR 请求(好处请参考 Vue Demo 中的 引入服务层

  • 引入 路径别名 实现优雅的加载模式

  • 引入 React Hot Reload,支持热替换

  • 生产环境下的编译对代码进行优化

  • 迄今为止我见过的最完美的 starter kit > 有关 Redux DevTools 与 why-did-you-update 的启用与禁用,见下面的 开发环境全局变量 配置 ***

    § 开发

    ⊙ Webpack 配置

    由于已经拥有相对成熟的 Webpack 配置,因此在一定程度上您可以不求甚解,但了解其配置会更能把握整体开发

  • 前端开发服务器为 localhost:9090,可在 build/webpack.config.dev.js 中找到 > 后端 RESTful API 基地址写在了 src/services/xhr/config.js 中,请根据实际自行修改

  • 框架 / 类库 须分离打包以加快开发时的编译速度并有利于缓存,详见 build/webpack.base.conf.js 中的 vendor > 实际上该步骤可通过读取 package.jsondependencies 字段实现自动化,但其灵活度不够高,必要性也不大 > P.S. 安装包时勿忘 --save / --save-dev 以添加依赖记录

  • 路径别名 的定义位于 build/webpack.base.conf.js,好处就是引入与重构都很方便 > 例如,在某组件中,引入 userService 需要 import userService from '../../../services/userService' > 但有了路径别名后,只需要 import userService from 'SERVICE/userService' > 相比于 AngularJS 中的依赖注入,这种方式依赖于构建工具,显得更为简单 > > 您可能会说,Webpack 只需要设定了 root属性为 src/ > 就可以 import userService from 'services/userService' > 但在这里其实是会引起歧义的(不过这属于强迫症的范畴。。。) > 例如,import createBrowserHistory from 'history/lib/createBrowserHistory' > 您可能会觉得这是 src/history/lib/createBrowserHistory.js > 但实际上 history 是一个 npm package > 同样地,您又怎么知道 services 不是一个 npm package? > 而且重构之后,文件夹的变动会导致相对路径的变化,services/ 目录未必仍在 src/ 下 > 因此,路径别名相当有必要。其常量的形式,让人一看就知道不是一个 npm package

  • 开发环境全局变量,由 webpack.DefinePlugin 提供(详见 build/webpack.base.conf.js) > 默认有 __DEV__ / __PROD__ / __COMPONENT_DEVTOOLS__ / __WHY_DID_YOU_UPDATE__ 四个全局变量 > 若要继续添加,则还需要在 .eslintrcglobals 同步写入 > > 在此需要提醒,在 package.json 中设置 NODE_ENV 要注意末尾空格的问题 > 最好就是使用前 trim 一下:process.env.NODE_ENV.trim() > > 拓展阅读:解读 UglifyJS > 看看生产环境下编译 if (__PROD__) { ... } => if (true) { ... }UglifyJS 会如何处理

    ⊙ 规范

    本示例项目的代码极尽详细地添加了注释,其中不乏最佳实践提示 为了减少代码量,我省去了 Prop 验证,建议您在往后的开发中使用

    ⊙ 性能

    大概可参阅如下文章:

  • React 文档 · Advanced Performance

  • 反鸡汤 · Should I use shouldComponentUpdate译文

  • 淘宝 FED · 高性能 React 组件

  • 腾讯 Dev Club · React 移动 Web 极致优化 ***

    § 测试

    请自行选择测试工具 ***

    § 部署

    react-demo 的命令窗口下,敲下 npm run build,将会在项目根目录下生成 dist/ 您可以使用命令行静态资源服务器 serve ( npm i serve -g ),敲下 serve dist/ -p [端口] 来快速查看 build 后的项目 还可以 cd dist 后,python -m SimpleHTTPServer [端口]php -S localhost:[端口] 快速便捷地实现静态资源服务器 关于生产环境下的部署与优化,已超出本文档的论述范围,请自行查阅相关资料 ***

    § 参考

  • Vue Demo

  • davezuko/react-redux-starter-kit

  • 探讨 React 项目目录结构

Related Repositories

react-demo

react-demo

React 示例项目 · 简易留言板。本项目拥有完善的文档说明与注释,让您快速上手 React 开发 SPA。Webpack / ES6 + Babel / Redux / React Router —— An Excellent React Starter,可能是东半球最佳的 React Starter,基于 Vue Cli 二次开发 ...

dotnetify-react-demo-vs2017

dotnetify-react-demo-vs2017

DotNetify-React demo using Visual Studio 2017 + WebPack ...

react-example-modern-javascript

react-example-modern-javascript

The thinking in react demo recreated with modern javascript (aka ES15+ or es6+) ...

react-example-es2015

react-example-es2015

The thinking in react demo recreated with ES15 (aka es2015 or es6) ...

spring-kotlin-react-demo

spring-kotlin-react-demo

Demo Webapp using SpringBoot, Kotlin and React.js ...


Top Contributors

kenberkeley LittleStupid LuckyMona