SlideShare a Scribd company logo
Dependencies & Modules

Wednesday, January 8, 14

To handle dependencies and modules in a simple way we need some proper tooling.
Wednesday, January 8, 14

Then talk a bit about Browserify.
Wednesday, January 8, 14

I’ve been writing JS for quite a while, then I was off doing mostly backend & Android for while.
This is Theo, I felt like him here towards JS for a while I feel that the tools around for JS has increased and grown in complexity quite fast. It also feels like it is
changing quite rapid. This is also what attracts me to JS, for me it feels like this is where a lot of creativity and innovation is happening.
But picking the right tools is a/has been challenge.
Web Sites vs Web Apps
What’s the difference?

Wednesday, January 8, 14

I find this quite interesting. And is there a difference and why do we make a difference?
We’re all building sites that people visit, do
something, and leave. Differentiating websites vs. web
apps is no good to anyone.
– Jack Franklin
https://speakerdeck.com/jackfranklin/port80-practical-javascripting

Wednesday, January 8, 14
Why do you want to make that distinction?
What benefit do you gain by arbitrarily dividing
the entire web into two classes?
– Jeremy Keith
http://adactio.com/journal/6246/

Wednesday, January 8, 14
A lot of people ignore new JavaScript tools, methods
or approaches because those are just for “web apps.”
– Jack Franklin
https://speakerdeck.com/jackfranklin/port80-practical-javascripting

Wednesday, January 8, 14

I’ve done this for too long.
Dev Environment
•

Module System: A way to programmatically load scripts when they’re
needed.

•

Package Manager: Fetch scripts from online sources like GitHub, taking
dependencies into account.

•

Build Tool: Combine scripts and other assets together into something
usable by browsers.
http://dailyjs.com/2013/01/28/components/

Wednesday, January 8, 14

And to handle modules and dependencies properly we need to use proper tools to cope with a modern development environment
Modules
A way to programmatically load scripts when they’re needed

Wednesday, January 8, 14

Let’s start with modules.
What is a module? Keep it simple, it’s basically just a script that we can load whenever we need it.
<script
<script
<script
<script
<script
<script
<script
<script
<script
<script

type="text/javascript"
type="text/javascript"
type="text/javascript"
type="text/javascript"
type="text/javascript"
type="text/javascript"
type="text/javascript"
type="text/javascript"
type="text/javascript"
type="text/javascript"

src="/js/namespace.js"></script>
src="/js/vendor/buffer-loader.js"></script>
src="/js/vendor/requestanimframe.js"></script>
src="/js/vendor/stats.min.js"></script>
src="/js/vendor/minpubsub.js"></script>
src="/js/app.js"></script>
src="/js/utils.js"></script>
src="/js/sound.js"></script>
src="/js/shape.js"></script>
src="/js/main.js"></script>

Wednesday, January 8, 14

We can easily do this by separating our code into various scripts. It gets a bit troublesome to manage this though. For me this way hinders me from playing
around and prototyping and testing things out while developing.
SRC_DIR = src
BUILD_DIR = build
JS_SERVER_FILES = $(SRC_DIR)/js/namespace.js
! $(SRC_DIR)/js/vendor/buffer-loader.js
! $(SRC_DIR)/js/vendor/requestanimframe.js
! $(SRC_DIR)/js/vendor/stats.min.js
! $(SRC_DIR)/js/vendor/minpubsub.js
! $(SRC_DIR)/js/app.js
! $(SRC_DIR)/js/utils.js
! $(SRC_DIR)/js/sound.js
! $(SRC_DIR)/js/shape.js
! $(SRC_DIR)/js/main.js
JS_BUNDLE = $(BUILD_DIR)/app.js
BUILD_BUNDLE = $(BUILD_DIR)/app-min.js
.DEFAULT_GOAL := all
all: bundle
! java -jar $(GCC_COMPRESSOR) $(GCC_OPTION) --js=$(JS_BUNDLE) -js_output_file=$(BUILD_BUNDLE)
debug: bundle
! cat $(JS_FILES) >> $(JS_BUNDLE)
Wednesday, January 8, 14

To assemble this for production we would need a build script. This is a Makefile from an old project of mine. Sure we can have grunt but it is still configuration
clean:
we need to add.

! rm -Rf $(BUILD_DIR)/*

For me this isn’t really prototyping friendly.
<% if (production) { %>
<script type="text/javascript"
<% } else { %>
<script type="text/javascript"
<script type="text/javascript"
<script type="text/javascript"
<script type="text/javascript"
<script type="text/javascript"
<script type="text/javascript"
<script type="text/javascript"
<script type="text/javascript"
<script type="text/javascript"
<script type="text/javascript"
<% } %>

src="/js/app-min.js"></script>
src="/js/namespace.js"></script>
src="/js/vendor/buffer-loader.js"></script>
src="/js/vendor/requestanimframe.js"></script>
src="/js/vendor/stats.min.js"></script>
src="/js/vendor/minpubsub.js"></script>
src="/js/app.js"></script>
src="/js/utils.js"></script>
src="/js/sound.js"></script>
src="/js/shape.js"></script>
src="/js/main.js"></script>

Wednesday, January 8, 14

And we add a conditional to check if we are in production. Personally I don’t like this since it means that we’re during development will most likely run a different
version of the site than we will in production.
The Problem
•
•
•
•

Code complexity grows as the site gets bigger
Assembly gets harder
Developer wants discrete JS files/modules
Deployment wants optimized code in just one or a few HTTP calls

http://requirejs.org/docs/why.html#1
Wednesday, January 8, 14

Why do we want modules. Require.JS outlines a few arguments on there website.
We basically want it because we need better structure in our code.
Current Landscape
•
•
•
•
•
•

Globals
Globals + Namespace
AMD (Asynchronous Module Definition)
CommonJS
UMD (Universal Module Definition)
(ES6)

Wednesday, January 8, 14

Alternatives for modules, not taking framework specific ones like Angular into account.
var isEven = function(i) {
return i % 2 === 0;
};

Wednesday, January 8, 14

I like small bits of code that can be separated and re-used. Here’s a quite simple re-usable bit of code but is short enough to fit a slide.
Simple re-usable code
Globals

Wednesday, January 8, 14
even.js

var isEven = function(i) {
return i % 2 === 0;
};

Wednesday, January 8, 14
app.js
console.log(1,
console.log(2,
console.log(3,
console.log(4,

Wednesday, January 8, 14

isEven(1));
isEven(2));
isEven(3));
isEven(4));
index.html
<!doctype html>
<script src="even.js"></script>
<script src="app.js"></script>

Wednesday, January 8, 14
Globals + Namespace

Wednesday, January 8, 14
app-even.js
var App = App || {};
App.isEven = function(i) {
return i % 2 === 0;
};

Wednesday, January 8, 14
app.js
var App = App || {};
console.log(1,
console.log(2,
console.log(3,
console.log(4,

Wednesday, January 8, 14

App.isEven(1));
App.isEven(2));
App.isEven(3));
App.isEven(4));
index.html

<!doctype html>
<script src="app-even.js"></script>
<script src="app.js"></script>

Wednesday, January 8, 14
AMD
Asynchronous Module Definition
With Require.JS

Wednesday, January 8, 14
even.js
define([], function() {
var isEven = function(i) {
return i % 2 === 0;
};
return isEven;
});

Wednesday, January 8, 14
app.js
require(['even'], function(even){
console.log(1, even(1));
console.log(2, even(2));
console.log(3, even(3));
console.log(4, even(4));
});

Wednesday, January 8, 14
index.html

<!doctype html>
<script data-main="js/app.js"
src="js/require.js"></script>

Wednesday, January 8, 14
//Allow for anonymous modules
if (typeof name !== 'string') {
//Adjust args appropriately
callback = deps;
deps = name;
name = null;
}
//This module may not have dependencies
if (!isArray(deps)) {
callback = deps;
deps = null;
}

require.js

//If no name, and callback is a function, then figure out if it a
//CommonJS thing with dependencies.
if (!deps && isFunction(callback)) {
deps = [];
//Remove comments from the callback string,
//look for require calls, and pull them into the dependencies,
//but only if there are function args.
if (callback.length) {
callback
.toString()
.replace(commentRegExp, '')
.replace(cjsRequireRegExp, function (match, dep) {
deps.push(dep);
});

//May be a CommonJS thing even without require calls, but still
//could use exports, and module. Avoid doing exports and module
//work though if it just needs require.
//REQUIRES the function to expect the CommonJS variables in the
//order listed below.
deps = (callback.length === 1 ? ['require'] : ['require', 'exports', 'module']).concat(deps);
}
}
//If in IE 6-8 and hit an anonymous define() call, do the interactive
//work.
if (useInteractive) {
node = currentlyAddingScript || getInteractiveScript();
if (node) {
if (!name) {
name = node.getAttribute('data-requiremodule');
}
context = contexts[node.getAttribute('data-requirecontext')];
}
}
//Always save off evaluating the def call until the script onload handler.
//This allows multiple modules to be in a file without prematurely
//tracing dependencies, and allows for anonymous module support,
//where the module name is not known until the script onload event
//occurs. If no context, use the global queue, and get it processed
//in the onscript load callback.
(context ? context.defQueue : globalDefQueue).push([name, deps, callback]);
};
define.amd = {
jQuery: true
};

Wednesday, January 8, 14

/**
* Executes the text. Normally just uses eval, but can be modified
* to use a better, environment-specific call. Only used for transpiling
* loader plugins, not for plain JS modules.
* @param {String} text the text to execute/evaluate.
*/
req.exec = function (text) {
/*jslint evil: true */
return eval(text);
};

Quite a massive file that is required //Set load these files. Not sure exactly what goes on here, but it works.
to up with config info.
req(cfg);
}(this));
Makefile / Build step

build:
! node r.js -o name=app out=js/app-built.js baseUrl=./js
build-even:
! node r.js -o name=even out=js/even-built.js baseUrl=./js

Wednesday, January 8, 14

For production you might want to bundle your files into one bundle. You still depend on require.js though. And you will have one setup for development and another one
for production.
CommonJS / Node.js

Wednesday, January 8, 14
even.js
var isEven = function(i) {
return i % 2 === 0;
};
module.exports = isEven;

Wednesday, January 8, 14
app.js
var isEven = require('./even');
console.log(1,
console.log(2,
console.log(3,
console.log(4,

Wednesday, January 8, 14

isEven(1));
isEven(2));
isEven(3));
isEven(4));
UMD
Universal Module Definition

Wednesday, January 8, 14
var shim = {};
if (typeof(exports) === 'undefined') {
if(typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
// we are in amd.
shim.exports = {};
define(function() {
return shim.exports;
});
} else {
// we are in a browser, define its namespaces in global
shim.exports = typeof(window) !== 'undefined' ? window : _global;
}
}
else {
// we are in commonjs, define its namespaces in exports
shim.exports = exports;
}

even-lib.js

(function(exports) {

var isEven = function(i) {
return i % 2 === 0;
};

if (typeof(exports) !== 'undefined') {
exports.isEven = isEven;
}
})(shim.exports);
})(this);

header.js

Wednesday, January 8, 14

This approach has been quite popular for library developers to be able to meet end users requirements.
var shim = {};
if (typeof(exports) === 'undefined') {
if(typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
// we are in amd.
shim.exports = {};
define(function() {
return shim.exports;
});
} else {
// we are in a browser, define its namespaces in global
shim.exports = typeof(window) !== 'undefined' ? window : _global;
}
}
else {
// we are in commonjs, define its namespaces in exports
shim.exports = exports;
}

even-lib.js

header.js

(function(exports) {

even.js

footer.js
header.js

var isEven = function(i) {
return i % 2 === 0;
};

if (typeof(exports) !== 'undefined') {
exports.isEven = isEven;
}
})(shim.exports);
})(this);

Wednesday, January 8, 14

This approach has been quite popular for library developers to be able to meet end users requirements.
Makefile / Build step
build:
! cat header.js even.js footer.js > even-lib.js

Wednesday, January 8, 14
ES6
export function isEven() {}
import { isEven } from 'even';

Wednesday, January 8, 14

It’s not here yet.
AMD & CommonJS

Wednesday, January 8, 14

For me, there’s really only two options here. AMD or CommonJS. Both of these solves the issue of loading modules.
Wednesday, January 8, 14

Various alternatives around for common js, as far as I know there is only require js for AMD
CommonJS

Wednesday, January 8, 14

Various alternatives around for common js, as far as I know there is only require js for AMD
CommonJS

AMD

Wednesday, January 8, 14

Various alternatives around for common js, as far as I know there is only require js for AMD
CommonJS

AMD

Wednesday, January 8, 14

Various alternatives around for common js, as far as I know there is only require js for AMD
What I want
•
•
•
•
•
Wednesday, January 8, 14

Simple
Active community
No complicated build environment
Works with existing libraries, with none or minimal adaption
Prototype friendly
require('modules') in the browser

Wednesday, January 8, 14

http://browserify.org/, substack
Demo

Wednesday, January 8, 14
Browserify
•
•
•

Wednesday, January 8, 14

require & npm modules in the browser
Browser versions of core node modules (events, stream, path, url, ...)
Extendable
How does it work?
•
•
•
•
Wednesday, January 8, 14

Small wrapper for the require function
Build process that keeps track of dependencies
Bundles to one file
No global leakage
;
(function e(t, n, r) {
function s(o, u) {
if (!n[o]) {
if (!t[o]) {
var a = typeof require == "function" && require;
if (!u && a) return a(o, !0);
if (i) return i(o, !0);
throw new Error("Cannot find module '" + o + "'")
}
var f = n[o] = {
exports: {}
};
t[o][0].call(f.exports, function (e) {
var n = t[o][1][e];
return s(n ? n : e)
}, f, f.exports, e, t, n, r)
}
return n[o].exports
}
var i = typeof require == "function" && require;
for (var o = 0; o < r.length; o++) s(r[o]);
return s
})({
1: [
function (require, module, exports) {
var isEven = function (i) {
return i % 2 === 0;
};
module.exports = isEven;
}, {}
],
2: [
function (require, module, exports) {
var isEven = require('./even');
console.log(isEven(2));
}, {
"./even": 1
}
]
}, {}, [2]);

Wednesday, January 8, 14
voxel.js
http://voxeljs.com/

Wednesday, January 8, 14
Dependencies
Package Manager
Fetch scripts, taking dependencies into account

Wednesday, January 8, 14
Current Landscape
•
•
•
•
•
•

Ender (http://ender.jit.su/)
Volo (http://volojs.org/)
Jam (http://jamjs.org/)
Bower (http://bower.io/) 7 000+
Component (http://component.io/)
npm (http://npmjs.org) 53 000+

Wednesday, January 8, 14

Quite a few alternatives around. Not likely that all of these will survive. Currently it seems like Bower is the one getting more and more attraction for front end
developers
Transformations
•
•
•
•
•

AMD via deamdify
Bower via debowerify
Global via deglobalify
ES6 via es6ify
& more

Wednesday, January 8, 14
{
"name": "bower-demo",
"version": "0.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo "Error: no test specified" && exit 1"
},
"author": "Johan Nilsson",
"license": "BSD-2-Clause",
"devDependencies": {
"debowerify": "~0.5.1"
}
}

Wednesday, January 8, 14
{
"name": "bower-demo",
"main": "index.js",
"version": "0.0.0",
"authors": [
"Johan Nilsson <johan@markupartist.com>"
],
"license": "BSD-2-Clause",
"private": true,
"dependencies": {
"jquery": "~2.0.3"
}
}

Wednesday, January 8, 14
var $ = require('jquery');
$('body').append('<p>bla bla</p>');

Wednesday, January 8, 14
browserify index.js -t debowerify > bundle.js

Wednesday, January 8, 14
Additional Tools
•
•
•
•
Wednesday, January 8, 14

Watchify – Watch mode for browserify builds
Beefy – Local development server
grunt-browserify
gulp-browserify
Johan Nilsson
johan@markupartist.com
@johanni

Wednesday, January 8, 14

More Related Content

PDF
Browserify
PDF
Lightning Talk: Making JS better with Browserify
PDF
Requirejs
PDF
Integrating Browserify with Sprockets
KEY
Requirejs
PPSX
RequireJS
PPT
Managing JavaScript Dependencies With RequireJS
PDF
Packing it all: JavaScript module bundling from 2000 to now
Browserify
Lightning Talk: Making JS better with Browserify
Requirejs
Integrating Browserify with Sprockets
Requirejs
RequireJS
Managing JavaScript Dependencies With RequireJS
Packing it all: JavaScript module bundling from 2000 to now

What's hot (20)

PPTX
An Intro into webpack
PDF
PPTX
Asynchronous Module Definition (AMD) used for Dependency Injection (DI) and MVVM
PPTX
uRequire@greecejs: An introduction to http://uRequire.org
PPTX
Webpack Introduction
PDF
Javascript ui for rest services
PDF
Once upon a time, there were css, js and server-side rendering
PDF
Vue 淺談前端建置工具
PDF
Webpack Tutorial, Uppsala JS
PDF
Module, AMD, RequireJS
PPTX
Backbone.js
PDF
Building Isomorphic Apps (JSConf.Asia 2014)
PPTX
Webpack
PDF
Asynchronous Module Definition (AMD)
PDF
JSConf US 2014: Building Isomorphic Apps
PDF
Webpack DevTalk
PDF
Developing large scale JavaScript applications
PDF
Vue.js is boring - and that's a good thing
PDF
Backbone.js
PDF
Grunt.js and Yeoman, Continous Integration
An Intro into webpack
Asynchronous Module Definition (AMD) used for Dependency Injection (DI) and MVVM
uRequire@greecejs: An introduction to http://uRequire.org
Webpack Introduction
Javascript ui for rest services
Once upon a time, there were css, js and server-side rendering
Vue 淺談前端建置工具
Webpack Tutorial, Uppsala JS
Module, AMD, RequireJS
Backbone.js
Building Isomorphic Apps (JSConf.Asia 2014)
Webpack
Asynchronous Module Definition (AMD)
JSConf US 2014: Building Isomorphic Apps
Webpack DevTalk
Developing large scale JavaScript applications
Vue.js is boring - and that's a good thing
Backbone.js
Grunt.js and Yeoman, Continous Integration
Ad

Viewers also liked (14)

PDF
CommonJSの話
PDF
Get Pumped for the HTML 5 Gamepad API
PDF
Web development tools { starter pack }
PDF
1st npm
PDF
Designing Modules for the Browser and Node with Browserify
PDF
npm + browserify
PPTX
Don't Be Afraid of Abstract Syntax Trees
PDF
Building testable chrome extensions
PDF
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
PDF
System webpack-jspm
PDF
Modern UI Development With Node.js
PDF
EMOCON 2015 - Jspm & systemjs
PDF
Gulp入門 - コーディングを10倍速くする
PDF
reveal.js 3.0.0
CommonJSの話
Get Pumped for the HTML 5 Gamepad API
Web development tools { starter pack }
1st npm
Designing Modules for the Browser and Node with Browserify
npm + browserify
Don't Be Afraid of Abstract Syntax Trees
Building testable chrome extensions
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
System webpack-jspm
Modern UI Development With Node.js
EMOCON 2015 - Jspm & systemjs
Gulp入門 - コーディングを10倍速くする
reveal.js 3.0.0
Ad

Similar to JavaScript Dependencies, Modules & Browserify (20)

PDF
Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...
PDF
Introduction to node.js by Ran Mizrahi @ Reversim Summit
PPTX
PDF
Node JS Express: Steps to Create Restful Web App
PDF
node.js 실무 - node js in practice by Jesang Yoon
PDF
Voorhoede - Front-end architecture
PPTX
Javascript Frameworks Comparison - Angular, Knockout, Ember and Backbone
PDF
TDC2017 | Florianopolis - Trilha DevOps How we figured out we had a SRE team ...
DOCX
Bhanu Resume
PDF
PHP Unit Testing in Yii
PDF
Full Stack React Workshop [CSSC x GDSC]
PDF
Isomorphic JavaScript: #DevBeat Master Class
PDF
CodeFest 2014. Пухальский И. — Отзывчивые кроссплатформенные веб-приложения
PDF
Intro to React - Featuring Modern JavaScript
PDF
Max Voloshin - "Organization of frontend development for products with micros...
PDF
AngularJS - Overcoming performance issues. Limits.
PDF
Dragos Rusu - Angular JS - Overcoming Performance Issues - CodeCamp-10-may-2014
PDF
WebNet Conference 2012 - Designing complex applications using html5 and knock...
PDF
Refactor Large applications with Backbone
PDF
Refactor Large apps with Backbone
Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...
Introduction to node.js by Ran Mizrahi @ Reversim Summit
Node JS Express: Steps to Create Restful Web App
node.js 실무 - node js in practice by Jesang Yoon
Voorhoede - Front-end architecture
Javascript Frameworks Comparison - Angular, Knockout, Ember and Backbone
TDC2017 | Florianopolis - Trilha DevOps How we figured out we had a SRE team ...
Bhanu Resume
PHP Unit Testing in Yii
Full Stack React Workshop [CSSC x GDSC]
Isomorphic JavaScript: #DevBeat Master Class
CodeFest 2014. Пухальский И. — Отзывчивые кроссплатформенные веб-приложения
Intro to React - Featuring Modern JavaScript
Max Voloshin - "Organization of frontend development for products with micros...
AngularJS - Overcoming performance issues. Limits.
Dragos Rusu - Angular JS - Overcoming Performance Issues - CodeCamp-10-may-2014
WebNet Conference 2012 - Designing complex applications using html5 and knock...
Refactor Large applications with Backbone
Refactor Large apps with Backbone

More from Johan Nilsson (11)

PDF
Utmaningar som tredjepartsutvecklare för kollektivtrafikbranchen - Kollektivt...
PDF
GTFS & OSM in STHLM Traveling at Trafiklab
PDF
STHLM Traveling Trafiklab
PDF
Spacebrew & Arduino Yún
PDF
Trafiklab 1206
PDF
Custom UI Components at Android Only 2011
PPT
new Android UI Patterns
PDF
FOSS STHLM Android Cloud to Device Messaging
PDF
Android Cloud to Device Messaging Framework at GTUG Stockholm
PDF
Android swedroid
PPT
GTUG Android iglaset Presentation 1 Oct
Utmaningar som tredjepartsutvecklare för kollektivtrafikbranchen - Kollektivt...
GTFS & OSM in STHLM Traveling at Trafiklab
STHLM Traveling Trafiklab
Spacebrew & Arduino Yún
Trafiklab 1206
Custom UI Components at Android Only 2011
new Android UI Patterns
FOSS STHLM Android Cloud to Device Messaging
Android Cloud to Device Messaging Framework at GTUG Stockholm
Android swedroid
GTUG Android iglaset Presentation 1 Oct

Recently uploaded (20)

PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PPTX
Understanding_Digital_Forensics_Presentation.pptx
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PDF
Bridging biosciences and deep learning for revolutionary discoveries: a compr...
PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
PDF
Electronic commerce courselecture one. Pdf
PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PDF
KodekX | Application Modernization Development
PDF
Machine learning based COVID-19 study performance prediction
PDF
Approach and Philosophy of On baking technology
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PDF
CIFDAQ's Market Insight: SEC Turns Pro Crypto
PDF
Encapsulation_ Review paper, used for researhc scholars
PDF
Modernizing your data center with Dell and AMD
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PPTX
A Presentation on Artificial Intelligence
PPT
Teaching material agriculture food technology
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
Understanding_Digital_Forensics_Presentation.pptx
Digital-Transformation-Roadmap-for-Companies.pptx
Bridging biosciences and deep learning for revolutionary discoveries: a compr...
“AI and Expert System Decision Support & Business Intelligence Systems”
Electronic commerce courselecture one. Pdf
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
KodekX | Application Modernization Development
Machine learning based COVID-19 study performance prediction
Approach and Philosophy of On baking technology
Agricultural_Statistics_at_a_Glance_2022_0.pdf
CIFDAQ's Market Insight: SEC Turns Pro Crypto
Encapsulation_ Review paper, used for researhc scholars
Modernizing your data center with Dell and AMD
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
A Presentation on Artificial Intelligence
Teaching material agriculture food technology

JavaScript Dependencies, Modules & Browserify

  • 1. Dependencies & Modules Wednesday, January 8, 14 To handle dependencies and modules in a simple way we need some proper tooling.
  • 2. Wednesday, January 8, 14 Then talk a bit about Browserify.
  • 3. Wednesday, January 8, 14 I’ve been writing JS for quite a while, then I was off doing mostly backend & Android for while. This is Theo, I felt like him here towards JS for a while I feel that the tools around for JS has increased and grown in complexity quite fast. It also feels like it is changing quite rapid. This is also what attracts me to JS, for me it feels like this is where a lot of creativity and innovation is happening. But picking the right tools is a/has been challenge.
  • 4. Web Sites vs Web Apps What’s the difference? Wednesday, January 8, 14 I find this quite interesting. And is there a difference and why do we make a difference?
  • 5. We’re all building sites that people visit, do something, and leave. Differentiating websites vs. web apps is no good to anyone. – Jack Franklin https://speakerdeck.com/jackfranklin/port80-practical-javascripting Wednesday, January 8, 14
  • 6. Why do you want to make that distinction? What benefit do you gain by arbitrarily dividing the entire web into two classes? – Jeremy Keith http://adactio.com/journal/6246/ Wednesday, January 8, 14
  • 7. A lot of people ignore new JavaScript tools, methods or approaches because those are just for “web apps.” – Jack Franklin https://speakerdeck.com/jackfranklin/port80-practical-javascripting Wednesday, January 8, 14 I’ve done this for too long.
  • 8. Dev Environment • Module System: A way to programmatically load scripts when they’re needed. • Package Manager: Fetch scripts from online sources like GitHub, taking dependencies into account. • Build Tool: Combine scripts and other assets together into something usable by browsers. http://dailyjs.com/2013/01/28/components/ Wednesday, January 8, 14 And to handle modules and dependencies properly we need to use proper tools to cope with a modern development environment
  • 9. Modules A way to programmatically load scripts when they’re needed Wednesday, January 8, 14 Let’s start with modules. What is a module? Keep it simple, it’s basically just a script that we can load whenever we need it.
  • 10. <script <script <script <script <script <script <script <script <script <script type="text/javascript" type="text/javascript" type="text/javascript" type="text/javascript" type="text/javascript" type="text/javascript" type="text/javascript" type="text/javascript" type="text/javascript" type="text/javascript" src="/js/namespace.js"></script> src="/js/vendor/buffer-loader.js"></script> src="/js/vendor/requestanimframe.js"></script> src="/js/vendor/stats.min.js"></script> src="/js/vendor/minpubsub.js"></script> src="/js/app.js"></script> src="/js/utils.js"></script> src="/js/sound.js"></script> src="/js/shape.js"></script> src="/js/main.js"></script> Wednesday, January 8, 14 We can easily do this by separating our code into various scripts. It gets a bit troublesome to manage this though. For me this way hinders me from playing around and prototyping and testing things out while developing.
  • 11. SRC_DIR = src BUILD_DIR = build JS_SERVER_FILES = $(SRC_DIR)/js/namespace.js ! $(SRC_DIR)/js/vendor/buffer-loader.js ! $(SRC_DIR)/js/vendor/requestanimframe.js ! $(SRC_DIR)/js/vendor/stats.min.js ! $(SRC_DIR)/js/vendor/minpubsub.js ! $(SRC_DIR)/js/app.js ! $(SRC_DIR)/js/utils.js ! $(SRC_DIR)/js/sound.js ! $(SRC_DIR)/js/shape.js ! $(SRC_DIR)/js/main.js JS_BUNDLE = $(BUILD_DIR)/app.js BUILD_BUNDLE = $(BUILD_DIR)/app-min.js .DEFAULT_GOAL := all all: bundle ! java -jar $(GCC_COMPRESSOR) $(GCC_OPTION) --js=$(JS_BUNDLE) -js_output_file=$(BUILD_BUNDLE) debug: bundle ! cat $(JS_FILES) >> $(JS_BUNDLE) Wednesday, January 8, 14 To assemble this for production we would need a build script. This is a Makefile from an old project of mine. Sure we can have grunt but it is still configuration clean: we need to add. ! rm -Rf $(BUILD_DIR)/* For me this isn’t really prototyping friendly.
  • 12. <% if (production) { %> <script type="text/javascript" <% } else { %> <script type="text/javascript" <script type="text/javascript" <script type="text/javascript" <script type="text/javascript" <script type="text/javascript" <script type="text/javascript" <script type="text/javascript" <script type="text/javascript" <script type="text/javascript" <script type="text/javascript" <% } %> src="/js/app-min.js"></script> src="/js/namespace.js"></script> src="/js/vendor/buffer-loader.js"></script> src="/js/vendor/requestanimframe.js"></script> src="/js/vendor/stats.min.js"></script> src="/js/vendor/minpubsub.js"></script> src="/js/app.js"></script> src="/js/utils.js"></script> src="/js/sound.js"></script> src="/js/shape.js"></script> src="/js/main.js"></script> Wednesday, January 8, 14 And we add a conditional to check if we are in production. Personally I don’t like this since it means that we’re during development will most likely run a different version of the site than we will in production.
  • 13. The Problem • • • • Code complexity grows as the site gets bigger Assembly gets harder Developer wants discrete JS files/modules Deployment wants optimized code in just one or a few HTTP calls http://requirejs.org/docs/why.html#1 Wednesday, January 8, 14 Why do we want modules. Require.JS outlines a few arguments on there website. We basically want it because we need better structure in our code.
  • 14. Current Landscape • • • • • • Globals Globals + Namespace AMD (Asynchronous Module Definition) CommonJS UMD (Universal Module Definition) (ES6) Wednesday, January 8, 14 Alternatives for modules, not taking framework specific ones like Angular into account.
  • 15. var isEven = function(i) { return i % 2 === 0; }; Wednesday, January 8, 14 I like small bits of code that can be separated and re-used. Here’s a quite simple re-usable bit of code but is short enough to fit a slide. Simple re-usable code
  • 17. even.js var isEven = function(i) { return i % 2 === 0; }; Wednesday, January 8, 14
  • 19. index.html <!doctype html> <script src="even.js"></script> <script src="app.js"></script> Wednesday, January 8, 14
  • 21. app-even.js var App = App || {}; App.isEven = function(i) { return i % 2 === 0; }; Wednesday, January 8, 14
  • 22. app.js var App = App || {}; console.log(1, console.log(2, console.log(3, console.log(4, Wednesday, January 8, 14 App.isEven(1)); App.isEven(2)); App.isEven(3)); App.isEven(4));
  • 23. index.html <!doctype html> <script src="app-even.js"></script> <script src="app.js"></script> Wednesday, January 8, 14
  • 24. AMD Asynchronous Module Definition With Require.JS Wednesday, January 8, 14
  • 25. even.js define([], function() { var isEven = function(i) { return i % 2 === 0; }; return isEven; }); Wednesday, January 8, 14
  • 26. app.js require(['even'], function(even){ console.log(1, even(1)); console.log(2, even(2)); console.log(3, even(3)); console.log(4, even(4)); }); Wednesday, January 8, 14
  • 28. //Allow for anonymous modules if (typeof name !== 'string') { //Adjust args appropriately callback = deps; deps = name; name = null; } //This module may not have dependencies if (!isArray(deps)) { callback = deps; deps = null; } require.js //If no name, and callback is a function, then figure out if it a //CommonJS thing with dependencies. if (!deps && isFunction(callback)) { deps = []; //Remove comments from the callback string, //look for require calls, and pull them into the dependencies, //but only if there are function args. if (callback.length) { callback .toString() .replace(commentRegExp, '') .replace(cjsRequireRegExp, function (match, dep) { deps.push(dep); }); //May be a CommonJS thing even without require calls, but still //could use exports, and module. Avoid doing exports and module //work though if it just needs require. //REQUIRES the function to expect the CommonJS variables in the //order listed below. deps = (callback.length === 1 ? ['require'] : ['require', 'exports', 'module']).concat(deps); } } //If in IE 6-8 and hit an anonymous define() call, do the interactive //work. if (useInteractive) { node = currentlyAddingScript || getInteractiveScript(); if (node) { if (!name) { name = node.getAttribute('data-requiremodule'); } context = contexts[node.getAttribute('data-requirecontext')]; } } //Always save off evaluating the def call until the script onload handler. //This allows multiple modules to be in a file without prematurely //tracing dependencies, and allows for anonymous module support, //where the module name is not known until the script onload event //occurs. If no context, use the global queue, and get it processed //in the onscript load callback. (context ? context.defQueue : globalDefQueue).push([name, deps, callback]); }; define.amd = { jQuery: true }; Wednesday, January 8, 14 /** * Executes the text. Normally just uses eval, but can be modified * to use a better, environment-specific call. Only used for transpiling * loader plugins, not for plain JS modules. * @param {String} text the text to execute/evaluate. */ req.exec = function (text) { /*jslint evil: true */ return eval(text); }; Quite a massive file that is required //Set load these files. Not sure exactly what goes on here, but it works. to up with config info. req(cfg); }(this));
  • 29. Makefile / Build step build: ! node r.js -o name=app out=js/app-built.js baseUrl=./js build-even: ! node r.js -o name=even out=js/even-built.js baseUrl=./js Wednesday, January 8, 14 For production you might want to bundle your files into one bundle. You still depend on require.js though. And you will have one setup for development and another one for production.
  • 31. even.js var isEven = function(i) { return i % 2 === 0; }; module.exports = isEven; Wednesday, January 8, 14
  • 32. app.js var isEven = require('./even'); console.log(1, console.log(2, console.log(3, console.log(4, Wednesday, January 8, 14 isEven(1)); isEven(2)); isEven(3)); isEven(4));
  • 34. var shim = {}; if (typeof(exports) === 'undefined') { if(typeof define == 'function' && typeof define.amd == 'object' && define.amd) { // we are in amd. shim.exports = {}; define(function() { return shim.exports; }); } else { // we are in a browser, define its namespaces in global shim.exports = typeof(window) !== 'undefined' ? window : _global; } } else { // we are in commonjs, define its namespaces in exports shim.exports = exports; } even-lib.js (function(exports) { var isEven = function(i) { return i % 2 === 0; }; if (typeof(exports) !== 'undefined') { exports.isEven = isEven; } })(shim.exports); })(this); header.js Wednesday, January 8, 14 This approach has been quite popular for library developers to be able to meet end users requirements.
  • 35. var shim = {}; if (typeof(exports) === 'undefined') { if(typeof define == 'function' && typeof define.amd == 'object' && define.amd) { // we are in amd. shim.exports = {}; define(function() { return shim.exports; }); } else { // we are in a browser, define its namespaces in global shim.exports = typeof(window) !== 'undefined' ? window : _global; } } else { // we are in commonjs, define its namespaces in exports shim.exports = exports; } even-lib.js header.js (function(exports) { even.js footer.js header.js var isEven = function(i) { return i % 2 === 0; }; if (typeof(exports) !== 'undefined') { exports.isEven = isEven; } })(shim.exports); })(this); Wednesday, January 8, 14 This approach has been quite popular for library developers to be able to meet end users requirements.
  • 36. Makefile / Build step build: ! cat header.js even.js footer.js > even-lib.js Wednesday, January 8, 14
  • 37. ES6 export function isEven() {} import { isEven } from 'even'; Wednesday, January 8, 14 It’s not here yet.
  • 38. AMD & CommonJS Wednesday, January 8, 14 For me, there’s really only two options here. AMD or CommonJS. Both of these solves the issue of loading modules.
  • 39. Wednesday, January 8, 14 Various alternatives around for common js, as far as I know there is only require js for AMD
  • 40. CommonJS Wednesday, January 8, 14 Various alternatives around for common js, as far as I know there is only require js for AMD
  • 41. CommonJS AMD Wednesday, January 8, 14 Various alternatives around for common js, as far as I know there is only require js for AMD
  • 42. CommonJS AMD Wednesday, January 8, 14 Various alternatives around for common js, as far as I know there is only require js for AMD
  • 43. What I want • • • • • Wednesday, January 8, 14 Simple Active community No complicated build environment Works with existing libraries, with none or minimal adaption Prototype friendly
  • 44. require('modules') in the browser Wednesday, January 8, 14 http://browserify.org/, substack
  • 46. Browserify • • • Wednesday, January 8, 14 require & npm modules in the browser Browser versions of core node modules (events, stream, path, url, ...) Extendable
  • 47. How does it work? • • • • Wednesday, January 8, 14 Small wrapper for the require function Build process that keeps track of dependencies Bundles to one file No global leakage
  • 48. ; (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { var a = typeof require == "function" && require; if (!u && a) return a(o, !0); if (i) return i(o, !0); throw new Error("Cannot find module '" + o + "'") } var f = n[o] = { exports: {} }; t[o][0].call(f.exports, function (e) { var n = t[o][1][e]; return s(n ? n : e) }, f, f.exports, e, t, n, r) } return n[o].exports } var i = typeof require == "function" && require; for (var o = 0; o < r.length; o++) s(r[o]); return s })({ 1: [ function (require, module, exports) { var isEven = function (i) { return i % 2 === 0; }; module.exports = isEven; }, {} ], 2: [ function (require, module, exports) { var isEven = require('./even'); console.log(isEven(2)); }, { "./even": 1 } ] }, {}, [2]); Wednesday, January 8, 14
  • 50. Dependencies Package Manager Fetch scripts, taking dependencies into account Wednesday, January 8, 14
  • 51. Current Landscape • • • • • • Ender (http://ender.jit.su/) Volo (http://volojs.org/) Jam (http://jamjs.org/) Bower (http://bower.io/) 7 000+ Component (http://component.io/) npm (http://npmjs.org) 53 000+ Wednesday, January 8, 14 Quite a few alternatives around. Not likely that all of these will survive. Currently it seems like Bower is the one getting more and more attraction for front end developers
  • 52. Transformations • • • • • AMD via deamdify Bower via debowerify Global via deglobalify ES6 via es6ify & more Wednesday, January 8, 14
  • 53. { "name": "bower-demo", "version": "0.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo "Error: no test specified" && exit 1" }, "author": "Johan Nilsson", "license": "BSD-2-Clause", "devDependencies": { "debowerify": "~0.5.1" } } Wednesday, January 8, 14
  • 54. { "name": "bower-demo", "main": "index.js", "version": "0.0.0", "authors": [ "Johan Nilsson <johan@markupartist.com>" ], "license": "BSD-2-Clause", "private": true, "dependencies": { "jquery": "~2.0.3" } } Wednesday, January 8, 14
  • 55. var $ = require('jquery'); $('body').append('<p>bla bla</p>'); Wednesday, January 8, 14
  • 56. browserify index.js -t debowerify > bundle.js Wednesday, January 8, 14
  • 57. Additional Tools • • • • Wednesday, January 8, 14 Watchify – Watch mode for browserify builds Beefy – Local development server grunt-browserify gulp-browserify