Coder Social home page Coder Social logo

livereactload's Introduction

LiveReactload

Live code editing with Browserify and React.

Motivation

There are many live reloading components for CSS (and its variants) but unfortunately JavaScript didn't have such tools yet. After I played a little bit with React, I realised that its architecture and programming principles are a perfect match that could solve the puzzle.

I did some Googling and managed to find one similar implementation for the Webpack. However, I'm a very satisfied Browserify user so I wanted one for it too. The results of this work can be found in this repository and npm.

What is LiveReactload

LiveReactload is a Browserify implementation similar to LiveReload but for JavaScript instead. Ok, LiveReload actually supports JavaScript reloading but it reloads the whole page when the changes occur. If you have done something with the page, then the state is lost and you have to do the same operations again.

LiveReactload solves the state propagation problem over JavaScript reloads. It provides the following features:

  • Automatic state propagation management for React components as a Browserify transform
  • Notification infrastructure for change event delegation
  • Automatic change event listening and bundle reloading (when the Browserify transform is enabled)
  • Custom state propagation by using LiveReactload API
  • Integration interfaces for build systems

And because one photo tells more than a thousand words, see the following video to see LiveReactload in action:

Video

Usage

Install LiveReactload as development dependency

npm install --save-dev livereactload

LiveReactload package is a standard Browserify transform so it can be used like any other transformation (e.g. reactify, uglifyify, ...).

However, just adding the transformation is not enough. It will give your codebase a capability to reload itself but the codebase itself does not know about code changes. That's why LiveReactload must be integrated to your watch system (e.g. watchify). LiveReactload provides the following commands to do it:

# starts a server tht listens for change events and delegates them to the browser
node_modules/.bin/livereactload listen

# sends a change event notification to the listening server
node_modules/.bin/livereactload notify

Here is an example bin/watch script that you can use (presuming that browserify and watchify have been installed locally) to watch your bundle changes:

#!/bin/bash

{ { node_modules/.bin/watchify site.js -v -t babelify -t livereactload -o static/bundle.js 1>&2; } 2>&1 \
  | while read result; do
    echo "$result"
    [[ "$result" =~ ^[0-9]+[[:space:]]bytes[[:space:]]written  ]] && node_modules/.bin/livereactload notify
  done
} &

node_modules/.bin/livereactload listen
wait

And finally just start watch and begin coding:

./bin/watch

For build system integrations, please see this example

How it works

The React programming model suits perfectly live code editing: components are just stupid ones that render the data they are told to render and the DOM changes are handled with VirtualDOM diff. This (hopefully) prevents developers from hiding the state inside the application.

If the state is managed by React components and those components are exported via module.exports, it is possible to weave those components with a logic that enables state propagation: when the bundle is reloaded, the new implementation replaces the old prototypes but not the actual state.

More detailed explanation about the idea coming later...

So basically if you code your React application using its best practices, then you can use this reloading component without any modifications to your code!.

When does it not work?

Well... if you hide your state inside the modules then the reloading will lose the state. For example the following code will not work:

// counter.js
var React = require('react')

var totalClicks = 0

module.exports = React.createClass({

  getInitialState: function() {
    return {clickCount: totalClicks}
  },

  handleClick: function() {
    totalClicks += 1
    this.setState({clickCount: totalClicks})
  },


  render: function() {
    return (
      <div>
        <button onClick={this.handleClick}>Increment</button>
        <div>{this.state.clickCount}</div>
      </div>
    )
  }
})

A second problem arises when you have "private" components inside your modules that are not exported with module.exports.

However, both of those challenges can be solved by using LiveReactload API. Please see the examples to see how to use the API in different situations.

License

MIT

Problems?

Please create a Github issue if something occurs

Remember also Gitter chat:

Gitter

Thanks

  • Dan Abramov - an amazing React Hot API that was used for the basis of the state propagation mechanism
  • Hannu - inspiring and sparring with this project

livereactload's People

Contributors

milankinen avatar tkurki avatar

Watchers

 avatar  avatar

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.