Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags!...

63
Modular JavaScript Andrew Eisenberg Tasktop Technologies 1

Transcript of Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags!...

Page 1: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

ModularJavaScriptAndrew Eisenberg

Tasktop Technologies

���1

Page 2: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

ModularJavaScriptAndrew Eisenberg

Tasktop Technologies

���1

(Non-)

Page 3: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

A story about JavaScript and modularization in 4

parts

���2

Page 4: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

A story about JavaScript and modularization in 4

parts

���2

No Modules (ancient history)

Page 5: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

A story about JavaScript and modularization in 4

parts

���2

No Modules (ancient history)

Module Pattern (industrial revolution)

Page 6: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

A story about JavaScript and modularization in 4

parts

���2

No Modules (ancient history)

Module Pattern (industrial revolution)

Module loaders (today)

Page 7: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

A story about JavaScript and modularization in 4

parts

���2

No Modules (ancient history)

Module Pattern (industrial revolution)

Module loaders (today)

Harmony Modules (tomorrow)

Page 8: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

A story about JavaScript and modularization in 4

parts

���2

No Modules (ancient history)

Module Pattern (industrial revolution)

Module loaders (today)

Harmony Modules (tomorrow)

This is really the story of a language reaching maturity

Page 9: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

We are Java Devs. Why should we care?JavaScript is not just blinky text and popups

Massive applications being built with it on client AND server

JavaScript is useful and ubiquitous

TIOBE index #9 (March 2014)

But JavaScript is (or was) only a toy language

���3

blinky

Page 10: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

We are Java Devs. Why should we care?JavaScript is not just blinky text and popups

Massive applications being built with it on client AND server

JavaScript is useful and ubiquitous

TIOBE index #9 (March 2014)

But JavaScript is (or was) only a toy language

���3

Page 11: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

But there is a core goodness

���4

Page 12: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

But there is a core goodness

���4

Page 13: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

No modules

Part I --- Ancient History (c. 1995)

���5

Page 14: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

The original approach

Script tags

All code is global

���6

Page 15: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

The original approach

Script tags

All code is global

���6

<html>      <script  “foo.js”/>      <script  “bar.js”/>  </html>

Page 16: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

The original approach

Script tags

All code is global

���6

<html>      <script  “foo.js”/>      <script  “bar.js”/>  </html>

//  foo.js  var  x  =  9;

Page 17: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

The original approach

Script tags

All code is global

���6

<html>      <script  “foo.js”/>      <script  “bar.js”/>  </html>

//  foo.js  var  x  =  9;

//  bar.js  console.log(x);

Page 18: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

Prognosis?

Name clashes

No explicit dependencies

Order is important

Just pray that all dependencies are available

���7

Page 19: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

Prognosis?

Name clashes

No explicit dependencies

Order is important

Just pray that all dependencies are available

���7

Ugggh!

Page 20: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

Module pattern

Part II --- Industrial Revolution (c. 2006)

���8

Page 21: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

Module pattern

All code is still global

Each script defines its own namespace

Pattern has many variations

���9

Page 22: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

Module pattern

All code is still global

Each script defines its own namespace

Pattern has many variations

���9

<html>      <script  “foo.js”/>      <script  “bar.js”/>  </html>

Page 23: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

Module pattern

All code is still global

Each script defines its own namespace

Pattern has many variations

���9

<html>      <script  “foo.js”/>      <script  “bar.js”/>  </html>//  foo.js  foo  =  foo  ||  {};  foo.x  =  9;

Page 24: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

Module pattern

All code is still global

Each script defines its own namespace

Pattern has many variations

���9

<html>      <script  “foo.js”/>      <script  “bar.js”/>  </html>//  foo.js  foo  =  foo  ||  {};  foo.x  =  9;//  bar.js  (function(foo)  {    var  x  =  “Number  ”;    console.log(x  +  foo.x);  })(foo);

Page 25: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

Still very populare.g., jQuery fn namespace*

���10

* jQuery 1.7 introduced AMD modules

Page 26: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

Still very populare.g., jQuery fn namespace*

���10

(function(  $  )  {    $.fn.myPlugin=function(args){      //  awesome  plugin  stuff    };  })(  jQuery  );  

 $.fn.myPlugin(args);* jQuery 1.7 introduced AMD modules

Page 27: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

Prognosis?

Name clashes,

but far less common

Easier to mock dependencies

But…

Order matters

Just pray that all dependencies are available

���11

Page 28: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

Prognosis?

Name clashes,

but far less common

Easier to mock dependencies

But…

Order matters

Just pray that all dependencies are available

���11

Better

Page 29: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

Prognosis?

Name clashes,

but far less common

Easier to mock dependencies

But…

Order matters

Just pray that all dependencies are available

���11

Better

But still ugggh!

Page 30: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

Module loadersPart III --- Today

���12

Page 31: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

The module explosion

���13

Idea! Use the environment to selectively load modules in order

Page 32: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

The module explosion

���13

Idea! Use the environment to selectively load modules in order

Relies on a module loader outside the language specification

Page 33: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

The module explosionFormats

CommonJS

AMD

���13

Idea! Use the environment to selectively load modules in order

Relies on a module loader outside the language specification

Page 34: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

The module explosionFormats

CommonJS

AMD

Loaders

node (CJS)

requireJs (AMD)

curl (AMD)

���13

Idea! Use the environment to selectively load modules in order

Relies on a module loader outside the language specification

Page 35: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

CommonJS

Used by node

Bad news for the web

���14

var  modA  =  require(‘moduleA’),      modB  =  require(‘moduleB’);  !

export.aVal  =  modA.myVal;  export.bVal  =  modB.myVal;

Page 36: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

CJS is not web-friendly

���15

//  main.js  if  (needSub)  {      require('./sub');  }

//  sub.js  console.log(‘here’);

Conditional loading of modules. (Yay!) But, that means synchronous loading Synchronous loading makes for horrendous web experience

Page 37: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

Asynchronous module definition (AMD)

Asynchronous loading of modules

Makes a happy web

Syntax more cumbersome

���16

define(‘myModule’,      [‘moduleA’,  ‘moduleB],        function(a,  b)  {      return  {            aVal:  a.myVal,          bVal  :  b.myVal      }  });

Page 38: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

Require.js: a sort of deep dive

(There’s magic, but the good kind)

���17

Page 39: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

Universal Module Declarations (UMD)

Attempt to unify client and server side modules

BUT not a standard

Semantics different browser vs. server

���18

Page 40: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

Universal Module Declarations (UMD)

Attempt to unify client and server side modules

BUT not a standard

Semantics different browser vs. server

���18

define(function(require,export,module){      var  modA  =  require(‘moduleA’),          modB  =  require(‘moduleB’);      export.aVal  =  modA.myVal;      export.bVal  =  modB.myVal;  });

Page 41: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

But UMD needs even more boilerplate

���19

All sorts of UMD proposals here: https://github.com/umdjs/umd

Page 42: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

But UMD needs even more boilerplate

���19

All sorts of UMD proposals here: https://github.com/umdjs/umd

//  Boilerplate  if  (typeof  module  ===  'object'  &&            typeof  define  !==  'function')  {      var  define  =  function  (factory)  {          module.exports  =  factory(require,exports,module);     };  }  //  Here  is  the  actual  module  define(function  (require,  exports,  module)  {      var  b  =  require('b');     return  function  ()  {};  });

Page 43: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

Browserify: no more boilerplate

Pre-processor

converts CJS -> AMD

something browser compatible

Avoid AMD boilerplate

Can use some node.js libs in browser

���20

*http://browserify.org/

Page 44: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

Browserify example

���21

// require the core node events module!var EventEmitter = require(‘events')!! .EventEmitter;!!//create a new event emitter!var emitter = new EventEmitter;!!// set up a listener for the event!emitter.on('pizza', function(message){! console.log(message);!});!!// emit an event!emitter.emit('pizza', ‘yummy!');

Page 45: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

Browserify example

���21

// require the core node events module!var EventEmitter = require(‘events')!! .EventEmitter;!!//create a new event emitter!var emitter = new EventEmitter;!!// set up a listener for the event!emitter.on('pizza', function(message){! console.log(message);!});!!// emit an event!emitter.emit('pizza', ‘yummy!');

$  browserify  index.js  >  bundle.js

Page 46: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

Prognosis?

���22

Page 47: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

Prognosis?No more language level name clashes

Not order dependent

Dependencies explicit in module

Load and edit time checkers

���22

Page 48: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

Prognosis?No more language level name clashes

Not order dependent

Dependencies explicit in module

Load and edit time checkers

���22

Yay! We did it!

Page 49: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

Prognosis?No more language level name clashes

Not order dependent

Dependencies explicit in module

Load and edit time checkers

���22

Yay! We did it!

...right?

Page 50: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

Prognosis?No more language level name clashes

Not order dependent

Dependencies explicit in module

Load and edit time checkers

BUT...

Too many competing module systems

modules for client and server

Modules still not first class

Boilerplate

���22

Yay! We did it!

...right?

Page 51: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

Prognosis?No more language level name clashes

Not order dependent

Dependencies explicit in module

Load and edit time checkers

BUT...

Too many competing module systems

modules for client and server

Modules still not first class

Boilerplate

���22

Yay! We did it!

...right?

Ugggh!

Page 52: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

Harmony ModulesPart IV --- Tomorrow

���23

Page 53: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

Real Modules

ES6 Harmony

Official JavaScript module spec

Sync and async friendly

Browser and server friendly

���24

Page 54: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

ES6 Harmony

���25

//  foo.js  module  "foo"  {          export  var  x  =  42;  }

//  bar.js  import  "foo"  as  foo;  console.log(foo.x);

Page 55: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

ES6 modules, today!Using the ES6 Module Transpiler*

���26

*https://github.com/square/es6-module-transpiler

Page 56: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

Prognosis ES6?Finally, modules are first class in the language!

Loaders/runtimes will implement spec differently

sync loading possible

async loading possible

���27

Page 57: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

Prognosis ES6?Finally, modules are first class in the language!

Loaders/runtimes will implement spec differently

sync loading possible

async loading possible

���27

Expected release date? 201X?

Page 58: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

Prognosis JavaScript?

���28

Page 59: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

Prognosis JavaScript?Plagued by poor design choices early on

���28

Page 60: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

Prognosis JavaScript?Plagued by poor design choices early on

JS used to be a toy language

���28

Page 61: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

Prognosis JavaScript?Plagued by poor design choices early on

JS used to be a toy language

Hard, but possible to fix past mistakes.

���28

Page 62: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

ResourcesES6 module transpiler

https://github.com/square/es6-module-transpiler AMD module specification (draft, never ratified):

http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition CommonJS module specification:

http://wiki.commonjs.org/wiki/Modules UMD modules (various proposed implementations):

https://github.com/umdjs/umd ES6 Harmony draft specification

http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts JavaScript Module pattern

http://www.adequatelygood.com/JavaScript-Module-Pattern-In-Depth.html

Browserify http://browserify.org http://superbigtree.tumblr.com/post/54873453939/introduction-to-browserify (borrowed browserify example)

���29

Page 63: Modular JavaScript - EclipseCon Europe 2019 · 2017-12-06 · The original approach Script tags! All code is global "6

Questions?

Andrew Eisenberg

twitter: @werdnagreb

email: [email protected]

���30

Story parts

No modules

Module pattern

Module loaders

Language modules