REACT-SAGA 入门项目搭建笔记
用于学习记录
项目地址:开源中国
Install
Core Lib
//webpack
npm install --save-dev webpack
npm install --save-dev webpack-dev-server
//react
npm install --save react react-dom
//router v4版本
npm install --save react-router react-router-dom
//redux
npm install --save redux react-redux redux-saga
//babel
npm install --save-dev babel-core babel-loader babel-preset-react babel-preset-es2015 babel-preset-stage-0 babel-preset-stage-3
Plugins
Webpack-Browser-Plugin
用于自动打开浏览器
new WebpackBrowserPlugin()
Html-Webpack-Plugin
用于动态生成index入口页面
new HtmlWebpackPlugin({
title: 'Development'
})
Clean-Webpack-Plugin
清空webpack某个目录、一般用于构件项目之前清空项目输出目录,如:
new CleanWebpackPlugin(['dist']),
Loader
用于编译jsx、es6、react代码的loader
rules: [{
test: /.jsx?$/,
exclude: /node_modules/,
use: [{
loader: "babel-loader"
}],
}]
Init
初始化核心对象
Saga
集中管理action分发、调用
/**
- saga 集中管理action分发、异步操作
- action约定:
- type:
- 异步:FETCH_${ACTION.TYPE}
- 同步:LOCAL_${ACTION.TYPE}
-
- asyn:true|false
- data:Object
-
*/
import {fork,put,take,call} from 'redux-saga/effects'
import util from './util'
/**
- 加载数据方法
- 在这里、我们可以集中调用真实的API接口
- 我们可以把action type 和 api url 做个映射
- 这样的话、我们可以减少重复的调用接口方法
- @Author WangBing
- @DateTime 2017-11-07
- @returns {[type]} [description]
*/
function load(data){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(data);
},100)
})
}
/**
- 用于开发调试的工具函数
- @Author WangBing
- @DateTime 2017-11-07
- @param {[type]} action [description]
- @returns {[type]} [description]
*/
function logger(action){
console.log(`dispatche action`);
console.dir(action)
}
/**
- 异步加载数据
- @Author WangBing
- @DateTime 2017-11-07
- @param {[type]} action [description]
- @yields {[type]} [description]
*/
function* asynLoader(action){
try{
var result=yield call(load,action.data);
yield put({
type:util.success(action.type),
data:result
})
return result;
}catch(e){
console.error('run action:'+action.type);
console.error("action load error with a exception")
console.error(e)
}
}
/**
- 定义一个Watcher监控所有类型的action
- @Author WangBing
- @DateTime 2017-11-07
- @yields {[type]} [description]
*/
function* watcher(){
while(true){
const action=yield take("*");
logger(action);
if(action.sync){
yield put(action);
}else{
yield call(asynLoader,action);
}
}
}
export default function* rootSaga(){
yield fork(watcher);
}
Store
初始化store
import {createStore,applyMiddleware} from "redux";
import createSagaMiddleware from 'redux-saga';
import RootReducer from './reducer';
var sagaMiddleware=createSagaMiddleware();
var store=createStore(RootReducer,applyMiddleware(sagaMiddleware));
export default {
...store,
run:sagaMiddleware.run
}
Reducer
分模块初始化reducer
import { combineReducers } from 'redux'
import AppReducer from 'src/router/reducer';
import HomeReducer from 'src/router/home/reducer';
export const RootReducer=combineReducers({
app:AppReducer,
home:HomeReducer
})
export default RootReducer
Build Performance
Devtool
不同的devtool模式、有不用的效果、需要合理设置
devtool | build speed | rebuild speed | production supported | qualtiy |
---|---|---|---|---|
eval | +++ | +++ | no | generdared code |
cheap-eval-source-map | + | ++ | no | transformed code(lines only) |
cheap-source-map | + | 0 | yes | transformed code(lines only) |
cheap-module-eval-source-map | 0 | ++ | no | original source(lines only) |
cheap-module-source-map | 0 | - | yes | original source(lines only) |
eval-source-map | - | + | no | original source |
source-map | - | - | yes | original source |
开发环境推荐:
cheap-module-eval-source-map
生产环境推荐:
cheap-module-source-map