senchacon 2016: modernizing the ext js class system - don griffin
TRANSCRIPT
![Page 1: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/1.jpg)
Modernizing the Ext JS Class System
Don Griffin@dongryphon
![Page 2: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/2.jpg)
Agenda
• Background- Goals for language and tools
- Tool landscape
• Class system content- Modules
- Classes & Mixins
- Life-cycle
• Timeline- WARNING: Code names ahoy!
![Page 3: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/3.jpg)
Goals
![Page 4: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/4.jpg)
Future-proofing
Balance Between…
Compatibility
![Page 5: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/5.jpg)
Future-proofing
Balance Between…
Compatibility• Ext.define works as before
• Existing code organization is supported
• Ext.require works as before
• callParent must be available
• Ext namespace is globally available
• class syntax can derive from any class
• Module-based structure is first-class
• import and export syntax is supported
• super calls must work (strict mode)
• Ext is scoped to its module
Sencha will provide an upgrade tool to transform a code base to ES6 form!
![Page 6: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/6.jpg)
Language Standards
![Page 7: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/7.jpg)
ES6 Score Cards
Windows 7http://kangax.github.io/compat-table/es6/
?
![Page 8: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/8.jpg)
Tools Enable Language Adoption
![Page 9: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/9.jpg)
Build Tool Trends
https://www.google.com/trends/explore?cat=5&q=grunt,gulp,webpack
![Page 10: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/10.jpg)
Node.js
Sencha Build (*)Open tooling platform
Scanner
Optimizer
Indexer
Compressor
…
webpackplugins
rollup
gulp
SystemJS
??
![Page 11: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/11.jpg)
Transpilers and Source Maps
![Page 12: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/12.jpg)
Transpilers
• Transpilers (like Babel) are JavaScript-to-JavaScript compilers
• Transpilers go beyond “polyfills” by providing missing language syntax!
• Transpilers are currently the only platforms that accept imports, exports and decorators
• Transpilers allow us to future-proof our code (unblocking the language adoption curve)- No more “least common denominator” development!
- Mostly…
- Not all API’s can be polyfilled (Proxy)
![Page 13: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/13.jpg)
Source Maps
• Source Maps enable the debugger to display the original source code…- …not inscrutable transpiler output!
• Source Maps have been around since 2012- This is great because they are widely supported
• Source Maps are supported by:- Chrome, Firefox, Edge, Safari
- IE11 (with Windows 8.1 Update)
![Page 14: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/14.jpg)
Trust But Verify
• Transpilers can produce some scary code- Only transpile away what your target browser(s) do not support
- Check what is produced if performance or code size is a concern
- Especially if you need to support browsers like IE 11… or Safari 9 (or older)
• Even natively supported idioms can have surprising performance- The “for…of” loop construct – awesome syntax! Not-so-great performance
https://kpdecker.github.io/six-speed/
![Page 15: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/15.jpg)
Trust But Verifyfor...of
var data = [1, 2, 3];var ret = '';
for (var value of data) { ret += value;}
var data = [1, 2, 3];var ret = '';
for (var i = 0; i < data.length; ++i) { ret += data[i];}
![Page 16: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/16.jpg)
Class System Contents
![Page 17: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/17.jpg)
Namespaces vs Modules
![Page 18: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/18.jpg)
Ext = {};Ext.global = window;Ext.global.Ext = Ext;
Ext.define('App.some.Thing', { extend: 'App.foo.Bar', requires: [ 'Ext.grid.Panel' ],
Namespaces
• Namespaces are nested objects
• Ext.define() adds to the namespace
• The Loader maps names to URL’s
• Files are loaded at global scope
Ext = { global: { Ext: Ext, App: { foo: { Bar: constructor }, some: { Thing: constructor } } }, grid: { Panel: constructor } }
Ext.Loader.setPath({ Ext: '../ext/src', App: './app' });
// Ext.grid.Panel // => '../ext/src/grid/Panel.js'
// App.foo.Bar // => './app/foo/Bar.js'
![Page 19: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/19.jpg)
var foo = 'bar'; // private, not global
export var abc = 'abc';
export default class Bar { // ...}
Modules
• Modules are files
• Modules execute in a private scope (not global)
• Modules publish values using export
• Modules can have one, unnamed “default” export value
• Modules use import to acquire values exported by other modules
• Modules are imported by path or name
• Named modules are resolved by the module loader
import { abc } from '../path/file';
import Bar from '../path/file.js';
import Ext from '@extjs/kernel';
import { define } from '@extjs/kernel';
./path/file.js
./other/thing.js
![Page 20: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/20.jpg)
import { button } from '@extjs/modern';
import { hbox } from '@extjs/modern/layout';
import { Ext_Button } from '@extjs/modern';
Importing Components
• Classes are exported in several ways:- By xtype
- By alias family
- By class name
• These would be used where strings might be used today
• These exports can be generated by Sencha Build
![Page 21: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/21.jpg)
Sencha Cmd Understands Namespaces
Sencha Build Understands Modules
![Page 22: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/22.jpg)
Classes
![Page 23: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/23.jpg)
Ext.define('App.some.Thing', { extend: 'App.foo.Bar', requires: [ 'Ext.grid.Panel' ],
alias: 'thing', text: 'Hello',
constructor: function (config) { this.callParent([config]); },
method: function (x) { return this.callParent([x]) * 42; },
statics: { create: function (cfg) { cfg.type = 'thing'; return this.callParent([cfg]); } }});
Classes Today
Ext.define()
• Inheritance
• Directives
• Properties
• Constructors
• Methods
• Static methods
• Super calls / callParent
![Page 24: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/24.jpg)
Classes Today
__proto__
prototype
create
App.some.Thing
__proto__constructormethodself
App.some.Thing.prototype
{fn} {fn}{fn}
Function.prototype App.foo.Bar.prototype
Object.prototype
__proto__
foo 42
new App.some.Thing()
![Page 25: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/25.jpg)
import { define } from '@extjs/kernel';import { grid } from '@extjs/modern';import Bar from 'app/foo';
@define('App.some.Thing', { alias: 'thing', text: 'Hello'})class Thing extends Bar { method (x) { return super.method(x) * 42; }
static create (cfg) { cfg.type = 'thing'; return super.create(cfg); }}export default Thing;
Classes in ES6+
import - export - class - @define
• Inheritance
• Directives
• Properties
• Methods
• Static methods
• Super calls
Decorator
![Page 26: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/26.jpg)
function define (className, body) { return T => { T.define(className, body); };}
@define('App.some.Thing', { alias: 'thing', text: 'Hello'})class Thing extends Bar {}
define('App.some.Thing', { alias: 'thing', text: 'Hello'})(Thing);
Decorators
• Decorators are functions that manipulate classes (or methods)
• Decorators can accept arguments…- But must return a function to call as if no
arguments were provided
• The @decorator syntax is just a different way to call these functions
• Decorators are currently a Stage 2 proposal (not yet standardized)
// @define('App.some.Thing', {// alias: 'thing',// text: 'Hello'// })
https://github.com/tc39/proposals
![Page 27: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/27.jpg)
Classes in ES6+
__proto__
prototype
create
App.some.Thing
__proto__constructmethodconstructor
App.some.Thing.prototype
{fn} {fn}{fn}
Function.prototype
App.foo.Bar.prototype
Object.prototype
App.foo.Bar Same meaningas constructor
was previously
![Page 28: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/28.jpg)
Classes Before
__proto__
prototype
create
App.some.Thing
__proto__constructormethodself
App.some.Thing.prototype
{fn} {fn}{fn}
Function.prototypeApp.foo.Bar.prototype
Object.prototype
![Page 29: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/29.jpg)
Classes After
__proto__
prototype
create
App.some.Thing
__proto__constructmethodconstructor
App.some.Thing.prototype
{fn} {fn}{fn}
Function.prototype
App.foo.Bar.prototype
Object.prototype
App.foo.Bar
![Page 30: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/30.jpg)
class Foo { constructor (x) { this.x = 42; }}
new Foo(42);
let obj = {};Foo.call(obj, 42);
Restrictions on constructor
• A constructor can only be called with the new operator.
• Calling a constructor with call() or apply() throws a TypeError.
![Page 31: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/31.jpg)
Mixins
![Page 32: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/32.jpg)
Ext.define('App.mixin.Foo', { method: function (x) { return x * 42; }});
Ext.define('App.some.Thing', { extend: 'App.foo.Bar', mixins: [ 'App.mixin.Foo' ],});
Ext.define('App.some.OtherThing', { extend: 'App.foo.Bar', mixins: [ 'App.mixin.Foo' ],
method: function (x) { return 10 * this.mixins.foo.method.call(this, x); }});
Mixins Today
• Mixins ≈ multiple inheritance
• Mixins are classes
• Methods from the mixin prototype are copied to the target class prototype
• Unless there is already a method present
• The mixins object references the various mixin prototypes
thing.method(2);
this.mixins.observable.constructor.call(this);this.mixins.observable.construct.call(this);
![Page 33: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/33.jpg)
import { Ext, define } from '@extjs/kernel';import Bar from 'app/foo';
class Mixable extends Ext.Base { method (x) { return x * 42; }}
@define({ mixins: [ Mixable ] })class Thing extends Bar { method (x) { return 10 * this.mixins.mixable.method.call(this, x); }}
@define({ extend: [ Mixable ] })class OtherThing extends Bar { method (x) { return 10 * super.method(x); }}
Mixins in ES6+
• Mixins are classes (that extend Ext.Base)
• Use @define to mix in the mixin(s)
• Mixins will be able to act more like a true base- The extend directive accepts mixins
- Calls to overlapping methods are handled in the super call
![Page 34: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/34.jpg)
Common Object Life-cycle
![Page 35: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/35.jpg)
The Life-cycle of Ext.BaseCreation• Instances are created with operator new- or Ext.create() or other factory
• The native constructor is available to ES6 classes- Not recommended in most cases
• The construct method is available to all classes- The new name for the old constructor
![Page 36: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/36.jpg)
The Life-cycle of Ext.BaseConfiguration• Use the config directive to define configuration properties
• Config system calls your apply and update methods
• Use the built-in, single-object-parameter form of the construct method
• Ext.Base#construct calls initConfig (if needed)
![Page 37: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/37.jpg)
The Life-cycle of Ext.BaseDestruction• Cleanup is handled by destroy• Sets flags like destroying and destroyed• Ignores multiple calls
• Calls destruct (just once)
• Clears instance properties to avoid memory leaks
![Page 38: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/38.jpg)
The Life-cycle of Ext.BaseTemplate methods (*)• ctor- Called to initialize an instance
- Called after the ctor of all base classes and mixins
• dtor - Called to cleanup an instance
- Called before the dtor of bases or mixins
• No super calls required- All implementations of ctor and dtor are called automatically
![Page 39: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/39.jpg)
import Ext from '@extjs/kernel';
class A extends Ext.Base { construct (x) { super.construct(); this.x = 42; this.x2 = this.x * 10; }}
class B extends A { construct (x, y) { super.construct(x); this.y = y; this.y2 = y * 427; }}
@define({ mixins: [ B ] })class C extends Ext.Base { construct (x, y) { super.construct(); this.mixins.b.construct(x, y); this.c = this.x + this.y + this.x2 + this.y2; }}
new C(4, 42);
Life-cycles & Diamonds
A
Ext.Base
B
C
![Page 40: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/40.jpg)
import { Ext, define } from '@extjs/kernel';
@define({ config: { x: 0 }})class A extends Ext.Base { updateX (x) { this.x2 = x * 10; }}
class B extends A { ctor () { this.y2 = this.y * 427; }}
@define({ mixins: [ B ] })class C extends Ext.Base { ctor () { this.c = this.getX() + this.y + this.x2 + this.y2; }}
new C({ x: 2, y: 42 });
Life-cycles & Diamonds
A
Ext.Base
B
C
![Page 41: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/41.jpg)
Life-cycles & Diamonds
A
Ext.Base
B
C
• ctor methods are called once per class- In base-to-derived order (including mixins!)
• dtor methods are called once per class- In derived-to-base order
• Ext.Base#construct calls ctor
• Ext.Base#destruct calls dtor
• ctor/dtor methods are gathered lazily- Never unless construct/destruct are used
ctor
ctor
ctor
ctor
dtor
dtor
dtor
dtor
![Page 42: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/42.jpg)
The Road Ahead
![Page 43: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/43.jpg)
The Road AheadSencha Cmd 6.5
• Available now (Early Access)!
• Uses Google Closure Compiler
• Supports much of the ES6 syntax (http://kangax.github.io/compat-table/es6/)
• Provides polyfills as well
• Transpiling is optional
• New compressor (replaces YUI) can process native ES6 code- Only compressor currently to do so!
![Page 44: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/44.jpg)
The Road AheadExt JS.Next
• Sencha Build and Sencha Cmd
• Upgrade tool to convert from projects from Cmd to Build- See Ross’s talk!
• Estimated at 2nd half of 2017
![Page 45: SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin](https://reader035.vdocuments.mx/reader035/viewer/2022062523/58ec481b1a28ab35628b471d/html5/thumbnails/45.jpg)