Talk given at NDC,Oslo - June 2013
RequireJSSebastiano Armeli-Battana@sebarmeliNDC 2013, Oslo (Norway)Thursday, June 13, 13
View Slide
Thursday, June 13, 13
123456Thursday, June 13, 13
app.jsview.jsThursday, June 13, 13
view.js------------Thursday, June 13, 13
app.js------------Thursday, June 13, 13
4646Thursday, June 13, 13
app.js view.jshelpers.jsview2.jshelpers2.jsmodel.jsThursday, June 13, 13
app.js view.jshelpers.jsview2.jshelpers2.jsmodel.js123546Thursday, June 13, 13
app.js view.jshelpers.jsview2.jshelpers2.jsmodel.js123546413256Thursday, June 13, 13
AMDThursday, June 13, 13
var module = (function(){// private variables, methodsvar title = “”;function f1() {}return {// public/privileged methodsgetTitle: function(){return title;}}}()) ;MODULE PATTERNThursday, June 13, 13
define(function () {var title = “”;function f1() {}return {getTitle: function() {return title;}}});RJS MODULE PATTERNThursday, June 13, 13
define(id?, dependencies?, factory)Thursday, June 13, 13
index.htmljs /-- main.js-- helpers.js-- app /-- views /-- view1.js-- vendor /-- require.jsview1.js------------define([‘helpers’],function(helpers){return {init: function(){}}});define(function(){// code here});helpers.js------------Thursday, June 13, 13
define([‘module1’, module2’],function (dep1, dep2) {// do something})Multiple DependenciesThursday, June 13, 13
require(dependencies?, factory)Thursday, June 13, 13
index.html------------data-main=”js/main.js”<br/>main.js<br/>------------<br/>require([‘view1’],function(view1){<br/>view1.init();<br/>});<br/>index.html<br/>js /<br/>-- main.js<br/>-- helpers.js<br/>-- app /<br/>-- views /<br/>-- view1.js<br/>-- vendor /<br/>-- require.js<br/>Thursday, June 13, 13<br/>
main.js------------require.config({baseUrl: ‘./js’,paths: {‘view1’: ‘app/views/view1’}});require([‘view1’],function(view1){view1.init();});index.htmljs /-- main.js-- helpers.js-- app /-- views /-- view1.js-- vendor /-- require.jsThursday, June 13, 13
NO blocking!Thursday, June 13, 13
var node = document.createElement('script');node.async = true;node.setAttribute('data-requirecontext',context.contextName);node.setAttribute('data-requiremodule', moduleName);node.src = url;var head = document.getElementsByTagName('head')[0];head.appendChild(node);Script LoaderThursday, June 13, 13
require() asynchronousde!ne() - de!ne.amdAMDwell suited for browserThursday, June 13, 13
exports.render = function() {};var module = require(‘view1’);NO de!ne()require() synchronousServer-side approachThursday, June 13, 13
Simplified CommonJS Wrapperdefine(function(require, exports, module){// Module required before the callback runsvar helpers = require(‘helpers’);exports.render = function() {helpers.doSomething();}});Thursday, June 13, 13
define([“dep1”], function(require){var helpers = require(‘helpers’);//code here});Thursday, June 13, 13
if ( typeof define === "function" &&define.amd ) {define( "jquery", [], function () {return jQuery;});}Thursday, June 13, 13
index.htmljs /-- main.js-- helpers.js-- app /-- views /-- view1.js-- vendor /-- require.js-- backbone.js-- underscore.js-- jquery.jsmain.js------------require.config({baseUrl: ‘js/vendor’,shim: {‘underscore’:{exports: ‘_’},‘backbone’: {deps: [‘jquery’, ‘underscore’],exports: ‘Backbone’}}});require([‘backbone’],function(Backbone){Backbone.history.start();});Thursday, June 13, 13
LOADER PLUGINS• i18n!, async!, domReady!• text!, css!, json!, cs!, hbs![plugin Module ID]![resource ID]Thursday, June 13, 13
main.js------------require.config({baseUrl: ‘./js’});require([‘text!partials/file.txt’],function(txt) {// txt goes here});index.htmljs /-- main.js-- vendor /-- require.js-- text.js-- partials /-- !le.txtThursday, June 13, 13
main.js------------require.config({baseUrl: ‘./js’});require([‘css!../css/style.css’],function() {// After css is loaded});index.htmljs /-- main.js-- vendor /-- require.js-- css.jscss /-- style.cssThursday, June 13, 13
3 requests!Thursday, June 13, 13
r.jsnpm install -g requirejsOPTIMIZERThursday, June 13, 13
r.js -o tools/build.jsThursday, June 13, 13
build.js------------({appDir:'../',mainConfigFile: '../js/main.js',dir: "../build",modules: [{name: "../main"}]})index.htmljs /-- main.js-- helpers.js-- app /-- views /-- view1.js-- vendor /-- require.jstools /-- build.jsThursday, June 13, 13
build/js/main.js----------------index.htmlbuild /-- index.html-- build.txt-- js /-- main.js-- helpers.js-- app /-- views /-- view1.js-- vendor /-- require.js-- tools /-- build.jsjs/vendor/../main.js----------------js/helpers.jsjs/vendor/view1.jsjs/vendor/../main.jsbuild/build.txt----------------Thursday, June 13, 13
OPTIMIZER1 request!Thursday, June 13, 13
({appDir:'../',mainConfigFile: '../js/main.js',dir: "../build",preserveLicenseComments: false,removeCombined: true,optimize: "uglify2",modules: [{name: "../main",excludeShallow: ["view1"]}]})Thursday, June 13, 13
SOURCE MAPS({// other optionsgenerateSourceMaps: true,optimize: ‘uglify2’})Thursday, June 13, 13
Testingdefine([“view1”], function(view1) {describe(“view1”, function(){it(“should do something”, function(){// expectations});});});Thursday, June 13, 13
runner.html------------runner.htmlspec /-- view1Spec.js-- main.jsjs /-- vendor /-- require.jsdata-main=”spec/main.js”<br/>require.config({<br/>baseUrl: ‘js/vendor’,<br/>paths: {<br/>‘view1’: ...,<br/>‘spec’: ‘../../spec’<br/>}<br/>});<br/>main.js<br/>------------<br/>Thursday, June 13, 13<br/>
runner.htmlspec /-- view1Spec.js-- main.jsjs /-- vendor /-- require.js-- domReady.jsrequire.config({...});require([“domReady!”,“spec/view1Spec”],function(document){jasmine.getEnv().addReporter(new jasmine.HtmlReporter());jasmine.getEnv().execute();});main.js------------Thursday, June 13, 13
GRUNT integration??npm install -g grunt-cliGrunt!leHow to get Grunt?Thursday, June 13, 13
GRUNT integration??grunt-contrib-requirejsnpm install -g grunt-clinpm install grunt-contrib-require-js --save-devGrunt!leHow to get Grunt?Thursday, June 13, 13
module.exports = function(grunt) {var config = require(“build”);grunt.initConfig({requirejs: {compile: {options: config}}grunt.loadNpmTasks('grunt-contrib-requirejs');}Gruntfile.js------------Thursday, June 13, 13
grunt requirejsThursday, June 13, 13
ES6 - ModulesModule de!nitionmodule [module ID]export [variable | function]Module dependencyimport { [var | fn] } from [module ID]Thursday, June 13, 13
ES6 - Modulesmodule “helpers” {}module “view1” {import helpers from “helpers”;exports function init() {...};}Thursday, June 13, 13
RecapThursday, June 13, 13
Recap• ModularityThursday, June 13, 13
Recap• No globals• ModularityThursday, June 13, 13
Recap• Async Script loader• No globals• ModularityThursday, June 13, 13
Recap• Async Script loader• No globals• Optimization• ModularityThursday, June 13, 13
Recap• Async Script loader• Future proof• No globals• Optimization• ModularityThursday, June 13, 13
http://requirejs.comhttps://github.com/asciidisco/grunt-requirejs@sebarmelihttps://github.com/amdjs/amdjs-api/wiki/AMDhttp://wiki.ecmascript.org/doku.php?id=harmony:modulesThursday, June 13, 13