React server-side with ES6 syntax

February 26th, 2015 | es6, javascript, nodejs, react |

ES6 aka ES.next aka Harmony is already there

Even if it’s not fully standardized (last draft) and should get out mid-2015, ES6 is already there. We can already find several transpilers (a compiler that translates a language to another one) that translate ES6 to ES5 for our browsers or Node to run normally with the old known syntax.

Soon, it will be even useless to transpile with Node because ES6 is already on its way. For instance, Node has already implemented those features :

--harmony_scoping (enable harmony block scoping)
--harmony_modules (enable harmony modules (implies block scoping))
--harmony_proxies (enable harmony proxies)
--harmony_generators (enable harmony generators)
--harmony_numeric_literals (enable harmony numeric literals (0o77, 0b11))
--harmony_strings (enable harmony string)
--harmony_arrays (enable harmony arrays)
--harmony_arrow_functions (enable harmony arrow functions)
--harmony (enable all harmony features (except proxies))

And when using react-tools with the jsx tool (and reactify), you can have access too to some ES6 features.

For instance, with Browserify and Reactify :

browserify('app.jsx').transform({ es6: true }, reactify)

 
If you are not aware of all the new features, or just want to have a look again, check this page that resume clearly with examples what is available in ES6.

Babel FTW

But the best transpiler, the one that implements most of the features is Babel (formerly es5to6, they changed their name because they planned to go further than ES6 certainly, ES7 already being on its way !).

You can take a look at the compatibility table from kangax (awesome job!) to see what are the supported features for all of them : Traceur from Google, Babel, es6-transpiler, jsx.

On the 25/02/2015, Babel is already 78% compatible with the ES6 syntax. That’s pretty neat. Jsx being far at 16% ({harmony: true}), Node at 25% (--harmony).

Let’s not forget about the client side, Chrome being around 50% and Firefox 65%.

Before talking about React with ES6 in Node, I’m going to quickly present the most important and confortable features I think to not revamp our code later (with React at least). You can skip this part if you already know what features ES6 provide.

object literals

var name = "henry";
var phone = "+333456789"
var person = { name, phone };

Just sugar to avoid retyping the variable name and to be consistent.

templates

var what = "awesome";
console.log(`it's so ${what}`);

You just use backquotes and you have a basic template engine where you can evaluate any javascript inside.
No more unreadable “my name is ” + name + ” and I’m ” + yearOld + ” year” + (yearOld > 1 ? “s” : “”) + ” old”.

arrow functions

arr.map(item => item.value)

this being automatically passed to the function, no more need of ugly var self = this;

For instance:

class Math {
multiplyBy(i) { return 2*i; }
compute() { return [1, 2, 3].map(value => { return this.multiplyBy(value); }); }
}

class

class TopBarComponent extends React.Component {
  constructor() {
    super(props); // can be useful sometimes!
    this.state = { value: props.initialValue };
  }
  ...

Finally, a class keyword with its extends. No more prototype to play with and other module pattern, no more React.createClass, no more getInitialState(), you have a true constructor, let’s make some nice OO. No multiple inheritance through. Notice that the React props are now available in the constructor arguments.

short functions notations in classes

render() { return 
No function keyword
; }

And no comma between the functions or that’s not valid.

destructuring

(function({ name, age }) { // auto-associate the args
  console.log(`hi ${name} ${age}`);
})({ age: 12, name: 'henry', phone: '+333456789' });
// auto-associate the function result into the left member
var { name } = (() => { return { name: "toto", age: 30 } })();
console.log(name);

This is super useful and avoid to create manually bunch of variables.

module

import React from 'react';

basically that replaces var React = require('react');
you could also import several items at the same time using the destructuring :

import { React, cx } from 'react';

But it doesn’t work for now in Babel at least.
Those were the most useful features to know, and to run some React in Node.

Check out the others features, such as the promises, the generators, the spread parameters, the default arguments, let, const, symbol, iterators, and the new data structures (Map Set WeakMap, WeakSet), new functions on String, Math, Number…! So much to talk about. You can check out the Babel website to know what it’s all about.

React ES6 style

Let’s focus on React server-side now, using Node. We are going to use Babel to have the latest available features, and because it’s pretty straightforward to make it work.

– Install Babel globally, to have access to the babel executables npm install -g babel.

– Install react. You must have at least react>=0.13 otherwise Babel is going to fail with this error :

TypeError: Super expression must either be null or a function, not undefined

If the 0.13 is not yet available (it’s not yet at this time), force the installation using : npm install

Babel has an executable babel-node, that starts node with all its es6 features: babel-node app.jsx

Here is a program sample full ES6 style that just renders as a string (we are server side!) a component in another file:

App.jsx

import React from 'react';
import MyComponent from './MyComponent.jsx';

console.log(React.renderToString());

MyComponent.jsx

import React from 'react';

export class MyComponent extends React.Component {
  constructor(props) {
    this.state = { value: props.initialValue };
  }
  render() {
    var items = [ 1, , 3 ].map(x => {x * this.state.value});
    return 
{items}
; } }

You will have this result as expected:

3 9

We are already using the class, module, destructuring and arrow features in this tiny example.

So, this is the base template if you want to start playing with React in Node being full ES6 compliant. It took some time for me to find this result. I tested a lot of things, other frameworks and techniques to get my full ES6 working, and I found this one with Babel simple enough. So, it’s time to refactor our stuff now and combine this with some client side !

 

Check out the React post about this version 0.13 for more details: http://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html

 

What does it look like in ES5 ?

Instead of using babel-node, you can use the executable babel to get the transpiled output. It’s pretty interesting to see how Babel translates ES6 to ES5.

For instance, our previous sample, if you do babel app.jsx, that gives us :

"use strict";

var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
var React = _interopRequire(require("react"));
var MyComponent = _interopRequire(require("./MyComponent.jsx"));

console.log(React.renderToString(React.createElement(MyComponent, { initialValue: "3" })));

The import feature is automatically replaced by an _interopRequire + require function. If we babel MyComponent.jsx, that’s WAY more verbose :

"use strict";

var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
var _prototypeProperties = function (child, staticProps, instanceProps) { if (staticProps) Object.defineProperties(child, staticProps); if (instanceProps) Object.defineProperties(child.prototype, instanceProps); };
var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
var React = _interopRequire(require("react"));

var MyComponent = (function (_React$Component) {
        function MyComponent(props) {
                _classCallCheck(this, MyComponent);

                this.state = { value: props.initialValue };
        }

        _inherits(MyComponent, _React$Component);

        _prototypeProperties(MyComponent, null, {
                render: {
                        value: function render() {
                                var _this = this;

                                var items = [1,, 3].map(function (x) {
                                        return React.createElement(
                                                "span",
                                                { key: x },
                                                x * _this.state.value
                                        );
                                });
                                return React.createElement(
                                        "div",
                                        null,
                                        items
                                );
                        },
                        writable: true,
                        configurable: true
                }
        });

        return MyComponent;
})(React.Component);

module.exports = MyComponent;

We can see a bit how it’s translated :

– Class, superclass, and inheritance.
– Everything being a true ES5 object property value/writable/configurable using Object.defineProperties
– module.exports = MyComponent

 

You may have noticed the default keyword when we defined our React component:
export default class MyComponent {

If we omit it, the end of the generated file will be :

Object.defineProperty(exports, "__esModule", {
  value: true
});

instead of module.exports = MyComponent;

But we want this CommonJS syntax to work with Node, so we need this default keyword. If you don’t use it, you will get this error :

Warning: React.createElement: type should not be null or undefined. It should be a string (for DOM elements) or a ReactClass (for composite components).
Warning: Only functions or strings can be mounted as React components.

C:\test\node_modules\react\lib\ReactDefaultInjection.js:53
    tagName: type.toUpperCase(),
                 ^
TypeError: Cannot read property 'toUpperCase' of undefined

ES6 is not enough, we want ES7 !

It’s just getting started but Traceur, Babel and Firefox are already full steam ahead !
Check the kangax table : http://kangax.github.io/compat-table/es7/

You can use babel-node with the experimental flag : babel-node --experimental app.jsx to give a try to the already implemented ES7 features of Babel if you want.

Gulp is fond of Node streams

February 15th, 2015 | browserify, gulp, javascript, nodejs |

If you’re not familiar enough with browserify options and features, check out my previous post explaining browserify in-depth.

I love streaming

Gulp is a stream-based project builder. Basically: a bunch of modules that take one input and output something, which is taken by another module etc. until the whole process is done.

First thing to do, create our gulpfile.js at the root of our project and require() what we need: gulp and browserify.
Once, there was a gulp-browserify plugin. It’s still downloadable but it is not maintained anymore so don’t use it. You have to use browserify itself, that’s it.

var browserify = require('browserify');
var gulp = require('gulp');

gulp.task('default', function() {
    console.log('todo');
});
> gulp
[14:16:44] Starting 'default'...
todo
[14:16:44] Finished 'default' after 85 µs

Before throwing lines of code and browserify, let’s explain a bit more how this stream management work with some examples.

 
Continue reading Gulp is fond of Node streams

Browserify in-depth

February 14th, 2015 | browserify, gulp, highcharts, javascript |

I was seeing this name Browserify everywhere but I always found difficult to understand how Browserify work when I was reading blogs or others articles. It was never clear or it was using things I don’t wanted (I wanted to use gulp for instance to build my project, no grunt, no bower, and I knew gulp-browserify was blacklisted). I decided to step into and learn from the beginning what is browserify, and how it works.

You just need to know at least Node and npm to read further.

So, what I only knew at the beginning was that Browserify is used to create a bundle of js files (on which you can apply transforms such as uglify to minify and reactify to convert React .jsx files), and the html just need to reference one file and then you don’t care anymore of what component to include in the page, how to handle dependencies (A needs B, B should be included before A, this kind of stuff).

That what is, all I knew. Now, let’s start from scratch and let’s discover what’s inside.

We will start by using the browserify command line to check how that’s work and we’ll finish with examples having html and differents third party libs such as Highcharts.

Continue reading Browserify in-depth

February 12th, 2015 | javascript, react |

If you are not yet confortable with the notion of ownership and parent/child in React, take a look at my previous post.

How to communicate between React components ? That’s a good question, and there are multiple answers. That depends of the relationship between the components, and then, that depends on what you prefer.

I am not talking about data-stores, data-adapters or this kind of data-helpers that gets data from somewhere that you need to dispatch to your components, I’m really just talking about communication between React components only.

 

There are 3 possible relationships:

Ownership and children in ReactJS

February 10th, 2015 | javascript, react |

Let’s explore how does the ownership work in React, and what is exactly a child in React’s world by looking at the special property : this.props.children.

Luke, I’m your.. owner?

When you do:

var MyContainer = React.createClass({
    render: function() {
        return 
    }
});

is the owner of , and is the ownee.

We don’t talk about parent/child, this is used to talk about the DOM only.

In this example:

var MyContainer = React.createClass({
    render: function() {
        return 
} });

is not the parent of , it’s only its owner.

Continue reading Ownership and children in ReactJS

A journey through the creation of an app with Node, MongoDB, React, Gulp

February 9th, 2015 | expressjs, gulp, javascript, mongodb, nodejs, react |

So, being so interested in React, I wanted to create something, something useful, not just a single page with a Hello World in the middle, no, that does tell you how to really use a framework, what are its pros and cons.

To really evaluate it, you need at least to have a design of some application, with some links here and there (routing), some dynamic rendering (events), some webservice calls (server, async), a database, and a process to build the project (because you don’t want to manually add a reference in the .html everytime you add a .js file for instance, this is especially true when you deal with React components, every component should have its own file). Then it should have some testing.

So, my only constraint was : use React. After watching so many videos and read many things, I needed to write that down and see how I’m doing.
From that, I needed to store some data on a server that would connect to a DB. So for the server, I picked NodeJS. I barely used it, just for some tutorials I think. But nevermind, I’ll learn. Now a database, at first, I decided on NeDB, because I didn’t want to install a true database server at the beginning. But, I was going to have some many rows later (>300k) that I had to switch to a more powerful one. I through of MongoDB. Never used it, but I knew it integrates easily with NodeJS (using Mongoose) and NeDB has the same exact syntax so no code changes! I only used relational databases until now, so it was going to be a good learning curve ! Finally, as a build system, I used Grunt a bit back then, but I heard about Gulp being much nicer. Go for it. (I’ve added it at the end actually :-))
And of course, I did of all my coding in my new favorite editor, Atom!

I’m going to explain step by step how I did from scratch, what I’ve learned and give some tips and pointers.

Continue reading A journey through the creation of an app with Node, MongoDB, React, Gulp

How do you React ?

February 5th, 2015 | framework, javascript, react |

The React Team has held a 2-days conference few days ago, on the January 28 & 29, to share the current state of art of their library. Here is its schedule http://conf.reactjs.com/schedule.html
I barely heard about React name before that. Then I looked at all the conference videos, because the more I watched, the more I was getting interested in. And it’s just amazing.

React is not a yet another Javascript framework, definitely not.

Continue reading How do you React ?