Slide 1

Slide 1 text

ES6 in Production JSConf Uruguay 2015

Slide 2

Slide 2 text

- Made in Buenos Aires, Argentina - Front-end Developer - Working at Mango @pazguille (twitter / github) Guille Paz

Slide 3

Slide 3 text

#ES6inProd Your feedback is welcome!

Slide 4

Slide 4 text

ES6

Slide 5

Slide 5 text

Hi! https://getmango.com

Slide 6

Slide 6 text

Why?

Slide 7

Slide 7 text

Why?

Slide 8

Slide 8 text

Future Why?

Slide 9

Slide 9 text

Why? Code

Slide 10

Slide 10 text

Why? ● Write expressive code

Slide 11

Slide 11 text

Why? ● Write expressive code ● Easier to understand

Slide 12

Slide 12 text

Why? ● Write expressive code ● Easier to understand ● Standardizes commons practices

Slide 13

Slide 13 text

Why? ES6 Modules

Slide 14

Slide 14 text

define('Slideout', // Deps ['inherit', 'Emitter'], // Slideout function(inherit, Emitter) { function Slideout(options) { … } // Export return Slideout; }); Why? AMD

Slide 15

Slide 15 text

// Deps var inherit = require('inherit'); var Emitter = require('emitter'); // Slideout function Slideout(options) { … } // Export module.exports = Slideout; Why? CommonJS

Slide 16

Slide 16 text

Why? ES6 Modules // Deps import inherit from 'inherit'; import Emitter from 'emitter'; // Slideout function Slideout(options) { … } // Export export default Slideout;

Slide 17

Slide 17 text

Why? Classes

Slide 18

Slide 18 text

No content

Slide 19

Slide 19 text

// Slideout function Slideout(options) { … } // Inherit from Emitter inherit(Slideout, Emitter); // Extend prototype Slideout.prototype.open = function() { … }; Why? Classes

Slide 20

Slide 20 text

// Slideout class Slideout extends Emitter { constructor(options={}) { … } open() { … } } Why? Classes

Slide 21

Slide 21 text

// Deps var inherit = require('inherit'); var Emitter = require('emitter'); // Slideout function Slideout(options) { … } // Inherit from Emitter inherit(Slideout, Emitter); // Extend prototype Slideout.prototype.open = function() { … }; // Export module.exports = Slideout; Why?

Slide 22

Slide 22 text

// Deps var inherit = require('inherit'); var Emitter = require('emitter'); // Slideout function Slideout(options) { … } // Inherit from Emitter inherit(Slideout, Emitter); // Extend prototype Slideout.prototype.open = function() { … }; // Export module.exports = Slideout; Why? // Deps import Emitter from 'emitter'; // Slideout class Slideout extends Emitter { constructor(options={}) { … } open() { … } } // Export export default Slideout;

Slide 23

Slide 23 text

Why? Classes arrow = > functions Module Syntax let/const Rest Parameters Templates Strings Default Parameters

Slide 24

Slide 24 text

getmango.com/blog https://getmango.com/blog/writing-es6-modules-with-6to5/

Slide 25

Slide 25 text

How?

Slide 26

Slide 26 text

Transpilers How?

Slide 27

Slide 27 text

How? ES6 ES5

Slide 28

Slide 28 text

How?

Slide 29

Slide 29 text

How?

Slide 30

Slide 30 text

Build Process How?

Slide 31

Slide 31 text

How?

Slide 32

Slide 32 text

browserify({'entries': opts.entries, 'debug': true}) .plugin('factor-bundle', {'outputs': opts.bundles}) .on('error', function(err) { … }) .bundle() .pipe(fs.createWriteStream(opts.output)); How?

Slide 33

Slide 33 text

How? Babelify

Slide 34

Slide 34 text

browserify({'entries': opts.entries, 'debug': true}) .plugin('factor-bundle', {'outputs': opts.bundles}) .transform('babelify') .on('error', function(err) { … }) .bundle() .pipe(fs.createWriteStream(opts.output)); How?

Slide 35

Slide 35 text

Browser How?

Slide 36

Slide 36 text

How? http://kangax.github.io/compat-table/es5/ ES5

Slide 37

Slide 37 text

Polyfills How?

Slide 38

Slide 38 text

How? http://kangax.github.io/compat-table/es6/ ES6

Slide 39

Slide 39 text

core-js How? https://github.com/zloirock/core-js

Slide 40

Slide 40 text

How? es5.js (IE < 9) Custom build https://github.com/zloirock/core-js

Slide 41

Slide 41 text

How? es5.js (IE < 9) es6.js (all) Custom build https://github.com/zloirock/core-js

Slide 42

Slide 42 text

index.html How? …

Slide 43

Slide 43 text

No content

Slide 44

Slide 44 text

No content

Slide 45

Slide 45 text

Issues

Slide 46

Slide 46 text

Issues Context

Slide 47

Slide 47 text

~110 modules Issues

Slide 48

Slide 48 text

Issues

Slide 49

Slide 49 text

ES5 / ES6 Issues

Slide 50

Slide 50 text

Dependencies Issues

Slide 51

Slide 51 text

Issues ├─ src ├─ boot.js └─ bus.js ├─ package.json ├─ test └─ node_modules ├─ slideout └─ emitter Dashboard ES6 ES6

Slide 52

Slide 52 text

Issues bus.js // Deps import Emitter from 'emitter'; // bus const bus = new Emitter(); // Export export default bus;

Slide 53

Slide 53 text

Issues

Slide 54

Slide 54 text

… exports['default'] = bus; module.exports = exports['default']; },{'emitter':2}],2:[function(require,module,exports){ class Emitter { on(event, listener) { … Issues output.js

Slide 55

Slide 55 text

No content

Slide 56

Slide 56 text

Issues Dashboard ├─ src ├─ boot.js └─ bus.js ├─ package.json ├─ test └─ node_modules ├─ slideout └─ emitter Babelify

Slide 57

Slide 57 text

Issues Dashboard ├─ src ├─ boot.js └─ bus.js ├─ package.json ├─ test └─ node_modules ├─ slideout └─ emitter Babelify

Slide 58

Slide 58 text

Issues Dashboard ├─ src ├─ boot.js └─ bus.js ├─ package.json ├─ test └─ node_modules ├─ slideout └─ emitter Babelify

Slide 59

Slide 59 text

global : true Issues

Slide 60

Slide 60 text

browserify({'entries': opts.entries, 'debug': true}) .plugin('factor-bundle', {'outputs': opts.bundles}) .transform('babelify') .on('error', function(err) { … }) .bundle() .pipe(fs.createWriteStream(opts.output)); Issues

Slide 61

Slide 61 text

browserify({'entries': opts.entries, 'debug': true}) .plugin('factor-bundle', {'outputs': opts.bundles}) .transform('babelify', {'global': true}) .on('error', function(err) { … }) .bundle() .pipe(fs.createWriteStream(opts.output)); Issues

Slide 62

Slide 62 text

… exports['default'] = bus; module.exports = exports['default']; },{'emitter':2}],2:[function(require,module,exports){ var Emitter = (function () { function Emitter() { … Issues output.js

Slide 63

Slide 63 text

package.json Issues

Slide 64

Slide 64 text

… "browserify": { "transform": ["babelify"] }, … Issues Emitter.js - package.json

Slide 65

Slide 65 text

… "browserify": { "transform": ["babelify"] }, "dependencies": { "babelify": "6.0.2" }, … Issues Emitter.js - package.json

Slide 66

Slide 66 text

Issues

Slide 67

Slide 67 text

Writing ES6 Issues

Slide 68

Slide 68 text

Publishing ES5 Issues

Slide 69

Slide 69 text

Issues Module ├─ src └─ index.js ├─ package.json └─ test

Slide 70

Slide 70 text

Issues Module ├─ src └─ index.js ├─ package.json └─ test ES6

Slide 71

Slide 71 text

Issues Module ES5 ├─ src └─ index.js ├─ package.json └─ test ├─ dist └─ index.js

Slide 72

Slide 72 text

… "main": "dist/index.js", … Issues package.json

Slide 73

Slide 73 text

Issues Compile Task (npm, grunt, gulp, broccoli)

Slide 74

Slide 74 text

… "main": "dist/index.js", "script": { "compile": "babel src --out-dir dist" }, … Issues Compile Task

Slide 75

Slide 75 text

Issues npm run compile

Slide 76

Slide 76 text

… "main": "dist/index.js", "script": { "compile": "babel src --out-dir dist", "prepublish": "npm run compile" }, … Issues Prepublish Task

Slide 77

Slide 77 text

mango/emitter Issues https://github.com/mango/emitter

Slide 78

Slide 78 text

Inheritance Issues

Slide 79

Slide 79 text

'use strict'; var extend = require('extend'); // Inherits prototype properties module.exports = function inherit(child, parent) { extend(child.prototype, parent.prototype); return parent.prototype; }; Issues inherit.js - ES5

Slide 80

Slide 80 text

Issues Emitter.js - ES6 class Emitter { constructor(options={}) { … } on() { … } emit() { … } … } export default Emitter;

Slide 81

Slide 81 text

// Deps var inherit = require('inherit'); var Emitter = require('emitter'); // Slideout function Slideout(options) { … } // Inherit from Emitter inherit(Slideout, Emitter); // Extend prototype Slideout.prototype.open = function() { … }; // Export module.export = Slideout; Issues Slideout.js - ES5

Slide 82

Slide 82 text

// Deps var inherit = require('inherit'); var Emitter = require('emitter'); // Slideout function Slideout(options) { … } // Inherit from Emitter inherit(Slideout, Emitter); // Extend prototype Slideout.prototype.open = function() { … }; // Export module.export = Slideout; Issues Slideout.js - ES5

Slide 83

Slide 83 text

console.log(Slideout.prototype); // { open: function } Issues Slideout.js - ES5

Slide 84

Slide 84 text

console.log(Emitter.prototype); // { } Issues Emitter.js - ES6

Slide 85

Slide 85 text

Issues http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts

Slide 86

Slide 86 text

Issues

Slide 87

Slide 87 text

class Emitter { … on() { … } … } Issues Emitter.js - ES6

Slide 88

Slide 88 text

class Emitter { … on() { … } … } Issues Emitter.js - ES5 function Emitter() {} Object.defineProperties(Emitter.prototype, { 'on': { 'writable': true, 'configurable': true, 'enumerable': false, 'value': function on() {} } });

Slide 89

Slide 89 text

class Emitter { … on() { … } … } Issues Emitter.js - ES5 function Emitter() {} Object.defineProperties(Emitter.prototype, { 'on': { 'writable': true, 'configurable': true, 'enumerable': false, 'value': function on() {} } });

Slide 90

Slide 90 text

Loose Mode (babel) Issues

Slide 91

Slide 91 text

Issues es6.classes

Slide 92

Slide 92 text

browserify({'entries': opts.entries, 'debug': true}) .plugin('factor-bundle', {'outputs': opts.bundles}) .transform('babelify', {'global': true, 'loose': ['es6.classes']}) .on('error', function(err) { … }) .bundle() .pipe(fs.createWriteStream(opts.output)); Issues Build Process

Slide 93

Slide 93 text

class Emitter { … on() { … } … } Issues Emitter.js - ES5 var Emitter = (function () { function Emitter() { … } Emitter.prototype.on = function on() {}; … return Emitter; })();

Slide 94

Slide 94 text

console.log(Slideout.prototype); // { open: function, on: function } Issues Slideout.js - ES5

Slide 95

Slide 95 text

Object.create Issues

Slide 96

Slide 96 text

'use strict'; var extend = require('extend'); // Inherits prototype properties. module.exports = function inherit(child, parent) { extend(child.prototype, parent.prototype); return parent.prototype; }; Issues inherit.js - ES5

Slide 97

Slide 97 text

'use strict'; // Inherits prototype properties. module.exports = function inherit(child, parent) { child.prototype = Object.create(parent.prototype); return parent.prototype; }; Issues inherit.js - ES5

Slide 98

Slide 98 text

super() - this Issues

Slide 99

Slide 99 text

class Slideout extends Emitter { constructor(options={}) { this._padding = options.padding; … } } Issues Slideout.js - ES6

Slide 100

Slide 100 text

Line 12: 'this' is not allowed before super() Issues

Slide 101

Slide 101 text

class Slideout extends Emitter { constructor(options={}) { this._padding = options.padding; … } } Issues Slideout.js - ES6

Slide 102

Slide 102 text

class Slideout extends Emitter { constructor(options={}) { super(options); this._padding = options.padding; … } } Issues Slideout.js - ES6

Slide 103

Slide 103 text

Issues https://twitter.com/jashkenas/status/585458831993528320

Slide 104

Slide 104 text

Issues http://benmccormick.org/2015/04/07/es6-classes-and-backbone-js/

Slide 105

Slide 105 text

import & hoisting Issues

Slide 106

Slide 106 text

import _ from 'i18n'; import translations from 'translations.json'; _.add(translations); import login from './login'; … Issues Login View - ES6

Slide 107

Slide 107 text

import _ from 'i18n'; import translations from 'translations.json'; _.add(translations); import login from './login'; … Issues Login View - ES6

Slide 108

Slide 108 text

Issues

Slide 109

Slide 109 text

Issues Login View - ES5 var _import = require('i18n'); var _import2 = _interopRequireWildcard(_import); var _translations = require('translations.json'); var _translations2 = _interopRequireWildcard(_translations); var _login = require('./login'); var __login2 = _interopRequireWildcard(__login); _import2['default'].add(_translations2['default']);

Slide 110

Slide 110 text

var _import = require('i18n'); var _import2 = _interopRequireWildcard(_import); var _translations = require('translations.json'); var _translations2 = _interopRequireWildcard(_translations); var _login = require('./login'); var __login2 = _interopRequireWildcard(__login); _import2['default'].add(_translations2['default']); Issues Login View - ES5

Slide 111

Slide 111 text

Issues

Slide 112

Slide 112 text

Babel 4.1.7 Issues

Slide 113

Slide 113 text

Takeaway

Slide 114

Slide 114 text

● Transpile to ES5 (Babel) Takeaway

Slide 115

Slide 115 text

● Transpile to ES5 (Babel) ● Use ES5/ES6 polyfills (core-js) Takeaway

Slide 116

Slide 116 text

● Transpile to ES5 (Babel) ● Use ES5/ES6 polyfills (core-js) ● Babelify: opts.global or package.json Takeaway

Slide 117

Slide 117 text

Takeaway ● Transpile to ES5 (Babel) ● Use ES5/ES6 polyfills (core-js) ● Babelify: opts.global or package.json ● Write ES6, publish ES5 (compile task)

Slide 118

Slide 118 text

● Transpile to ES5 (Babel) ● Use ES5/ES6 polyfills (core-js) ● Babelify: opts.global or package.json ● Write ES6, publish ES5 (compile task) ● Babel - loose mode (es6.classes, es6.modules, … ) Takeaway

Slide 119

Slide 119 text

Thank you! <3