Web Technologies
- Package Management
- JavaScript Modules
- Module Loading
- JavaScript Languages
- JavaScript Client Frameworks
- JavaScript Testing Frameworks
- Task Runners/Development Experience
- Bundling/Deployment/Loading
- Offline Applications/Electron (chromium)
Package Management
- NPM - npmjs.org
- Bower - bower.io
- JSPM - jspm.io
NPM
- npm is the package manager for Node.js. It was created in 2009 as an open source project to help JavaScript developers easily share packaged modules of code.
- The npm Registry is a public collection of packages of open-source code for Node.js, front-end web apps, mobile apps, robots, routers, and countless other needs of the JavaScript community.
- npm is the command line client that allows developers to install and publish those packages.
- npm, Inc. is the company that hosts and maintains all of the above.
NPM
How do I use it?
# Installing a package
$ npm install bluebird
# Save installed package to package.json
$ npm install bluebird --save
# Save installed package to development package list in package.json
$ npm install karma --save-dev
# Install packages in clean repository from package.json
$ npm install
NPM
How does it work?
Require desired module using CommonJS or ES6 module loading. (Will discuss modules more in the next slides.)
// CommonJS style
var Promise = require('bluebird');
// ES6 module loading
import * as Promise from 'bluebird';
// or
// has to have a default export
import Promise from 'bluebird';
// or
// has to export an object with the mapped properties
import {Foo, Bar} from 'somelib';
NPM
How does it work? (continued)
- Node.js will first look to see if the required module is a core module like http, fs, path, etc. Node comes packaged with these core modules.
- If the required module is not a core module, node will then search the filesystem. It does this by starting in the current executing directory for a folder named "node_modules". If not found, it will look in the parent folder and so on.
-
Once a node_modules folder is found, it will look in that folder for the following in order. (Let's assume we are looking for module "bluebird").
- node_modules/bluebird.js
- node_modules/bluebird/index.js
- node_modules/bluebird/package.json (and use the main property value as a file location reference)
NPM
Can I install globally?
NPM allows you to install a package globally.
npm install bluebird -g
Node.js will look in the global package directory (defined in your require.paths array) for a required package if it cannot be found in the locations mentioned in the previous slide.
NPM
Can I create a command line tool?
Yes, you can configure a script to be run as a command line tool.
http://blog.npmjs.org/post/118810260230/building-a-simple-command-line-tool-with-npm
# typescript (and many other tools) works this way
$ npm install typescript -g
$ tsc ...
NPM
What does the package.json file look like?
{
"name": "bluebird",
"description": "Full featured Promises/A+ implementation with exceptionally good performance",
"version": "2.9.34",
"keywords": [
// keywords for searching on npmjs.org
],
"scripts": {
"lint": "node scripts/jshint.js",
"test": "node tools/test.js",
"istanbul": "istanbul",
"prepublish": "node tools/build.js --no-debug --main --zalgo --browser --minify"
},
"homepage": "https://github.com/petkaantonov/bluebird",
"repository": {
"type": "git",
"url": "git://github.com/petkaantonov/bluebird.git"
},
"bugs": {
"url": "http://github.com/petkaantonov/bluebird/issues"
},
"license": "MIT",
"author": {
"name": "Petka Antonov",
"email": "petka_antonov@hotmail.com",
"url": "http://github.com/petkaantonov/"
},
"devDependencies": {
"acorn": "~0.6.0",
"baconjs": "^0.7.43",
// truncated...
},
"main": "./js/main/bluebird.js",
"browser": "./js/browser/bluebird.js",
"files": [
"js/browser",
"js/main",
"js/zalgo",
"zalgo.js"
],
"maintainers": [
{
"name": "esailija",
"email": "petka_antonov@hotmail.com"
}
],
"readme": "ERROR: No README data found!"
}
NPM
Can it do anything else?
- Reference public and private git repos
- If private, requires ssh, not https basic-auth
- Reference tarbal via http or file path
Bower

Bower works by fetching and installing packages from all over, taking care of hunting, finding, downloading, and saving the stuff you're looking for. Bower keeps track of these packages in a manifest file, bower.json. How you use packages is up to you. Bower provides hooks to facilitate using packages in your tools and workflows.
Bower is optimized for the front-end. Bower uses a flat dependency tree, requiring only one version for each package, reducing page load to a minimum.
Bower

How do I use it?
# Unlike npm, it doesn't come packaged with node.js. You must install it, via npm!
$ npm install -g bower
#######################
# Installing packages #
#######################
# registered package
$ bower install jquery
# GitHub shorthand
$ bower install desandro/masonry
# Git endpoint
$ bower install git://github.com/user/package.git
# URL
$ bower install http://example.com/script.js
Bower

How does it work?
Unlike npm, which uses CommonJS modules, you do not reference Bower modules in the same way.
Bower is focused mainly on browser modules. These are typically files that you directly include via script tags like illustrated below. Some will support AMD modules, which will be discussed in a few slides.
<script src="bower_components/jquery/dist/jquery.min.js"></script>
Bower

How does it work? (continued)
-
Bower by default stores all installed packages into a directory called "bower_components".
- You can override this by configuring an .bowerrc file in the root directory.
-
Bower, similar to npm, has a manifest file called bower.json. This file contains references to all the bower packages you have installed.
- You typically will not check in your bower packages. You will check in your bower.json file and install via a startup script similar to npm.
# Install bower packages configured in the bower.json file
$ bower install
Bower

What does the bower.json file look like?
{
"name": "blue-leaf",
"description": "Physics-like animations for pretty particles",
"main": [
"js/motion.js",
"sass/motion.scss"
],
"dependencies": {
"get-size": "~1.2.2",
"eventEmitter": "~4.2.11"
},
"devDependencies": {
"qunit": "~1.16.0"
},
"moduleType": [
"amd",
"globals",
"node"
],
"keywords": [
"motion",
"physics",
"particles"
],
"authors": [
"Betty Beta <bbeta@example.com>"
],
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
]
}
JSPM
- jspm is a package manager for the SystemJS universal module loader, built on top of the dynamic ES6 module loader
- Load any module format (ES6, AMD, CommonJS and globals) directly from any registry such as npm and GitHub with flat versioned dependency management. Any custom registry endpoints can be created through the Registry API.
- For development, load modules as separate files with ES6 and plugins compiled in the browser.
- For production (or development too), optimize into a bundle, layered bundles or a self-executing bundle with a single command.

JSPM

How do I set it up?
# Install jspm CLI
$ npm install jspm -g
# Use in a project
$ npm install jspm --save-dev
$ jspm init
# You will need to follow the instructions: Here is an example output
#
# Package.json file does not exist, create it? [yes]:
# Would you like jspm to prefix the jspm package.json properties under jspm? [yes]:
# Enter server baseURL (public folder path) [.]:
# Enter jspm packages folder [./jspm_packages]:
# Enter config file path [./config.js]:
# Configuration file config.js doesn't exist, create it? [yes]:
# Enter client baseURL (public folder URL) [/]:
# Which ES6 transpiler would you like to use, Traceur or Babel? [traceur]:
JSPM

How do I use it?
# Install any packages from the jspm Registery, Github, or npm
$ jspm install npm:lodash-node
$ jspm install github:components/jquery
$ jspm install jquery
$ jspm install myname=npm:underscore
JSPM is also allows plugins, so you can install from bower for example.
# Install jspm-bower-endpoint via npm
$ npm install -g jspm-bower-endpoint
# add registry endpoint
$ jspm registry create bower jspm-bower-registry
# Install bower dependency
$ jspm install bower:skeleton
JSPM

How does it work?
This gets more into module loading and I will cover this in that section while also talking about RequireJS, Browserify, WebPack, etc.
JavaScript Modules
- CommonJS
- Module system created for node.js
- Resolved using the process mentioned in the npm discussion (traditionally)
- AMD (Asynchronous Module Definitions)
- Module system created for RequireJS
- Resolved using a config file mapping (traditionally)
Both:
- Only load the module once, and within an isolated scope
- Load all dependencies up front before execution of the module code. (except for inline require statements in AMD)
JavaScript Modules
Examples
// CommonJS Example
var $ = require('jquery');
exports.nameElement = $('input.name');
// AMD Example
define(['jquery'], function ($) {
return {
nameElement: $('input.name')
};
});
JavaScript Modules
CommonJS
// Export multiple properties as example.js
var $ = require('jquery');
var _ = require('lodash');
var fruit = ['Apple', 'Banana', 'Peach'];
exports.nameElement = $('input.name');
exports.findFruit = function (predicate) {
return _.where(fruit, predicate);
};
// Consume example.js
var example = require('./example');
var nameElement = example.nameElement;
var fruitWithFiveLetters = example.findFruit(function (fruit) {
return fruit.length === 5;
});
JavaScript Modules
CommonJS (weirdness)
// Export function (class) person.js
function Person (name, age) {
this.name = name;
this.age = age;
}
exports.Person = Person;
// Consume person.js
var Person = require('./person');
var adam = new Person.Person('Adam Carr', 34); // I hate redundancy!!
/************
* The fix! *
***********/
// person.js
function Person (name, age) {
this.name = name;
this.age = age;
}
exports = Person;
// Consume person.js
var Person = require('./person');
var adam = new Person('Adam Carr', 34);
JavaScript Modules
CommonJS (ES6)
// person.js
export function canDrink (person) {
return person.age >= 21;
}
export default function Person (name, age) {
this.name = name;
this.age = age;
}
// Consume person.js
import Person from './person';
var adam = new Person('Adam Carr', 34);
// How do I get to canDrink? You can't this way.
// Consume person.js
import Person, { canDrink } from './person';
var adam = ...;
canDrink(adam); // true
// What if there were more exported properties, how do I get them all?
// Do I have to list each on? You can, and there are advantages to listing
// them all (performance wise), but you can also import all to a local object
import Person, * as PersonExtra from './person';
var adam = ...;
PersonExtra.canDrink(adam); // true
PersonExtra.isHandsome(adam); // we don't know, it is not implemented
// NOTE: Person could also be referenced as follows in this example
var john = new PersonExtra.default('John Doe', 100);
JavaScript Modules
AMD
// Export multiple properties as example.js
define(['jquery', 'lodash'], function ($, _) {
var fruit = ['Apple', 'Banana', 'Peach'];
return {
namedElement: $('input.name'),
findFruit: function (predicate) {
return _.where(fruit, predicate);
}
};
});
// Consume example.js
define(['./example'], function (example) {
var nameElement = example.nameElement;
var fruitWithFiveLetters = example.findFruit(function (fruit) {
return fruit.length === 5;
});
});
JavaScript Modules
AMD (no weirdness)
// Export function (class) person.js
// Since it is a usual require statement, you naturally would just return
// the function vs assigning to exports. Easier to grok for me at least.
define([], function () {
function Person (name, age) {
this.name = name;
this.age = age;
}
return Person;
});
// Consume person.js
define(['./person'], function (Person) {
var adam = new Person('Adam Carr', 34);
});
Module Loading
In the browser
- RequireJS
- Browserify
- JSPM
- WebPack




Module Loading
RequireJS

- Designed for loading AMD modules
- Only works with AMD modules
- r.js bundler/optimizer
- Config for customizing deployment locations, shimming libraries, setting dependencies
- Only load modules when needed, asynchronously, unless told otherwise.
- Supports plugins for non-JavaScript files like text, css, etc.
Module Loading
browserify
- Let's you require('modules') in the browser by bundling up all of your dependencies.
- Provides functionality to handle common node-isms like process.nextTick(), __dirname, and __filename that are common in npm modules.
- Has browser versions of the node core libraries events, stream, path, url, assert, buffer, util, querystring, http, vm, and crypto and are included when require('')'d.
- Supports plugins for non-JavaScript files like text, css, etc.

Module Loading
JSPM
- Load any module format (ES6, AMD, CommonJS, globals) directly from any registry such as npm, and github with flat versioned dependency management.
- Allows you to both bundle output into a single or partitioned files, or load on demand, when require('')'d.
- Creates a config file for customizing deployment and mapping dependencies.
- Supports plugins for non-JavaScript files like text, css, etc.

Module Loading
WebPack
- Supports AMD and CommonJS modules.
- Allows you to both bundle output into a single or partitioned files.
- Does't support load on demand, when require('')'d.
- Supports plugins for non-JavaScript files like text, css, etc.

JavaScript Languages
- ES[3,5,6,7...] - ECMAScript (JavaScript) versions.
- TypeScript - Microsoft design time typed/transpiled language
- CoffeeScript - Community (OSS) transpiled language
- Dart - Google native language for Chrome also compiled
- GWT - Google Web Toolkit - Java compiled to JavaScript
- ScriptSharp - C# compiled to JavaScript
- ASM.js - An intermediate programming language designed to allow computer software written in languages such as C to be run as web applications while maintaining performance characteristics considerably better than standard JavaScript.
JavaScript Languages
TypeScript
TypeScript lets you write JavaScript the way you really want to. TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. Any browser. Any host. Any OS, Open Source

- TypeScript supports copy and paste of raw JavaScript. It will output the same since it is a superset.
- Provides design time type support.
- Provides design and runtime decorators (attributes)
- Provides support for generics, interfaces, classes, and inheritance
- Single module system that will transpile to both CommonJS and AMD*
- Familiar feel with typed languages like C#
- Clean output
JavaScript Languages
TypeScript (Example)

class Greeter {
constructor (public message: string) { }
greet() {
return `Hello, ${this.message}`;
}
}
var greeter = new Greeter("world");
var button = document.createElement('button')
button.innerText = "Say Hello"
button.onclick = function() {
alert(greeter.greet())
}
document.body.appendChild(button)
var Greeter = (function () {
function Greeter(message) {
this.message = message;
}
Greeter.prototype.greet = function () {
return "Hello, " + this.message;
};
return Greeter;
})();
var greeter = new Greeter("world");
var button = document.createElement('button');
button.innerText = "Say Hello";
button.onclick = function () {
alert(greeter.greet());
};
document.body.appendChild(button);
JavaScript Languages
CoffeeScript

CoffeeScript is a little language that compiles into JavaScript. Underneath that awkward Java-esque patina, JavaScript has always had a gorgeous heart. CoffeeScript is an attempt to expose the good parts of JavaScript in a simple way.
- Familiar feel to Ruby developers.
- Doesn't support copy/paste of raw JavaScript
- No design time typing support. (Some third party library options here like jzbuild.)
- Support for classes and inheritance
- Built in language extensions like comprehensions, loops, and ranges.
- Clean output (more of a shift than with TypeScript due to the different syntax)
JavaScript Languages
CoffeeScript (Example)

class Greeter
constructor: (@message) ->
greet: () ->
return "Hello, #{@message}"
greeter = new Greeter 'World'
button = document.createElement 'button'
button.innerText = 'Say Hello'
button.onclick ->
alert greeter.greet()
document.body.appendChild button
var Greeter, button, greeter;
Greeter = (function() {
function Greeter(message) {
this.message = message;
}
Greeter.prototype.greet = function() {
return "Hello, " + this.message;
};
return Greeter;
})();
greeter = new Greeter('World');
button = document.createElement('button');
button.innerText = 'Say Hello';
button.onclick(function() {
return alert(greeter.greet());
});
document.body.appendChild(button);
Client Frameworks
- AngularJS
- BackboneJS
- EmberJS
- KnockoutJS
- ReactJS
- Web Components*
Client Frameworks
Common features:
- MV* (C | VM) design philosophy
- Data binding (one way and/or two way)
- Template management
- REST API library
- Routing
- Component Encapsulation
BackboneJS

- Basic plumbing
- Strong model/collection mapping to REST API
- No default template library
- No direct support for two-way binding
- Data binding usually provided via collection/model change events and third party template library
- Dependency on underscore and jquery
EmberJS

- Full featured MVC framework
- Mustache templates
- Two-way binding (using object wrappers)
- jquery for REST API calls (typically)
- Dependency on jquery
KnockoutJS

- MVVM framework
- Two-way binding (using object wrappers)
- Similar to C# IObservables
- Similar syntax to WPF bindings
- Custom elements (ko-components)
- jquery for REST API calls (typically)
- No built in routing (sammyjs)
AngularJS

- POJO models and collections
- Two-way data binding
- Scope
- Digest Loop
- Watches**
- Directives
- Dependency Injection
ReactJS

- POJO models and collections
- Two-way data binding
- No watch concerns
- Full stack render on data change
- Diff on changes and update DOM where necessary
- Combines JavaScript with Template in single file
- Flux (concept, not library)
Web Components
- Not a library, but a concept based on new HTML5 specs
- Custom elements
- Shadow DOM
- HTML Imports
- HTML Templates
- Encapsulation
- Polymer (google)
JavaScript Section 05
By Developers Bay
JavaScript Section 05
- 982