diff --git a/.babelrc b/.babelrc
new file mode 100644
index 0000000..09fba6d
--- /dev/null
+++ b/.babelrc
@@ -0,0 +1,3 @@
+{
+ presets: ["es2015", "react","stage-1"]
+}
\ No newline at end of file
diff --git a/client/App-Client.jsx b/client/App-Client.jsx
index 48b36d2..144d0ec 100644
--- a/client/App-Client.jsx
+++ b/client/App-Client.jsx
@@ -6,7 +6,7 @@ import AppRoutes from '../common/AppRoutes.js';
//状态管理
import {Provider} from 'react-redux';
-import configureStore from '../common/store/store.js';
+import configureStore from '../common/store/index.js';
// `__INITIAL_STATE__` 来自服务器端渲染
diff --git a/client/Layout.jsx b/client/Layout.jsx
deleted file mode 100644
index c0cf1d6..0000000
--- a/client/Layout.jsx
+++ /dev/null
@@ -1,20 +0,0 @@
-import React,{Component} from 'react';
-// import {Link} from 'react-router';
-
-import Header from './component/Header';
-import Footer from './component/Footer';
-
-
-class Layout extends Component {
- render() {
- return (
-
-
-
- {this.props.children}
-
-
-
- );
- }
-}
\ No newline at end of file
diff --git a/client/component/Edit.jsx b/client/component/Edit.jsx
deleted file mode 100644
index e69de29..0000000
diff --git a/client/component/Footer.jsx b/client/component/Footer.jsx
deleted file mode 100644
index c612da9..0000000
--- a/client/component/Footer.jsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import React, {Component} from 'react'
-// import {Link} from 'react-router';
-
-/**
- * Footer组件,可定义些尾部信息
- */
-const Footer = ()=> {
-
-}
-
-export default Footer;
\ No newline at end of file
diff --git a/client/component/Header.jsx b/client/component/Header.jsx
deleted file mode 100644
index e5a90c1..0000000
--- a/client/component/Header.jsx
+++ /dev/null
@@ -1,16 +0,0 @@
-import React, {Component} from 'react'
-import {Link} from 'react-router';
-
-/**
- * Header组件,可定义些头部标题,头像
- */
-const Header = ()=> {
-
-
- Hello World! This is my Blog
-
-
-}
-
-
-export default Header;
\ No newline at end of file
diff --git a/client/component/Layout.jsx b/client/component/Layout.jsx
deleted file mode 100644
index 51cca30..0000000
--- a/client/component/Layout.jsx
+++ /dev/null
@@ -1 +0,0 @@
-import React from 'react';
\ No newline at end of file
diff --git a/client/component/Posts.jsx b/client/component/Posts.jsx
deleted file mode 100644
index e69de29..0000000
diff --git a/client/component/Signin.jsx b/client/component/Signin.jsx
deleted file mode 100644
index e69de29..0000000
diff --git a/client/component/Signup.jsx b/client/component/Signup.jsx
deleted file mode 100644
index e69de29..0000000
diff --git a/client/component/signput.jsx b/client/component/signput.jsx
deleted file mode 100644
index e69de29..0000000
diff --git a/common/AppRoutes.js b/common/AppRoutes.js
index 5574434..a4cef02 100644
--- a/common/AppRoutes.js
+++ b/common/AppRoutes.js
@@ -1,28 +1,18 @@
import React from 'react';
-import {Route, Redirect} from 'react-router';
-
-import Layout from '../client/Layout.jsx';//布局页面
-import Signin from '../client/component/Signin.jsx';//登入,签到
-import Signout from '../client/component/signput.jsx';//登出
-import Signup from '../client/component/Signup.jsx';//注册
-import Posts from '../client/component/Posts.jsx';//文章页
-
-
-import NotFoundPage from './NotFoundPage.jsx';//错误页
+import {Route, IndexRoute} from 'react-router';
+import Layout from './components/Layout.jsx';//布局页面
+import Counterpage from './containers/Counterpage.jsx';
+import Todopage from './containers/Todopage.jsx';
+import Indexpage from './components/Indexpage.jsx';
+
//注意这个重定向路由
const AppRoutes = (
-
-
-
-
-
-
-
-
-
+
+
+
);
diff --git a/common/NotFoundPage.jsx b/common/NotFoundPage.jsx
deleted file mode 100644
index e69de29..0000000
diff --git a/common/action/counteraction.js b/common/action/counteraction.js
new file mode 100644
index 0000000..8050fe0
--- /dev/null
+++ b/common/action/counteraction.js
@@ -0,0 +1,26 @@
+import request from 'axios';
+import fetch from 'isomorphic-fetch';
+
+export const ADD_COUNT = 'ADD_COUNT';
+
+export const ASYNC_REQUEST_ADD ="ASYNC_REQUEST_ADD";//异步请求中
+export const ASYNC_RECEIVE_ADD ="ASYNC_RECEIVE_ADD";//成功收获数据
+
+
+
+export const counterAction=()=> {//同步
+ return {
+ type: ADD_COUNT
+ }
+}
+
+const AsyncCounterAction=()=>{//异步
+ return dispatch=>{
+ dispatch({type:ASYNC_REQUEST_ADD});//先分发一个action表明请求中
+ return fetch('/api/posts')
+ .then(response=>response.json())
+ .then(json=>dispatch({type:ASYNC_RECEIVE_ADD, data:json}));
+ }
+}
+
+export default AsyncCounterAction;
\ No newline at end of file
diff --git a/common/action/posts.js b/common/action/posts.js
deleted file mode 100644
index 7d997fa..0000000
--- a/common/action/posts.js
+++ /dev/null
@@ -1,122 +0,0 @@
-import fetch from 'isomorphic-fetch';
-
-/*
- * action 类型:
- * 与post相关
- */
-export const INVALIDATE_POSTS = 'INVALIDATE_POSTS';
-export const REQUEST_CREATE_POST_BY_USERID= 'REQUEST_CREATE_POST_BY_USERID';
-export const REQUEST_UPDATE_POST_BY_ID = 'REQUEST_UPDATE_POST_BY_ID';
-export const REQUEST_DEL_POST_BY_ID = 'REQUEST_DEL_POST_BY_ID';
-export const REQUEST_POSTS = 'REQUEST_POSTS';
-export const RECEIVE_POSTS = 'RECEIVE_POSTS';
-
-/*
- * action 函数:
- */
-
-function requestPosts() {//只返回一个正在请求的状态
- return {
- type: REQUEST_POSTS,
- }
-}
-
-function requestUpdatePostById() {//只返回一个正在请求的状态
- return {
- type: REQUEST_UPDATE_POST_BY_ID,
- }
-}
-
-function requestDeletePostById() {//只返回一个正在请求的状态
- return {
- type: REQUEST_DEL_POST_BY_ID,
- }
-}
-
-
-function requestCreatePostByUser() {
- return {
- type: REQUEST_CREATE_POST_BY_USERID,
- }
-}
-
-function receivePosts(jsonData) {
- return {
- type:RECEIVE_POSTS,
- posts: jsonData
- }
-}
-
-function errorGetPost(){
- return {
- type: INVALIDATE_POSTS
- }
-}
-
-
-export function fetchPosts() {
- return (dispatch,getState)=>{
- dispatch(requestPosts());//先表明正在请求
- return fetch('/api/posts')
- .then(res=>res.json())
- .then(json=>dispatch(receivePosts(json)))
- }
-}
-
-
-export function createPostByUser(post, user){
- return (dispatch,getState)=>{
- dispatch(requestCreatePostByUser());//先表明正在请求
-
-
- let option={
- method:'post',
- headers:{
- 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8'
- },
- body:{
- post,
- user
- }
- };
- return fetch('/api/post',option)
- .then(res=>res.json())
- .then(json=>dispatch(receivePosts()))
- .catch(()=>dispatch(errorGetPost()));
- }
-}
-export function updatePostById(postId) {
- return (dispatch,getState) =>{
- dispatch(requestPosts());//先表明正在请求
-
- let option={
- method:'post',
- headers:{
- 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8'
- },
- body:[]
- };
- return fetch(`/api/posts/${postId}/edit`,option)
- .then(res=>res.json())
- .then(json=>dispatch(receivePosts(json)))
- .catch(()=>dispatch(errorGetPost()));
- }
-}
-
-export function delePostById(postId) {
- return (dispatch,getState) =>{
- dispatch(requestPosts());//先表明正在请求
-
- let option={
- method:'post',
- headers:{
- 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8'
- },
- body:[]
- };
- return fetch(`/api/posts/${postId}/remove`)
- .then(res=>res.json())
- .then(json=>dispatch(receivePosts(json)))
- .catch(()=>dispatch(errorGetPost()));//获取失败时
- }
-}
\ No newline at end of file
diff --git a/common/action/todoaction.js b/common/action/todoaction.js
new file mode 100644
index 0000000..0f9299b
--- /dev/null
+++ b/common/action/todoaction.js
@@ -0,0 +1,10 @@
+export const ADD_TODO = 'ADD_TODO';
+
+const todoAction=(todoTxt)=> {
+ return {
+ type: ADD_COUNT,
+ todo:todoTxt
+ }
+}
+
+export default todoAction;
\ No newline at end of file
diff --git a/common/action/user.js b/common/action/user.js
deleted file mode 100644
index 044dfde..0000000
--- a/common/action/user.js
+++ /dev/null
@@ -1,104 +0,0 @@
-export const REQUEST_SIGNIN = 'REQUEST_SIGNIN';
-export const REQUEST_SIGNINUP ='REQUEST_SIGNINUP';
-export const REQUEST_SIGNINOUT = 'REQUEST_SIGNINOUT';
-export const ERROR_USER='ERROR_USER';
-
-export const FINISH_SIGNIN='FINISH_SIGNIN';
-export const FINISH_SIGNUP ='FINISH_SIGNUP';
-export const FINISH_SIGNOUT='FINISH_SIGNOUT';
-
-function requestSignin(){
- return {
- type:REQUEST_SIGNIN
- }
-}
-
-function requestSignup(){
- return {
- type:REQUEST_SIGNINUP
- }
-}
-
-
-function requestSignout(){
- return {
- type:REQUEST_SIGNINOUT
- }
-}
-
-
-//完成后的状态
-function finishSignin(userInfo){//登录
- return {
- type: FINISH_SIGNIN,
- userInfo
- }
-}
-
-function finishSignup(userInfo){
- return {
- type: FINISH_SIGNUP,
- userInfo
- }
-}
-
-function finishSignout(userInfo){
- return {
- type: FINISH_SIGNOUT,
- userInfo
- }
-}
-
-function errorUserHandle(){
- return {
- type: ERROR_USER
- }
-}
-
-
-
-
-export default UserSignin=(username,password)=>{//登录
- return (dispatch,getState)=>{
- dispatch(requestSignin());
-
- let option = {
- method:'post',
- headers:{
- 'Content-Type': 'application/x-www-form-urlencoded'
- },
- body:`username=${encodeURIComponent(username)}&password=${encodeURIComponent(password)}`
- }
- return fetch('/api/signin',option)
- .then(userinfo=>dispatch(finishSignin(userinfo)))
- .catch(()=>dispatch(errorUserHandle()));
- }
-}
-
-export default UserSignup=(username,password,repassword,gender)=>{//注册,表单数据
- return (dispatch,getState)=>{
- dispatch(requestSignup());//先表明正在请求
-
- let option = {
- method:'post',
- headers:{
- 'Content-Type': 'application/x-www-form-urlencoded'
- },
- body:`username=${encodeURIComponent(username)}&password=${encodeURIComponent(password)}&
- repassword=${encodeURIComponent(repassword)}&gender=${encodeURIComponent(gender)}`
- }
-
- return fetch('/api/signup',option)
- .then(userinfo=>dispatch(finishSignup(userinfo)))
- .catch(()=>dispatch(errorUserHandle()));
- }
-}
-
-export default UserSignout=(user)=>{//通过user来设置登出
- return (dispatch,getState) =>{
- dispatch(requestSignout());//先表明正在请求
- return fetch(`/api/signout/`)
- .then((message)=>dispatch(finishSignout(message)))
- .catch(()=>dispatch(errorUserHandle()));
- }
-}
\ No newline at end of file
diff --git a/common/components/Counter.jsx b/common/components/Counter.jsx
new file mode 100644
index 0000000..01ddaf6
--- /dev/null
+++ b/common/components/Counter.jsx
@@ -0,0 +1,47 @@
+import React,{Component} from 'react';
+import {Link} from 'react-router';
+
+
+class Counter extends Component {
+ constructor(props){
+ super(props);
+
+ }
+ componentDidMount () {
+ console.log("Counter did mount");
+ }
+
+ handleClick=(e)=>{
+ const {onIncreaseClick} = this.props;
+ e.preventDefault();
+ console.log("click");
+ onIncreaseClick();//改变状态,触发action,props会自动随之变化,由react-redux提供,我只需要提供UI组件
+ }
+
+
+ handleAsyncClick=(e)=>{
+ const {AsyncRequestDispatch} = this.props;
+ e.preventDefault();
+ console.log("async click");
+ console.log(AsyncRequestDispatch);
+ AsyncRequestDispatch();//异步改变状态
+ }
+
+ render() {
+ const { count} = this.props;
+ console.log(count);
+ return(
+
+ Hello Counter{count.num}
+ Post数据:{count.data.post}
+
+
+
+ Index
+ Todo
+
+ );
+ }
+}
+
+export default Counter;
\ No newline at end of file
diff --git a/common/components/Indexpage.jsx b/common/components/Indexpage.jsx
new file mode 100644
index 0000000..f58ed99
--- /dev/null
+++ b/common/components/Indexpage.jsx
@@ -0,0 +1,25 @@
+import React,{Component} from 'react';
+import {Link} from 'react-router';
+
+
+class Indexpage extends Component {
+ constructor(props){
+ super(props);
+ }
+ componentDidMount () {
+ console.log("Indexpage did mount");
+ console.log(this.props);
+ }
+
+ render() {
+ return(
+
+ Hello Indexpage
+ Counter
+ Todo
+
+ );
+ }
+}
+
+export default Indexpage;
\ No newline at end of file
diff --git a/common/components/Layout.jsx b/common/components/Layout.jsx
new file mode 100644
index 0000000..5ffc496
--- /dev/null
+++ b/common/components/Layout.jsx
@@ -0,0 +1,22 @@
+import React,{Component} from 'react';
+
+class Layout extends Component {
+ constructor(props){
+ super(props);
+ }
+ componentDidMount() {
+ console.log("layout mount here");
+ console.log(this.props);
+ }
+
+ render() {
+ return(
+
+
Hello Layout
+ {this.props.children}
+
+ );
+ }
+}
+
+export default Layout;
\ No newline at end of file
diff --git a/common/components/Todo.jsx b/common/components/Todo.jsx
new file mode 100644
index 0000000..e5c6b3e
--- /dev/null
+++ b/common/components/Todo.jsx
@@ -0,0 +1,30 @@
+import React,{Component} from 'react';
+import {Link} from 'react-router';
+
+
+class Todo extends Component {
+ constructor(props){
+ super(props);
+ }
+
+ componentDidMount () {
+ console.log("Todo did mount");
+ console.log(this.props);
+
+ }
+
+ render() {
+ const { todo, onAddTodoClick } = this.props
+ console.log(todo);
+ console.log(onAddTodoClick);
+ return(
+
+ Hello Todo!
+ Index
+ Counter
+
+ );
+ }
+}
+
+export default Todo;
\ No newline at end of file
diff --git a/common/containers/Counterpage.jsx b/common/containers/Counterpage.jsx
new file mode 100644
index 0000000..20f8cb3
--- /dev/null
+++ b/common/containers/Counterpage.jsx
@@ -0,0 +1,33 @@
+import React from 'react';
+
+import {connect} from 'react-redux';
+import Counter from '../components/Counter.jsx';
+import {bindActionCreators} from 'redux';
+import {counterAction} from '../action/counteraction.js';//导入action分法函数
+import AsyncCounterAction from '../action/counteraction.js';
+//mapStateToProps
+const mapStateToProps = (state, ownProps) => {
+ return {
+ count: state.count
+ }
+}
+
+
+const mapDispatchToProps = (dispatch, ownProps) => {
+
+ return {
+ onIncreaseClick: () => {
+ console.log("onIncreaseClick here");
+ dispatch(counterAction())
+ },
+
+ AsyncRequestDispatch:()=>{
+ console.log("AsyncRequestDispatch here");
+ console.log(AsyncCounterAction());
+ dispatch(AsyncCounterAction());
+ }
+ }
+}
+
+
+export default connect(mapStateToProps,mapDispatchToProps)(Counter);
\ No newline at end of file
diff --git a/common/containers/Todopage.jsx b/common/containers/Todopage.jsx
new file mode 100644
index 0000000..fb4ec00
--- /dev/null
+++ b/common/containers/Todopage.jsx
@@ -0,0 +1,24 @@
+import {connect} from 'react-redux';
+import Todo from '../components/Todo.jsx';
+import {bindActionCreators} from 'redux';
+import todoAction from '../action/todoaction.js';
+
+
+//mapStateToProps
+const mapStateToProps = (state, ownProps) => {
+ return {
+ todo: state.todo
+ }
+}
+
+
+const mapDispatchToProps = (dispatch, ownProps) => {
+
+ return {
+ onAddTodoClick: (text) => {
+ dispatch(todoAction(text))
+ }
+ }
+}
+
+export default connect(mapStateToProps,mapDispatchToProps)(Todo);
\ No newline at end of file
diff --git a/common/reducers/counterReducer.js b/common/reducers/counterReducer.js
new file mode 100644
index 0000000..23c923c
--- /dev/null
+++ b/common/reducers/counterReducer.js
@@ -0,0 +1,30 @@
+import {ADD_COUNT,ASYNC_RECEIVE_ADD,ASYNC_REQUEST_ADD} from '../action/counteraction';
+
+
+let initialState={
+ num:0,
+ isFetching:false,
+ data:{}
+}
+
+const counterReducer=(state=initialState, action)=>{
+ switch(action.type) {
+ case ADD_COUNT:
+ return Object.assign({},state,{
+ num:state.num+1
+ });
+ case ASYNC_REQUEST_ADD://请求
+ return Object.assign({},state,{
+ isFetching:true
+ });
+ case ASYNC_RECEIVE_ADD://响应
+ return Object.assign({},state,{
+ data:action.data,
+ isFetching:false
+ });
+ default:
+ return state;
+ }
+}
+
+export default counterReducer;
\ No newline at end of file
diff --git a/common/reducers/index.js b/common/reducers/index.js
deleted file mode 100644
index e09ef96..0000000
--- a/common/reducers/index.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import userReducer from './user';
-import postsReducer from './posts';
-
-const initialState={};
-
-export default rootReducer=(state=initialState, action)=>{
- return {
- userReducer:userReducer(state.user, action),
- postsReducer:postsReducer(state.posts, action)
- }
-}
diff --git a/common/reducers/posts.js b/common/reducers/posts.js
deleted file mode 100644
index b1a6af6..0000000
--- a/common/reducers/posts.js
+++ /dev/null
@@ -1,44 +0,0 @@
-import
- {
- INVALIDATE_POSTS,
- REQUEST_UPDATE_POST_BY_ID,
- REQUEST_DEL_POST_BY_ID,
- REQUEST_POSTS,
- RECEIVE_POSTS,
- } from '../action/posts.js';
-
-
-
-const initialState = {
- isFetching:false,//文章是否在获取中
- didInvalidate:false,//是否无效
- items:[]
-};//初始状态文章为空
-
-export default postsReducer=(state = initialState, action)=>{
- switch(action.type) {
- case INVALIDATE_POSTS://当文章无效的时候
- return Object.assign({}, state, {
- didInvalidate:true
- });
-
- //请求类
- case REQUEST_UPDATE_POST_BY_ID://通过文章id更新文章数据
- case REQUEST_POSTS://请求所有的文章
- case REQUEST_DEL_POST_BY_ID://通过文章id删除文章数据
- return Object.assign({},state,{
- isFetching:true,
- didInvalidate:false,
- });
-
- case RECEIVE_POSTS://获取数据
- return Object.assign({},state,{
- isFetching:false,
- didInvalidate:false,
- items:action.posts
- });
-
- default:
- return state;
- }
-}
\ No newline at end of file
diff --git a/common/reducers/rootReducer.js b/common/reducers/rootReducer.js
new file mode 100644
index 0000000..3bce9de
--- /dev/null
+++ b/common/reducers/rootReducer.js
@@ -0,0 +1,18 @@
+import { combineReducers }from 'redux';
+import counterReducer from './counterReducer';
+import todoReducer from './todoReducer';
+
+
+// const rootReducer=(state={},action)=>{
+// return {
+// count:counterReducer(state.count, action),
+// todo: todoReducer(state.todo, action)
+// }
+// }
+const rootReducer =combineReducers({//这里的count和todo一定要和状态属性一致
+ count:counterReducer,
+ todo:todoReducer
+});
+
+
+export default rootReducer;
\ No newline at end of file
diff --git a/common/reducers/todoReducer.js b/common/reducers/todoReducer.js
new file mode 100644
index 0000000..73407a3
--- /dev/null
+++ b/common/reducers/todoReducer.js
@@ -0,0 +1,12 @@
+import {ADD_TODO} from '../action/todoaction';
+
+const todoReducer=(state=[],action)=>{
+ switch(action.type){
+ case ADD_TODO:
+ return state.push(action.todo);
+ default:
+ return state;
+ }
+}
+
+export default todoReducer;
\ No newline at end of file
diff --git a/common/reducers/user.js b/common/reducers/user.js
deleted file mode 100644
index e4f7d55..0000000
--- a/common/reducers/user.js
+++ /dev/null
@@ -1,38 +0,0 @@
-import {
- REQUEST_SIGNIN,
- REQUEST_SIGNINOUT,
- REQUEST_SIGNINUP,
- ERROR_USER,
- FINISH_SIGNIN,
- FINISH_SIGNOUT,
- FINISH_SIGNUP
-} from '../action/user';
-
-
-let initialState = {
- isRequesting:false,
- isLogin:false,
- userInfo:{}
-}
-
-export default userReducer=(state=initialState,action)=>{
- switch(action.type){
- case REQUEST_SIGNIN:
- case REQUEST_SIGNINOUT:
- case REQUEST_SIGNINUP:
- return Object.assign({},state,{
- isRequesting:true
- });
- case FINISH_SIGNUP://注册
- case FINISH_SIGNIN://登录
- return Object.assign({},state,{
- isLogin:true,
- userInfo:action.userInfo
- });
- case FINISH_SIGNOUT:
- return Object.assign({},state,{
- isLogin:false,
- userInfo:{}
- });
- }
-}
\ No newline at end of file
diff --git a/common/store/index.js b/common/store/index.js
new file mode 100644
index 0000000..a66ef55
--- /dev/null
+++ b/common/store/index.js
@@ -0,0 +1,11 @@
+import {createStore, applyMiddleware} from 'redux';
+import rootReducer from '../reducers/rootReducer';
+import thunk from 'redux-thunk';//应用一下中间件
+
+
+const configureStore=(initialState)=>{
+ const store =createStore(rootReducer,initialState,applyMiddleware(thunk));
+ return store;
+}
+
+export default configureStore;
\ No newline at end of file
diff --git a/common/store/store.js b/common/store/store.js
deleted file mode 100644
index 0a45953..0000000
--- a/common/store/store.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import { createStore,applyMiddleware} from 'react-redux';
-import thunkMiddleware from 'redux-thunk';
-import createLogger from 'redux-logger';
-import rootReducer from '../reducers';
-
-const loggerMiddleware = createLogger();
-
-export default configureStore=(preloadedState)=>{
- return createStore(
- rootReducer,
- preloadedState,
- applyMiddleware(
- thunkMiddleware,
- loggerMiddleware
- )
- );
-}
-
-
-
-
diff --git a/config/default.js b/config/default.js
index 825da67..5ee8510 100644
--- a/config/default.js
+++ b/config/default.js
@@ -2,7 +2,7 @@ module.exports = {
port: 3000,
session: {
secret: 'myblog',
- key: 'myblog',
+ key: 'blog',
maxAge: 2592000000
},
mongodb: 'mongodb://localhost:27017/myblog'
diff --git a/index.js b/index.js
index eea37b5..3f61fca 100644
--- a/index.js
+++ b/index.js
@@ -1,126 +1,76 @@
-var path = require('path');
-var express = require('express');
-var session = require('express-session');
-var MongoStore = require('connect-mongo')(session);
-var flash = require('connect-flash');
-var config = require('config-lite');
-var NodeRoutes = require('./server/noderoutes');
-var pkg = require('./package');
-var winston = require('winston');
-var expressWinston = require('express-winston');
-
+import config from 'config-lite';
+import express from 'express';
+import path from 'path';
+import pkg from './package.json';
+import ApiRoutes from './server/apiroutes';
//react服务端渲染配置
+import React from 'react';
import {renderToString} from 'react-dom/server';
-import {match, RoutingContext} from 'react-router';
+import {match, RouterContext} from 'react-router';
import AppRoutes from './common/AppRoutes';
import renderFullPage from './server/lib/viewpage';
+import configureStore from './common/store/index';
+import {Provider} from 'react-redux';
var app = express();
-// 设置模板目录
-app.set('views', path.join(__dirname, 'views'));
-// 设置模板引擎为 ejs
-app.set('view engine', 'ejs');
-
// 设置静态文件目录
-app.use(express.static(path.join(__dirname, 'public')));
-// session 中间件
-app.use(session({
- name: config.session.key,// 设置 cookie 中保存 session id 的字段名称
- secret: config.session.secret,// 通过设置 secret 来计算 hash 值并放在 cookie 中,使产生的 signedCookie 防篡改
- cookie: {
- maxAge: config.session.maxAge// 过期时间,过期后 cookie 中的 session id 自动删除
- },
- store: new MongoStore({// 将 session 存储到 mongodb
- url: config.mongodb// mongodb 地址
- })
-}));
-// flash 中间价,用来显示通知
-app.use(flash());
-// 处理表单及文件上传的中间件
-app.use(require('express-formidable')({
- uploadDir: path.join(__dirname, 'public/img'),// 上传文件目录
- keepExtensions: true// 保留后缀
-}));
-
-// 设置模板全局常量
-app.locals.blog = {
- title: pkg.name,
- description: pkg.description
-};
-
-// 添加模板必需的三个变量
-app.use(function (req, res, next) {
- res.locals.user = req.session.user;
- res.locals.success = req.flash('success').toString();
- res.locals.error = req.flash('error').toString();
- next();
-});
-
-// 正常请求的日志
-app.use(expressWinston.logger({
- transports: [
- new (winston.transports.Console)({
- json: true,
- colorize: true
- }),
- new winston.transports.File({
- filename: 'logs/success.log'
- })
- ]
-}));
-// 路由
-// routes(app);
-
+app.use(express.static(path.join(__dirname, 'server/public')));
+//RESTful api路由,必须置于前
+ApiRoutes(app);
+//处理react路由
+app.get("*",(req, res)=>{
-app.use((req, res)=>{
-
- match( {AppRoutes, location:req.url}, (err, redirectLocation, renderProps)=>{
-
- console.log(err);
- console.log(redirectLocation);
- console.log(renderProps);
-
+ match( {routes:AppRoutes, location:req.url}, (err, redirectLocation, renderProps)=>{
+
if(err) {
+
res.status(500).send(err.message);
+
}else if(redirectLocation) {
+
res.redirect(302, redirectLocation.pathname+redirectLocation.search);
+
}else if(renderProps) {
- // let marked = renderToString();
- // res.status(200).end(marked);
+ var initialState = {
+ count:{
+ num:1,
+ isFetching:false,
+ data:{
+ post:"hhhh"
+ }
+ },
+ todo:['haha']
+ };
+
+ const store = configureStore(initialState);
+
+ console.log(store.getState());
+ let marked = renderToString(
+
+
+
+ );
+
+ const initHtml= renderFullPage(marked,store.getState());
+
+ res.status(200).end(initHtml);
}else {
- // let notFoundPage = renderToString();
- // res.status(404).end(notFoundPage);
+ res.status(404).end('404 npt found');
}
});
});
-
-
-
-// 错误请求的日志
-app.use(expressWinston.errorLogger({
- transports: [
- new winston.transports.Console({
- json: true,
- colorize: true
- }),
- new winston.transports.File({
- filename: 'logs/error.log'
- })
- ]
-}));
-
// error page
-app.use(function (err, req, res, next) {
- res.render('error', {
- error: err
- });
-});
+// app.use(function (err, req, res, next) {
+// res.render('error', {
+// error: err
+// });
+// });
if (module.parent) {
module.exports = app;
diff --git a/package.json b/package.json
index 7747c29..6f98ede 100644
--- a/package.json
+++ b/package.json
@@ -4,7 +4,9 @@
"description": "a blog system",
"main": "index.js",
"scripts": {
- "test": "echo \"Error: no test specified\" && exit 1"
+ "test": "echo \"Error: no test specified\" && exit 1",
+ "start": "node_modules/.bin/babel-node index.js",
+ "build": "webpack -p"
},
"repository": {
"type": "git",
@@ -21,6 +23,7 @@
},
"homepage": "https://github.com/BetaMee/ReactBlog#readme",
"dependencies": {
+ "axios": "^0.15.3",
"config-lite": "^1.5.0",
"connect-flash": "^0.1.1",
"connect-mongo": "^1.3.2",
@@ -41,5 +44,16 @@
"redux-thunk": "^2.2.0",
"sha1": "^1.1.1",
"winston": "^2.3.1"
+ },
+ "devDependencies": {
+ "babel-cli": "^6.23.0",
+ "babel-core": "^6.23.1",
+ "babel-loader": "^6.3.2",
+ "babel-preset-es2015": "^6.22.0",
+ "babel-preset-react": "^6.23.0",
+ "babel-preset-stage-1": "^6.22.0",
+ "react-hot-loader": "^1.3.1",
+ "webpack": "^2.2.1",
+ "webpack-dev-server": "^2.4.0"
}
}
diff --git a/server/apiroutes/index.js b/server/apiroutes/index.js
new file mode 100644
index 0000000..c451058
--- /dev/null
+++ b/server/apiroutes/index.js
@@ -0,0 +1,6 @@
+module.exports = function (app) {
+ app.use('/api/signup', require('./signup'));
+ app.use('/api/signin', require('./signin'));
+ app.use('/api/signout', require('./signout'));
+ app.use('/api/posts', require('./posts'));
+};
diff --git a/server/noderoutes/posts.js b/server/apiroutes/posts.js
similarity index 94%
rename from server/noderoutes/posts.js
rename to server/apiroutes/posts.js
index bc6ae5e..079f815 100644
--- a/server/noderoutes/posts.js
+++ b/server/apiroutes/posts.js
@@ -8,15 +8,19 @@ var checkLogin = require('../middlewares/check').checkLogin;
// GET /posts 所有用户或者特定用户的文章页
// eg: GET /posts?author=xxx
router.get('/', function(req, res, next) {
- var author = req.query.author;
+ // var author = req.query.author;
+
+ // PostModel.getPosts(author)
+ // .then(function (posts) {
+ // res.render('posts', {
+ // posts: posts
+ // });
+ // })
+ // .catch(next);
+ res.json({
+ post:"hello redux"
+ });
- PostModel.getPosts(author)
- .then(function (posts) {
- res.render('posts', {
- posts: posts
- });
- })
- .catch(next);
});
// GET /posts/create 发表文章页
diff --git a/server/noderoutes/signin.js b/server/apiroutes/signin.js
similarity index 100%
rename from server/noderoutes/signin.js
rename to server/apiroutes/signin.js
diff --git a/server/noderoutes/signout.js b/server/apiroutes/signout.js
similarity index 100%
rename from server/noderoutes/signout.js
rename to server/apiroutes/signout.js
diff --git a/server/noderoutes/signup.js b/server/apiroutes/signup.js
similarity index 100%
rename from server/noderoutes/signup.js
rename to server/apiroutes/signup.js
diff --git a/server/lib/viewpage.js b/server/lib/viewpage.js
index d1c810f..db38c30 100644
--- a/server/lib/viewpage.js
+++ b/server/lib/viewpage.js
@@ -12,9 +12,9 @@ function renderFullPage(html, initiaState) {
-
+