Module, AMD, RequireJS

65
Module, AMD, RequireJS othree @ JSDC 2012

Transcript of Module, AMD, RequireJS

Page 1: Module, AMD, RequireJS

Module, AMD, RequireJSothree @ JSDC 2012

Page 2: Module, AMD, RequireJS

Object

Page 3: Module, AMD, RequireJS

Object Oriented Programming

Page 4: Module, AMD, RequireJS

Why OOP

• Maintainable & Scalable

• Gathering related variables & methods

Page 5: Module, AMD, RequireJS

Object from OOP

• Inheritance

• Polymorphism

• Encapsulation

Page 6: Module, AMD, RequireJS

Encapsulation

• A language mechanism for restricting access to some of the object's components.

http://en.wikipedia.org/wiki/Encapsulation_(object-oriented_programming)

Page 7: Module, AMD, RequireJS

Why Encapsulation

• Protect variable from unwanted change

Page 8: Module, AMD, RequireJS

JavaScript is Prototype-based

Page 9: Module, AMD, RequireJS

Private Data in JavaScript

Page 10: Module, AMD, RequireJS

Naming Conventionfunction Human(sgender) { //Private this._age = 1; this._gender = sgender || 'Male'; //Public this.growUp = function () { this._age++; };}

Page 11: Module, AMD, RequireJS

Human

_age

_gender

growUp

Accessible Anywhere

Page 12: Module, AMD, RequireJS

Privileged Methodfunction Human(sgender) { //Private var age = 1, gender = sgender || 'Male'; //Privileged Method this.growUp = function () { age++; };}

http://javascript.crockford.com/private.html

Page 13: Module, AMD, RequireJS

Human

age

gender

growUp

Accessible Anywhere

Page 14: Module, AMD, RequireJS

Module Pattern

Page 15: Module, AMD, RequireJS

Module Patternfunction Human(sgender) { //Private var age = 1, gender = sgender || 'Male'; //Public return { growUp: function () { age++; } };}

http://yuiblog.com/blog/2007/06/12/module-pattern/

Page 16: Module, AMD, RequireJS

Accessible Anywhere

exports

Human

age

gender

growUp

Page 17: Module, AMD, RequireJS

Advantage

• Easy

• Keep private data safe

Page 18: Module, AMD, RequireJS

Disadvantage

• Hard to inherit

Page 19: Module, AMD, RequireJS

Large Application

• Lots of modules

• Complex dependency

Page 20: Module, AMD, RequireJS

Lots of Modules

• One file per module

• Lots of files:

• Performance Issue

• Async loading?

Page 21: Module, AMD, RequireJS

Complex Dependency

• Load modules by order

• Hard to know the order by head and hand

Page 22: Module, AMD, RequireJS

Solution?

• Not hard to solve

• But there is no standard API

Page 23: Module, AMD, RequireJS

CommonJS

Page 24: Module, AMD, RequireJS

CommonJS

• by Kevin Dangoor

• Volunteers and mailing list

• Unify server side JavaScript API

• Build JavaScript ecosystem

• Not an official organization

Page 25: Module, AMD, RequireJS

CommonJS APIs

• Binary

• Filesystem

• IO

• ...

• Modules

Page 26: Module, AMD, RequireJS
Page 27: Module, AMD, RequireJS

CommonJS Module

• Modules/1.0

• NodeJS

• Modules/AsynchronousDefinition

• AMD

Page 28: Module, AMD, RequireJS

AMD

Page 29: Module, AMD, RequireJS

Asynchronous Module Definition

define(id?, dependencies?, factory);

Page 30: Module, AMD, RequireJS

Exampledefine( 'account', ['service', 'pubsub'], function (service, pubsub) { //do something

//export public APIs return { signin: function () { /* ... */ }, signout: function () { /* ... */ }, getName: function () { /* ... */ }, setName: function () { /* ... */ } }; });

Page 31: Module, AMD, RequireJS

Another Way(function () { //10000 lines of code exports = { signin: function () { /* ... */ }, signout: function () { /* ... */ } }; define('account', function () { return exports; });}());

Page 32: Module, AMD, RequireJS

In jQuery

if ( typeof define === "function" && define.amd && define.amd.jQuery ) { define( "jquery", [], function () { return jQuery; } );}

Page 33: Module, AMD, RequireJS

RequireJS

Page 34: Module, AMD, RequireJS

RequireJS

• AMD Implementation by James Burke

• Async resource loader

• 1.0.8 now, 2.0 under development

Page 35: Module, AMD, RequireJS

Usage

<script data-main="main" src="require.js"></script>

Page 36: Module, AMD, RequireJS

main.jsrequire(["app"], function(app) {

app.init();

});

Page 37: Module, AMD, RequireJS

app.jsdefine(["lib/account", "lib/session"], function (account, session) { //do something

return { init: function () { //init the application } }; });

Page 38: Module, AMD, RequireJS

main.js

account.js

app.js

session.js

crypt.js xhr.js storage.js

Page 39: Module, AMD, RequireJS

Features

• AMD

• Path alias

• Circular dependency

• Plugins

Page 40: Module, AMD, RequireJS

Plugins

• order

• text

• wrap, use

• cs (CoffeeScript)

Page 41: Module, AMD, RequireJS

Advantages

• No pollution to global scope

• Everything is organized in module

• Compile CoffeeScript on the fly

• ...etc

Page 42: Module, AMD, RequireJS

Minefield

• Module load fail: hard to debug

• Wrong path

• Use require function

• Plugin error, ex: CoffeeScript syntax error

Page 43: Module, AMD, RequireJS

Still Problems

• Lots of modules

• Lots of files

• Lots of requests

• Low performance

Page 44: Module, AMD, RequireJS

r.js

Page 45: Module, AMD, RequireJS

r.js

• Optimization tool

• Pack all modules into one file

• Minimize the JavaScript file

Page 46: Module, AMD, RequireJS

Usage

node r.js -o build.js

Page 47: Module, AMD, RequireJS

build.js({ appDir: "../", baseUrl: "scripts", dir: "../../appdirectory-build", modules: [ { name: "main" } ]})

Page 48: Module, AMD, RequireJS

main.js

account.js

app.js

session.js

crypt.js xhr.js storage.js

Page 49: Module, AMD, RequireJS

After Optimized

• require.js are large: 86kb

Page 50: Module, AMD, RequireJS

almond.js

Page 51: Module, AMD, RequireJS

almond.js

• Minimal AMD API implement

• Same author

Page 52: Module, AMD, RequireJS

Advantages

• Small: 9kb, 857 bytes minimized and gzipped

• Stable: no change since 0.0.3

Page 53: Module, AMD, RequireJS

Disadvantages

• No plugin support

• Not a resource downloader

• Lots of restriction

• Different optimize concept

Page 54: Module, AMD, RequireJS

Usage

node r.js -o baseUrl=. name=path/to/almond.js include=main out=main-built.js wrap=true

Page 55: Module, AMD, RequireJS

Tip

• You can use r.js to optimize

• And use almond.js to replace require.js

Page 56: Module, AMD, RequireJS

<script src="almond.js"></script><script src="main-optimized.js"></script>

Page 58: Module, AMD, RequireJS
Page 59: Module, AMD, RequireJS

Questions Time

Page 60: Module, AMD, RequireJS

Q

• I want to use Underscore and Backbone, but they don’t support RequireJS....

Page 61: Module, AMD, RequireJS

A

• Do nothing

• Use use/wrap plugin

• Use modified versionhttps://github.com/jrburke

• Use another script tag to include them first

Page 62: Module, AMD, RequireJS

<script src="undersocre+backbone.js"></script><script src="almond.js"></script><script src="main-optimized.js"></script>

Page 63: Module, AMD, RequireJS

<script src="yepnope.js"></script><script> yepnope({ load: [ "undersocre+backbone.js", "almond.js", "main-optimized.js" ] });</script>

Page 64: Module, AMD, RequireJS

Questions?

Page 65: Module, AMD, RequireJS

Thank You