JavaScript Module Server

By Szabolcs Szabolcsi-Tóth / @_Nec

Loading JavaScript

JS
HTML

Inline scripting

  • Quick sandboxing
  • Small demos
  • Learning
  • Testing
JS
HTML

JavaScript files

  • Separate code from markup
  • Step toward modules
  • Serve JS as an asset
JS
JS
JS
JS
JS
HTML

Code organization

  • Functions, Classes, Modules
  • Codebase growth
  • Loading becomes an issue

Packaging JavaScript

JS
JS
JS
JS
JS
HTML
PACKAGE

Packages

  • Single file
  • Less HTTP requests
  • Compressing
PACKAGE
PACKAGE
PACKAGE
PACKAGE

Partitioned Packages

  • Packs for Features
  • Few more HTTP rqs
  • JS packs according to features
PACKAGE
PACKAGE
modules/Foo
modules/Lorem
modules/Bar
modules/Foo
modules/Bar
modules/Ipsum

Overlapping Dependencies

  • common components
  • redundant code
PACKAGE
PACKAGE
PACKAGE
modules/Foo
modules/Lorem
modules/Bar
modules/Foo
modules/Bar
modules/Ipsum
modules/Baz
modules/Qux
modules/Dolor
modules/Sit

"Common Pitfall"

Put common code in a common package

Slowly leads to one,
huge package

Handling Dependencies

Modules

CommonJS

AMD

Harmony

Asynchronous Module Definition



define( 'name' , [ 'dep1', 'dep2' ] , function (dep1, dep2) { ... } );

Module Loaders

Register

Connect

Fetch

requirejs, curljs

Asynchronous Loading

SERVER
CLIENT
JS
JS
JS

Async Module Loading

  • Require
  • Fetch Modules
  • AMD references dependencies
  • Wait for deps
  • Module available

Dependency Graph

  • Codebase defined
  • Not Feature deined
JS
JS
JS
JS
JS
JS
JS
JS
JS
JS
JS
JS
JS
JS

Downside

  • Transitive dependencies
  • Waterfall of requests

Async Packages

SERVER
CLIENT
JS
JS
PACKAGE

Async Packages

  • Require
  • Fetch Package
  • Module available
SERVER
CLIENT
JS
JS
? PACKAGE

Downside

  • Which package?

Walking in circles?

Negative Loading

JSConf EU 2012

Malte Ubl & John Hjelmstad

Google / GMail

First Request

  • Module Request
  • Pack all dependencies
  • Serve
  • Register requested modules
SERVER
HTML
+ mod/Foo
+mod/Bar-mod/Foo
mod/Foo
dep1
dep2
dep3
dep4
PACKAGE
SERVER
HTML
+ mod/Foo
+ mod/Bar - mod/Foo
mod/Foo
dep1
dep2
dep3
dep4
mod/Bar
dep1
dep5
dep3
dep6

Subsequent Requests

  • Require
  • Find dependencies
  • Subtract
  • Serve
  • Register requested modules

Dependency Handling
on the Server

JavaScript is not a static asset anymore

JavaScript Module Server

Designed for

  • Single Page Applications
  • Large JS codebase
  • UX matters
  • Long visitor session

JMS

AMD module server for JavaScript

Serve Async and Efficiently

Deployment framework

JMS

Developed in Node.js

Stores data in Redis

Stateless server architecture

How it works

JMS
HTML
CLIENT

The JMS client

JMS
HTML
JMSC
PACKAGE
PACKAGE
+apps/Foo
+apps/Bar-apps/Foo

JMS Client

  • Serve client
  • Handle AMD
  • Fetch
  • Register
  • Order

Redundant requests

Circular dependencies

JMS
HTML
JMSC v42
v42
v43

Version Handling

  • Cliend Init
  • Bound to Version
  • Deploy
  • Client keeps version

Client embed




     ...

The JMS client

Almond.js + JMS loader

Deploy

Deploy

  • Code check
  • Dependencies
  • Plugins

Versioning

Error handling

Task runners

Cache

Unique URLs

version / + modules - modules ? extra-params

This is actually really bad

Support Re-Validation

Internal Cache
(mostly to save CPU)

Scale

Scale

VARNISH
CDN
JMS
JMS
JMS
JMS

Plugins

Plugins

Deploy

Serve

Deploy Plugins

Access all the codebase,
do the heavy work





  • jslint / jshint
  • code compression
  • transpile/generate

Server Plugins

Access the client request

Modify the modules to be served






  • i18n

Order plugins, can rely on each other

Plugin development

Simple Node.js Streams v2 interface

Every plugin is a Transform stream

Interface + Flow Control

Monitoring

Processes,
concurrent requests,
requests per second
...

Use

Integration

Measurements

Codebase refactor

Lessons learned

npm mirror

Sinopia

https://github.com/rlidwka/sinopia

PM2 clustering

PM2

https://github.com/unitech/pm2

Node.js Streams

Codebase modularization

Future

GZip
Source Maps
Cache Strategies
AMD plugins
CSS
SPDY / HTTP2
ES6 modules

github.com/ustream/jms

Thank you!

@_Nec

JavaScript Module Server Szabolcs Szabolcsi-Tóth