dbp-react-expres-mongo_db

2.0.0 • Public • Published

开发文档(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操作 相关文档

          { ...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<input className='input-main focus'/> 公共样式
          </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的方法。

Readme

Keywords

Package Sidebar

Install

npm i dbp-react-expres-mongo_db

Weekly Downloads

1

Version

2.0.0

License

ISC

Last publish

Collaborators

  • dbp