An introduction to modern JavaScript: ES6, modules...

# Part 1: ES6 syntax

ES6 is the next version of JavaScript!

* 2009: ES5
* 2015: ES6
* 2016: ES7

With Babel transformer, we can use ES6 **now**!
Babel is included in react-rails gem.

### Links

* [ES6 overview](https://github.com/lukehoban/es6features)
* [ES5 VS. ES6 syntax comparison](http://es6-features.org)
* [Airbnb JavaScript ES6 style guide](https://github.com/airbnb/javascript)
* [Babel transformer](https://babeljs.io/) 

### The arrow symbol `=>`

Useful in .jsx loops with `.map()` function and event handlers.
Benefits:

* compact! no `function` , no `{}`, no `return`
* No problem scope with `this` keyword

#### JSX Example 1: create table rows

BEFORE

```html



          <tbody>
            { entries.map( function (entry, i) {
              return(<RestoreLogList.Entry
                entry={ entry }
                key={ i }
              />);
            }
            ) }
          </tbody>
```

AFTER

```html


          <tbody>
            { entries.map( (entry, i) =>
              <RestoreLogList.Entry
                entry={ entry }
                key={ i }
              />
            ) }
          </tbody>
```

JSX Example 2: create a button toolbar

BEFORE

```js

var self = this;
```

```html


<div className="btn-group">
  { this.props.options.map(
    function (item, i) {
      return (<button
        key={ i }
        type="button"
        className={ 'btn' + (self.props.value == item ? ' active' : '')  }
        onClick={ function () { self.props.onChange(item); } }
      >
        { item }
      </button>);
    }
  )}
</div>

```

AFTER

```html


<div className="btn-group">
  { this.props.options.map( (item, i) =>
      <button
        key={ i }
        type="button"
        className={ 'btn' + (this.props.value == item ? ' active' : '')  }
        onClick={ () => this.props.onChange(item) }
      >
        { item }
      </button>
  ) }
</div>
```

### Destructuring

BEFORE

```js

var x = data.x;
var y = data.y;
var z = data.z;

```

AFTER

```js

let {x, y, z} = data;
```

### Other nice features

* `class`
* `let` and `const`
* default parameter value
* ...

### Coming soon: ES7 (ES2016) !

An example of feature: [decorators] (https://medium.com/google-developers/exploring-es7-decorators-76ecb65fb841)


# Part 2: use JavaScript modules ?

## 1. Old JavaScript (everything is global)

```js:my-component.jsx

//React is in the global namespace.

var MyComponent = React.createClass({

  handleSubmit: function(e) {
  },

  render: function() {
  }
});
```

```js:my-page.jsx

//MyComponent is an object declared in the global namespace

<MyComponent />
```

## 2. CommonJS module system (used by node.js)

* `require`
* `module.exports`

```js:my-component.jsx

var React = require('react');

var MyComponent = React.createClass({

  handleSubmit: function(e) {
  },

  render: function() {
  }
});

module.exports = MyComponent
```


```js:my-page.jsx

var MyComponent = require('./path/to/my-component.jsx');

<MyComponent />
```

## 3. ES6 modules

* `import`
* `export`

```js:my-component.jsx

import React from "react";

export default class MyComponent extends React.Component {

  handleSubmit(e) {
  }

  render() {
  }
}
```

```js:my-page.jsx

import MyComponent from './path/to/my-component.jsx';

<MyComponent />
```

More details about ES6 class syntax: [React on ES6+](http://babeljs.io/blog/2015/06/07/react-on-es6-plus/)



### Why use modules (instead of Rails sprockets) ?

* Code easier to read and maintain
* Code easier to test
* npm ecosystem power: more choice, librairies up-to-date...
* Decoupled architecture (Front-end application + Rails backend application, used to make API calls)

Blog entry and discussion: [Rails with Webpack - Why and How](https://reinteractive.net/posts/213-rails-with-webpack-why-and-how)

From [rails-webpack-react-flux](https://github.com/nambrot/rails-webpack-react-flux)

> Love the asset pipeline to death, but the lack of true modules definitely gets noticable with larger amounts of client side code. 

## How to use modules in our Rails application ?

We need to convert modules to plain JavaScript code.

* [Browserify](http://browserify.org/)
* [Webpack](http://webpack.github.io/) 

Webpack can be used to require any file (JavaScript, CoffeeScript, JSX, css, sass) and generates a single bundle file.

A nice add-on : [react-hot-reload](http://gaearon.github.io/react-hot-loader/)
React hot loader automaically updates the browser when a .JSX file is updated, keeping the context (state and props). 


### Examples of Rails + Webpack integration

* [rails-webpack-react-flux](https://github.com/nambrot/rails-webpack-react-flux): Rails + CoffeeScript + Flux (Flummox) + csjx + Webpack
* [react-webpack-rails-tutorial](https://github.com/justin808/react-webpack-rails-tutorial): Rails + ES6 + Flux (Alt) + Webpack
* [FFRRIWB on Rails](https://github.com/zepplock/FFRRIWB): Flux (Flummox), React, React Router, Immutable


## Discussion 

Single-Page-Application ("SPA") pros and cons

Pros:

* Fast (static assets pushed to a CDN, Rails only serves JSON data)
* Rich user experience
* Decoupled architecture: more flexible UI, easier to change
* Mobile application (native or hybrid) are possible

Cons:

* requires modern JavaScript skills!
* Building process
* in local environment, 2 servers are needed: a back-end server (Rails) + a front-end server that builds asset and serves static content (node.js) 
* Too complicated ? (皆んなさん、どう思いますか？)

## Coming soon, next 勉強会

* How to test (modern) JavaScript
* Flux architecture
* ...