All Projects → tomastrajan → React Typescript Webpack

tomastrajan / React Typescript Webpack

Licence: mit
Seed for building React app using Typescript and Webpack build using FLUXless architecture

Programming Languages

typescript
32286 projects

Projects that are alternatives of or similar to React Typescript Webpack

React Starter Kit
React Starter Kit — front-end starter kit using React, Relay, GraphQL, and JAM stack architecture
Stars: ✭ 21,060 (+17747.46%)
Mutual labels:  webpack, flux
Bedrock
Build a Node web app with user authentication, security, and more in under 10 minutes. Now supports React Hot Loading for super-fast development. 👌
Stars: ✭ 187 (+58.47%)
Mutual labels:  webpack, flux
Typescript Webpack React Redux Boilerplate
React and Redux with TypeScript
Stars: ✭ 182 (+54.24%)
Mutual labels:  webpack, flux
Starter React Flux
Generate your React PWA project with TypeScript or JavaScript
Stars: ✭ 65 (-44.92%)
Mutual labels:  webpack, flux
Ostap
CLI tool that fast checks if your bundle contains multiple versions of the same package, only by looking in package.json.
Stars: ✭ 117 (-0.85%)
Mutual labels:  webpack
Meteor Webpack
https://medium.com/@ardatan/meteor-with-webpack-in-2018-faster-compilation-better-source-handling-benefit-from-bc5ccc5735ef
Stars: ✭ 116 (-1.69%)
Mutual labels:  webpack
Webpack Target Electron Renderer
webpack target function for electron renderer
Stars: ✭ 115 (-2.54%)
Mutual labels:  webpack
Raw.macro
Read file contents at build time via babel-plugin-macros. webpack-less raw-loader
Stars: ✭ 115 (-2.54%)
Mutual labels:  webpack
Style Loader
Style Loader
Stars: ✭ 1,572 (+1232.2%)
Mutual labels:  webpack
Awesome Bundle Size
📝 An awesome list of tools and techniques to make your web bundle size smaller and your web apps load faster.
Stars: ✭ 118 (+0%)
Mutual labels:  webpack
Razzle
✨ Create server-rendered universal JavaScript applications with no configuration
Stars: ✭ 10,547 (+8838.14%)
Mutual labels:  webpack
Simple Boilerplate
A simple webpack boilerplate for your comfortable work with HTML, JS and CSS.
Stars: ✭ 116 (-1.69%)
Mutual labels:  webpack
Razzle Material Ui Styled Example
Razzle Material-UI example with Styled Components using Express with compression
Stars: ✭ 117 (-0.85%)
Mutual labels:  webpack
Webapp
[Experimental, WIP] A base for building modern, performant, huge web apps.
Stars: ✭ 115 (-2.54%)
Mutual labels:  webpack
Webpacktemplate
webpack多页面脚手架
Stars: ✭ 118 (+0%)
Mutual labels:  webpack
React Redux Auth0 Kit
Minimal starter boilerplate project with CRA, React, Redux, React Router and Auth0 authentication
Stars: ✭ 115 (-2.54%)
Mutual labels:  webpack
Habr App
React tutorial for Habrahabr
Stars: ✭ 116 (-1.69%)
Mutual labels:  webpack
Static Site Boilerplate
A better workflow for building modern static websites.
Stars: ✭ 1,633 (+1283.9%)
Mutual labels:  webpack
Reeakt
A modern React boilerplate to awesome web applications
Stars: ✭ 116 (-1.69%)
Mutual labels:  webpack
Webpack Hot Client
webpack HMR Client
Stars: ✭ 116 (-1.69%)
Mutual labels:  webpack

React Typescript Webpack FLUXless Todo Example Build Status

Seed for building React apps using FLUXless architecture, Typescript and Webpack build

Check out the Demo

Features

This is a simple Todos application with some sweet extra features like authentication (using Auth0) and persistence (separate node.js backend application - check out the gihub repository of todos-server)

  • FLUXless architecture - simple one way data flow (just components, services, models)
  • guest mode - local storage persistence
  • persistence - separate node.js backend application for authenticated users
  • authentication - Auth0 3rd party API with Google+ social login
  • material design - material-ui, react-bootstrap, material bootswatch theme
  • continuous deployment - travis ci build + deployment to gh-pages branch fo the repository (GitHub Pages)
  • webpack build - with react hot loader

How to run the project

  1. npm i - install npm dependencies
  2. npm start - run webpack build in DEV mode, open http://localhost:8081 in browser

Other build targets

  • npm run build - run build and store artifacts in build folder
  • npm run dist - run production build and stores artifacts in dist folder
  • npm run ci - build for Travis CI
  • npm run test - run lint & test

Preview

Components

Disclaimer: I think Flux architecture and it's multiple implementations are great idea but it is always good to understand the bigger picture and related trade-offs...

Motivation for FLUXless architecture

In software development, we should strive to attain deeper understanding of concepts instead of falling for the ever-changing HypeOfTheMonthYear. I was interested and a bit skeptical about the latest Flux hype and all the different libraries it spawned during relatively short period of time. Researching the topic brought fruit pretty quickly. In my opinion, this thread on reddit contains lot of insight into the situation.

TLDR; MVC done incorrectly doesn't scale so we replaced it with MVC done correctly and gave it a cooler name.

or

As far as I can tell (and as others have said) - FB seems to have missed the boat here. Their FLUX diagram is what I understood proper MVC to be...

These and many other similar comments are hinting that Flux may be just a specific implementation of MVC and that the main point (or constraint) is that the data must ALWAYS flow in one direction. Flux implementations usually achieve that by decoupling of all logic calls (in Actions) by event bus (Dispatcher) from their execution (in Stores). As it turned out, one way data flow is also easily achievable by using more familiar architecture with React components, services and models (check todo.container.ts, todo.service.ts, todo.model.ts to get an idea).

Architecture

The main concept at the core of all Flux implementations is that the data must always flow in one direction. This is a worthy cause and it brings a lot of benefits to the table during development and maintenance of projects. With such an architecture project state becomes predictable, easier to reason about and debug.

Event bus vs explicit calls

Flux decouples logic by implementing event bus with the Dispatcher being responsible for dispatching Action generated events to all the Stores. As everything, events too come with a trade-off. They enforce decoupling of application logic by their very nature. The cost of that is that it is usually much harder to track and debug event-heavy code. Yes you can store complete event history to see what happened in your application but you lose ability to easily comprehend scope of all the logic that will be executed as a result of producing single event. Another problem is assuring that the dependent operations happen in correct order (waitsFor from original Facebook's Flux example'). It might be matter of subjective preference but if you need to orchestrate complex business flows through various domains, nothing beats explicit calls.

Architecture

UI

React components

In this example we are using two types of React components with different set of responsibilities.

Container components

Container components are handling following tasks:

  • hold current (rendered) application state
  • register model change listeners to get notified on model data change
  • retrieve actual data on model change
  • pass state to children components through their props
  • implement calls to domain & application services (and pass them to children)

Template of container components consist purely of other React components (no own layout or functionality).

export default class TodoContainer extends React.Component<{}, {}> {

    constructor(props) {
        super(props);
        this.state = this._buildState();
    }

    // register model data change listeners
    componentDidMount() { TodoModel.observable.addListener(this._onModelUpdate.bind(this)); }
    componentWillUnmount() { TodoModel.observable.removeListener(this._onModelUpdate.bind(this)); }

    // handle model data change
    _onModelUpdate() {
        this.setState(this._buildState());
    }

    // helper function for retrieving state on model data change
    _buildState() {
        return {
            todos: TodoModel.getTodos()
        }
    }

    addTodo(description: string) { /* ... */ }

    // simplified for brevity

    render() {
        return(
            <TodoComponent todos={this.state.todos} addTodo={this.addTodo.bind(this)} />
        );
    }

}

Simple components

Simple components receive all their data and functionality through props (from parent component). They can implement their own local state and logic for handling of internal UI interactions but all mutations to the application state stored in models can only be achieved by executing functions received from parent through props (which are in turn calling domain and application services).

Logic

Domain separation

As applications grow larger it is usually a good idea to split functionality into multiple folders (packages) by their respective concern. In the perfect world these concerns would be perfectly orthogonal so we didn't have to implement any cross domain orchestration or cross-cutting concerns. Unfortunately, that's rarely the case and we usually have to deal with cross-domain coordination when implementing our business flows.

Application services

Application services (~Actions) are used to implement cross-domain orchestration. They are the only type of service which are allowed to import services from other domain packages. They only execute functionality of imported domain services and contain no business logic on their own.

(Domain) Services

Services (~Actions / Stores) are used to implement domain specific business and infrastructure logic. Services of particular domain can import only other services belonging to that domain. All inter-domain orchestration must be implemented using application services. Logic can be separated into multiple services based on concern (eg: business logic, persistence, ...).

Models

Models (~Stores) are responsible for holding app state during it's runtime. They implement observe/notify design pattern so that all interested container components can use model's addListener method to register callback to be notified when the model data change. This implementation enables one way data flow. Model has full control of the (possibly custom) notification behaviour, while component knows what kind of data it needs to retrieve from model after being notified.

All get data functions of the model create copy of the retrieved data so that they prevent direct mutation of model's data through shared reference. Also, while it is theoretically possible for component to directly call other model's methods, as guideline only listener and get methods are allowed.

Contributing

Don't hesitate to fork / submit PR with enhancements if you found this example useful.

TODO

  • [x] tslint
  • [ ] unit tests
  • [ ] integration tests
  • [ ] add notifications / alerts for operation's outcomes
  • [ ] cleanup of styling (select just one component library)
  • [ ] add form validation messages
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].