Date post: | 17-Jul-2015 |
Category: |
Technology |
Upload: | guillermo-paz |
View: | 132 times |
Download: | 0 times |
ES6 in ProductionJSConf Uruguay 2015
- Made in Buenos Aires, Argentina
- Front-end Developer
- Working at Mango
@pazguille (twitter / github)
Guille Paz
#ES6inProdYour feedback is welcome!
ES6
Hi!
https://getmango.com
Why?
Why?
Future
Why?
Why?
Code
Why?
● Write expressive code
Why?
● Write expressive code
● Easier to understand
Why?
● Write expressive code
● Easier to understand
● Standardizes commons practices
Why?
ES6 Modules
define('Slideout',
// Deps
['inherit', 'Emitter'],
// Slideout
function(inherit, Emitter) {
function Slideout(options) { … }
// Export
return Slideout;
});
Why?
AMD
// Deps
var inherit = require('inherit');
var Emitter = require('emitter');
// Slideout
function Slideout(options) { … }
// Export
module.exports = Slideout;
Why?
CommonJS
Why?
ES6 Modules
// Deps
import inherit from 'inherit';
import Emitter from 'emitter';
// Slideout
function Slideout(options) { … }
// Export
export default Slideout;
Why?
Classes
// Slideout
function Slideout(options) { … }
// Inherit from Emitter
inherit(Slideout, Emitter);
// Extend prototype
Slideout.prototype.open = function() { … };
Why?
Classes
// Slideout
class Slideout extends Emitter {
constructor(options={}) { … }
open() { … }
}
Why?
Classes
// 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
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;
Why?
Classesarrow = > functions
Module Syntax
let/const
Rest Parameters
Templates Strings Default Parameters
getmango.com/blog
https://getmango.com/blog/writing-es6-modules-with-6to5/
How?
Transpilers
How?
How?
ES6 ES5
How?
How?
Build Process
How?
How?
browserify({'entries': opts.entries, 'debug': true})
.plugin('factor-bundle', {'outputs': opts.bundles})
.on('error', function(err) { … })
.bundle()
.pipe(fs.createWriteStream(opts.output));
How?
How?
Babelify
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?
Browser
How?
Polyfills
How?
core-js
How?
https://github.com/zloirock/core-js
How?
es5.js(IE < 9)
Custom build
https://github.com/zloirock/core-js
How?
es5.js(IE < 9)
es6.js(all)
Custom build
https://github.com/zloirock/core-js
index.htmlHow?
…
<!--[if lt IE 9]>
<script src="/js/es5.js"></script>
<![endif]-->
<script src="/js/es6.js"></script>
<script src="/js/build.js"></script>
</body>
Issues
Issues
Context
~110 modules
Issues
Issues
ES5 / ES6
Issues
Dependencies
Issues
Issues
├─ src
├─ boot.js
└─ bus.js
├─ package.json
├─ test
└─ node_modules
├─ slideout
└─ emitter
Dashboard
ES6
ES6
Issues
bus.js
// Deps
import Emitter from 'emitter';
// bus
const bus = new Emitter();
// Export
export default bus;
Issues
…
exports['default'] = bus;
module.exports = exports['default'];
},{'emitter':2}],2:[function(require,module,exports){
class Emitter {
on(event, listener) {
…
Issues
output.js
Issues
Dashboard
├─ src
├─ boot.js
└─ bus.js
├─ package.json
├─ test
└─ node_modules
├─ slideout
└─ emitter
Babelify
Issues
Dashboard
├─ src
├─ boot.js
└─ bus.js
├─ package.json
├─ test
└─ node_modules
├─ slideout
└─ emitter
Babelify
Issues
Dashboard
├─ src
├─ boot.js
└─ bus.js
├─ package.json
├─ test
└─ node_modules
├─ slideout
└─ emitter
Babelify
global : true
Issues
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
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
…
exports['default'] = bus;
module.exports = exports['default'];
},{'emitter':2}],2:[function(require,module,exports){
var Emitter = (function () {
function Emitter() {
…
Issues
output.js
package.json
Issues
…
"browserify": {
"transform": ["babelify"]
},
…
Issues
Emitter.js - package.json
…
"browserify": {
"transform": ["babelify"]
},
"dependencies": {
"babelify": "6.0.2"
},
…
Issues
Emitter.js - package.json
Issues
Writing ES6
Issues
Publishing ES5
Issues
Issues
Module
├─ src
└─ index.js
├─ package.json
└─ test
Issues
Module
├─ src
└─ index.js
├─ package.json
└─ test
ES6
Issues
Module
ES5
├─ src
└─ index.js
├─ package.json
└─ test
├─ dist
└─ index.js
…
"main": "dist/index.js",
…
Issues
package.json
Issues
Compile Task(npm, grunt, gulp, broccoli)
…
"main": "dist/index.js",
"script": {
"compile": "babel src --out-dir dist"
},
…
Issues
Compile Task
Issues
npm run compile
…
"main": "dist/index.js",
"script": {
"compile": "babel src --out-dir dist",
"prepublish": "npm run compile"
},
…
Issues
Prepublish Task
Inheritance
Issues
'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
Issues
Emitter.js - ES6
class Emitter {
constructor(options={}) { … }
on() { … }
emit() { … }
…
}
export default Emitter;
// 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
// 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
console.log(Slideout.prototype);
// { open: function }
Issues
Slideout.js - ES5
console.log(Emitter.prototype);
// { }
Issues
Emitter.js - ES6
Issues
http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts
Issues
class Emitter {
…
on() { … }
…
}
Issues
Emitter.js - ES6
class Emitter {
…
on() { … }
…
}
Issues
Emitter.js - ES5
function Emitter() {}
Object.defineProperties(Emitter.prototype, {
'on': {
'writable': true,
'configurable': true,
'enumerable': false,
'value': function on() {}
}
});
class Emitter {
…
on() { … }
…
}
Issues
Emitter.js - ES5
function Emitter() {}
Object.defineProperties(Emitter.prototype, {
'on': {
'writable': true,
'configurable': true,
'enumerable': false,
'value': function on() {}
}
});
Loose Mode(babel)
Issues
Issues
es6.classes
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
class Emitter {
…
on() { … }
…
}
Issues
Emitter.js - ES5
var Emitter = (function () {
function Emitter() { … }
Emitter.prototype.on = function on() {};
…
return Emitter;
})();
console.log(Slideout.prototype);
// { open: function, on: function }
Issues
Slideout.js - ES5
Object.create
Issues
'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
'use strict';
// Inherits prototype properties.
module.exports = function inherit(child, parent) {
child.prototype = Object.create(parent.prototype);
return parent.prototype;
};
Issues
inherit.js - ES5
super() - this
Issues
class Slideout extends Emitter {
constructor(options={}) {
this._padding = options.padding;
…
}
}
Issues
Slideout.js - ES6
Line 12: 'this' is not allowed before super()
Issues
class Slideout extends Emitter {
constructor(options={}) {
this._padding = options.padding;
…
}
}
Issues
Slideout.js - ES6
class Slideout extends Emitter {
constructor(options={}) {
super(options);
this._padding = options.padding;
…
}
}
Issues
Slideout.js - ES6
Issues
https://twitter.com/jashkenas/status/585458831993528320
Issues
http://benmccormick.org/2015/04/07/es6-classes-and-backbone-js/
import & hoisting
Issues
import _ from 'i18n';
import translations from 'translations.json';
_.add(translations);
import login from './login';
…
Issues
Login View - ES6
import _ from 'i18n';
import translations from 'translations.json';
_.add(translations);
import login from './login';
…
Issues
Login View - ES6
Issues
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']);
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
Issues
Babel 4.1.7
Issues
Takeaway
● Transpile to ES5 (Babel)
Takeaway
● Transpile to ES5 (Babel)
● Use ES5/ES6 polyfills (core-js)
Takeaway
● Transpile to ES5 (Babel)
● Use ES5/ES6 polyfills (core-js)
● Babelify: opts.global or package.json
Takeaway
Takeaway
● Transpile to ES5 (Babel)
● Use ES5/ES6 polyfills (core-js)
● Babelify: opts.global or package.json
● Write ES6, publish ES5 (compile task)
● 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
Thank you!
<3