2.0.0 • Published 7 years ago

dbp-react-expres-mongo_db v2.0.0

Weekly downloads
-
License
ISC
Repository
-
Last release
7 years ago

开发文档(Asiainfo erp Internal use system--dbp)

up--2017.5.29

  • 一、技术栈

webpack https://webpack.toobug.net/zh-cn/chapter2/

react http://www.css88.com/react/docs/animation.html

react-router http://www.ruanyifeng.com/blog/2016/05/react_router.html?utm_source=tool.lu http://www.uprogrammer.cn/react-router-cn/

react-redux http://cn.redux.js.org/index.html

express http://www.expressjs.com.cn/

es6 http://es6.ruanyifeng.com/#docs/destructuring

less http://less.bootcss.com

antd https://ant.design/components/icon/

  • 二、实现功能

    	* 1.利用webpack实现开发环境与生产环境的资源整合、热替换、按需加载等功能
    	* 2.利用react实现数据渲染视图
    	* 3.利用react-router实现客户端路由功能-单页面spa
    	* 4.利用express搭建前端服务、结合swagger生成后端代理接口
    	* 5.利用less对css开发的友好化
    	* 6.利用es6语法和新属性提高开发效率、页面性能
    	* 7.利用antd节省了大量招轮子时间
  • 三、开发目录

	├── api -- 通过swagger生成代理后端api
	├── middleware -- express中间件集中营
	├── request -- 接收各种来自客户端的请求
	│        └── async -- 接收异步请求
	├── node_modules
	├── publish -- 发布时生成的文件(不用理它)
	├── source -- 源码目录
	│   ├── src
	│   │    ├── redux
	│   │    │    ├── action -- redux_action存放开发目录
	│   │    │    ├── reducers -- redux_reducers存放开发目录
	│   │    │    └── middleware -- redux_middleware
	│   │    │          ├── logger -- redux日志
	│   │    │          └── localStorage -- 本地存储(action包涵localStorage属性均本地存储)
	│   │    ├── module -- 页面视图、交互逻辑部分
	│   │    │    ├── use -- 各页面入口
	│   │    │    └── widget -- 公共模块
	│   │    ├── routes -- 客户端路由实现部分
	│   │    │    └── rootRoute -- 路由入口
	│   │    └── index.js -- javascript入口
	│   └── static -- 公共静态资源
	│        ├── images 
	│        ├── javascript
	│        └── less
	├── .baelrc
	├── webpack.config.js
	├── server.js
	└── app.js
  • 四、开发前准备

    	* #### 1.svn、github
    	* #### 2.npm install、npm install webpack -g、npm run getApi
    	* #### 3.sublime安装babel、JsFormat设置"e4x": true
  • 五、使用

    	* #### package scrpits
    		* 1.npm star 启动开发环境
    		* 2.npm start-tools 启动开发环境并打开store监听视图模块(有点问题)
    		* 3.npm run publish 打包并发布
    		* 4.npm run getApi 生成代理接口
    
    	* #### contrller
    		* 1.代理后端的api通过npm run getapi生成
    		* 2.客户端请求通过async目录下的express_Mini_router访问
    		* 3.express中间件规整在middleware中
    
    	* #### src
    		* 1.action type建议使用Symbol类型保障安全
    
    				export const SET_LOGIN_ACTIVE = Symbol('SET_LOGIN_ACTIVE');
    
    				export const setLoginAction = index => ({

    type: SET_LOGIN_ACTIVE, index }); async_action

    				//demo 一般情况够用了
    				/*
    				 *  异步action
    				 *  statusAction {dispatsh} 异步请求前后触发的dispatsh
    				 *  start {opt} 异步请求前传入action的关键属性
    				 *  end {opt} 异步请求后传入action的关键属性
    				 *  opts {arg} fetch参数
    				 */
    				export const sendAsyncAction = ({

    statusAction, start, end }, ...opts) => (dispatch) => {

    if (start) statusAction(start);

    return fetch(...opts) .then(response => response.json(), err=> err) .then(json => statusActend, json));

    				}
    			promise_action
    		
    					/*
    					 *  p1 action ispromise
    					 */
    					export const sendPromiseAction = ({
    					    action
    					}, ...opts) => {
    					    return fetch(opts)
    					        .then(response => action(response.json()))
    
    					};
    
    					//p2 action.payload ispromise
    
    					export const sendPromisePayloadAction = (type, ...opts) => ({
    					    type: type,
    					    payload: fetch(opts)
    					        .then(response => action(response.json()))
    					})
    
    					//感觉目前用了redux-thunk就用不上这个玩意了(ps:可能还没想到场景,哈哈) 有兴趣可以去看下源码了解下/node_modules/redux-promise/lib/index.js
    		* 2.书写 reducers 改变 state时切记不要直接改变state,可以通过es6剩余参数或assgin合并覆盖、Immutable操作 [相关文档](http://cn.redux.js.org/docs/basics/Reducers.html)
    
    				{ ...state, ...newState }✅正确姿势
    	
    				Object.assign({},state, { visibilityFilter: action.filter })✅正确姿势
    	
    				export const retraceSlideTitle = (title = titleDefault, action) => {✅正确姿势

    switch (action.type) { case GET_RE_TRACE_SLIDE_TITLE:

          			let $$title = Immutable.List.of(...title);
          			let titleIndex = $$title.indexOf(action.title)
          			let titleBool = $$title.includes(action.title)
    
          			if (titleBool) {
              			return $$title.slice(0, titleIndex + 1).toJS();
          			} else {
              			return [...$$title.toJS(), action.title];
          			}
    
      			default:
          			return title;

    } }

    				Object.assign(state, { visibilityFilter: action.filter })❌错误姿势
    	
    				state.xxx = xxx ❌错误姿势
    	
    		* 3.module 一个模块等于一个文件夹,一个文件夹包涵了它所有的独有的资源,告别传统开发的资源散乱在各个目录中。另外使用less时,除公共样式直接给样式名外其余less需要导入后.classname
    
    				import style from './index.less';
    				<div className={style.div}> 导入独有样式

    index 公共样式

    				</div>
    
    		* 4.routes 在开发页面级的widget时最好通过router去设置,其功能类似nunjucks的extents
    	
    				//router
    				const index = {

    path: 'index', indexRoute: { getComponent(nextState, callback) { require.ensure([], (require) => { callback(null, require('useModule/System/workIndex/workIndex').default) }, 'use/System/workIndex') }, }, getComponent(nextState, callback) { require.ensure([], (require) => { callback(null, require('widModule/headFoot/headFoot').default) }, 'widget/headFoot') }, childRoutes: require('./workDemo').default, require('./workDemo2').default }

    				export default index;
    			
    				//headFoot
    				export default class headFoot extends Component {

    render() { return (

          				<div className='fn-bgd-fff fn-h-rate100'>
              				<HeadContent/>
              				{this.props.children}
              				<FootContent/>
          				</div>
      				)

    } }

    				//childroutes module直接写就是了不再需要引用 headfoot
    				class workDemo extends Component {

    render() { return (

          				<div>
    							........
          				</div>
      				);

    } }

    	* #### static
    		* 1.公共资源存放处,less除reset外,按style属性分类,另外antdExtents.less为覆盖antd style 文件,然后baseConfig为less变量文件
    	* #### async request
    		* 1.请求url为request 内目录结构拼接+自定义
    	* #### 路径别名
    		* 1.可以到webpack.base.config.js里去配置alias
    		* 2.目前有	
    			
    				//src下目录
    				'rActions': path.join(__dirname, './source/redux/src/actions'),
          	'rReducers': path.join(__dirname, './source/redux/src/reducers'),
          	'rmiddleware': path.join(__dirname, './source/redux/src/middleware'),
          	'sRoutes': path.join(__dirname, './source/src/routes'),
          	//static下目录
          	'jStatic': path.join(__dirname, './source/static/javascript'),
          	'lStatic': path.join(__dirname, './source/static/less'),
          	'iStatic': path.join(__dirname, './source/static/images'),
          	//module下目录
          	'useModule': path.join(__dirname, './source/src/module/use'),
          	'widModule': path.join(__dirname, './source/src/module/widget'),
  • 六、存在问题

    	* #### 1.貌似reducers、routes都存在开发期间开发人员都会动到根级文件从而导致冲突的情况,虽然只是少量内容的冲突非常好解决,不晓得各位有木有解决的办法
    	* #### 2.想区分package script 配置除环境参数以外的值,从而是否开启tools工具,然而没找到入参到客户端code的方法。