Giter VIP home page Giter VIP logo

koa-cola's Introduction

koa-cola

Build Status Coverage Status npm

中文版readme

koa-cola is SSR(server side render) and SPA(single page application) integrated solution framework using koa/react/react-router/redux/typescript, and "isomorphic" codes in many modules(component/router/redux/validation used in both browser and server side).

Features

  • Built in SSR and SPA integrated solution
  • Writing "Isomorphic" component/router/redux/ajax/validation codes run in both client and server side
  • Typescript and ES7 decorator coding style

Usage

koa-cola requires node v12.

  • npm i koa-cola -g install global koa-cola cli.
  • koa-cola new koa-cola-app create new koa-cola project in current folder.
  • cd koa-cola-app
  • npm run dev start dev mode to build bundle and launch server.

Here is Cola decorator example to demonstrate what does it look like writing "Isomorphic" codes in Koa-cola:

import * as React from "react";
import { Cola, store } from "koa-cola/client";
import { GetFooApi } from "../../api";
var loadSuccess = store.loadSuccess;
// Api can be called either in browser or node.js, in server side, ctx parameter exists.
async function callApi(ctx?) {
  var getFooApi = new GetFooApi({});
  await getFooApi.fetch(ctx);
  var result: any = getFooApi.result;
  return `api called from ${ctx ? "server" : "client"}, data:${result.data}`;
}
// Use Cola decorator to "isomorphic" redux data flow
@Cola({
  // In SSR mode:
  // return some props in initData in server side and as the init state in client side redux
  // in client side, ssr component html "rendered" with the init state, so this looks like redux state flows from server side to client side
  
  // In SPA mode:
  // when visit the component without refreshing page like click react-router <link>, props in initData is run only in client side
  // So redux state only flows in client side
  initData: {
    hello: () => {
      return Promise.resolve("Wow koa-cola!");
    },
    // this callApi called is in server side in SSR mode
    // or in client side in SPA mode
    apiDataCallFromServer: async ({ params, helpers }) => {
      return await callApi(helpers.ctx);
    }
  },
  // react-redux "mapDispatchToProps"
  mapDispatchToProps: dispatch => {
    return {
      // update hello props 
      onClick: () => {
        dispatch(loadSuccess("hello", "Wow koa-cola and bundle work!"));
      },
      // this callApi called is in browser side
      callApiFromClient: async () => {
        var data = await callApi();
        dispatch({
          type: "CALL_API",
          data
        });
      },
      // use redux-thunk middlewares, defined in /config/reduxMiddlewares.js
      reduxThunk: () => {
        return dispatch(async () => {
          await new Promise((resolve, reject) => setTimeout(resolve, 1000));
          dispatch({
            type: "REDUX_THUNK",
            data: "this is from reduxMiddleware"
          });
        });
      }
    };
  },
  // react-redux "mapStateToProps" can be used as the props selector
  mapStateToProps: state => {
    return state;
  },
  // reducer of redux
  reducer: {
    apiDataCallFromClient: (state = "", action) => {
      switch (action.type) {
        case "CALL_API":
          return action.data;
        default:
          return state;
      }
    },
    dataFromReduxThunk: (state = "", action) => {
      switch (action.type) {
        case "REDUX_THUNK":
          return action.data;
        default:
          return state;
      }
    }
  }
})
export default class App extends React.Component {
  render() {
    return (
      <div>
        <h1>{this.props.hello}</h1>
        <button onClick={this.props.onClick}>check bundle if work</button>&nbsp;
        <button onClick={this.props.callApiFromClient}>call from client</button>&nbsp;
        <button onClick={this.props.reduxThunk}>redux thunk</button>&nbsp;
        <div>
          redux data flow in server side : {this.props.apiDataCallFromServer} <br />
          redux data flow in client side : {this.props.apiDataCallFromClient} <br />
          redux middleware : {this.props.dataFromReduxThunk} <br />
        </div>
      </div>
    );
  }
}

Try TODO-LIST demo in local:

  • git clone https://github.com/koa-cola/todolist
  • cd todolist
  • npm i
  • npm run local

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.