Naser Hassani
Software Engineer
May 2016
TehranJS
Seyed Naser Hassani
Freelance Frontend Developer
Before the topic,
There were something you may know…
Good authors divide their books into chapters and sections;
good programmers divide their programs into modules.
good product made with
good parts.
good parts is:
CAPSULAR (self-contained)
Encapsulation,
is an Object Oriented Programming concept that binds together the data and functions that manipulate the data, and that keeps both safe from outside interference and misuse.
Class
Variable
Method
Dependency WAR
<script src=“app.js”></script>
<script src=“jquery.min.js></script>Uncaught Referencer Error: jQuery is not defined.
<script src=“jquery.min.js></script>
<script src=“app.js”></script>Maintainability
Namespacing
Reusability
Modules resolve:
javascript module:
solutions
Ad-Hoc Solution:
Anonymous closure
(function () {
// We keep these variables private inside this closure scope
var myGrades = [93, 95, 88, 0, 55, 91];
var average = function() {
var total = myGrades.reduce(function(accumulator, item) {
return accumulator + item}, 0);
return 'Your average grade is ' + total / myGrades.length + '.';
}
var failing = function(){
var failingGrades = myGrades.filter(function(item) {
return item < 70;});
return 'You failed ' + failingGrades.length + ' times.';
}
console.log(failing());
}());
// ‘You failed 2 times.’Anonymous closure
Ad-Hoc Solution:
Global Import
(function (globalVariable) {
// Keep this variables private inside this closure scope
var privateFunction = function() {
console.log('Shhhh, this is private!');
}
// Expose the below methods via the globalVariable interface while
// hiding the implementation of the method within the
// function() block
globalVariable.each = function(collection, iterator) {
if (Array.isArray(collection)) {
for (var i = 0; i < collection.length; i++) {
iterator(collection[i], i, collection);
}
} else {
for (var key in collection) {
iterator(collection[key], key, collection);
}
}
};
globalVariable.map = function(collection, iterator) {
var mapped = [];
globalUtils.each(collection, function(value, key, collection) {
mapped.push(iterator(value));
});
return mapped;
};
}(globalVariable));Global Import
Ad-Hoc Solution:
Object Interface
var myGradesCalculate = (function () {
// Keep this variable private inside this closure scope
var myGrades = [93, 95, 88, 0, 55, 91];
// Expose these functions via an interface while hiding
// the implementation of the module within the function() block
return {
average: function() {
var total = myGrades.reduce(function(accumulator, item) {
return accumulator + item;
}, 0);
return'Your average grade is ' + total / myGrades.length + '.';
},
failing: function() {
var failingGrades = myGrades.filter(function(item) {
return item < 70;
});
return 'You failed ' + failingGrades.length + ' times.';
}
}
})();
myGradesCalculate.failing(); // 'You failed 2 times.'
myGradesCalculate.average(); // 'Your average grade is 70.33333333333333.'Object Interface
Ad-Hoc Solution:
The Revealing Module Pattern
var myRevealingModule = (function () {
var privateVar = "JavaScript",
publicVar = "Hey there!";
function privateFunction() {
console.log( "Name:" + privateVar );
}
function publicSetName( strName ) {
privateVar = strName;
}
function publicGetName() {
privateFunction();
}
// Reveal public pointers to
// private functions and properties
return {
setName: publicSetName,
greeting: publicVar,
getName: publicGetName
};
})();
myRevealingModule.setName( "Tehran JS" );The Revealing Module Pattern
but, we need more...
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Backbone.js Todos</title>
<link rel="stylesheet" href="todos.css"/>
</head>
<body>
<script src="../../test/vendor/json2.js"></script>
<script src="../../test/vendor/jquery.js"></script>
<script src="../../test/vendor/underscore.js"></script>
<script src="../../backbone.js"></script>
<script src="../backbone.localStorage.js"></script>
<script src="todos.js"></script>
</body>
<!-- (...) -->
</html>Backbonjs-todo.html
javascript module:
other solutions
CommonJS or AMD or ES2015
To be or not to be,
?
CommonJS
// In circle.js
const PI = Math.PI;
exports.area = (r) => PI * r * r;
exports.circumference = (r) => 2 * PI * r;
// In some file
const circle = require('./circle.js');
console.log( `The area of a circle of radius 4 is ${circle.area(4)}`);CommonJS Module
AMD (Asynchronous Module Definition)
//Calling define with a dependency array and a factory function
define(['dep1', 'dep2'], function (dep1, dep2) {
//Define the module value by returning a value.
return function () {};
});
// Or:
define(function (require) {
var dep1 = require('dep1'),
dep2 = require('dep2');
return function () {};
});AMD Module
ES2015 (native)
//------ lib.js ------
export const sqrt = Math.sqrt;
export function square(x) {
return x * x;
}
export function diag(x, y) {
return sqrt(square(x) + square(y));
}
//------ main.js ------
import { square, diag } from 'lib';
console.log(square(11)); // 121
console.log(diag(4, 3)); // 5ES2015 Module
System.import('some_module')
.then(some_module => {
// Use some_module
})
.catch(error => {
...
});
Promise.all(
['module1', 'module2', 'module3']
.map(x => System.import(x)))
.then(([module1, module2, module3]) => {
// Use module1, module2, module3
});ES2015 Module (Importing modules and loading scripts)
appendix:
(function (root, factory) {
if (typeof define === 'function' && define.amd)
{
// AMD
define(['myModule', 'myOtherModule'], factory);
}
else if (typeof exports === 'object')
{
// CommonJS
module.exports = factory(require('myModule'), require('myOtherModule'));
}
else {
// Browser globals (Note: root is window)
root.returnExports = factory(root.myModule, root.myOtherModule);
}
}(this, function (myModule, myOtherModule) {
// Methods
function notHelloOrGoodbye(){}; // A private method
function hello(){}; // A public method because it's returned (see below)
function goodbye(){}; // A public method because it's returned (see below)
// Exposed public methods
return {
hello: hello,
goodbye: goodbye
}
}));UMD Module
console.thanks('THE END');QUESTION?
By Naser Hassani
Learn about the different JavaScript module systems currently in use, and find out which will be the best option for your project.