# Modules
# sources
JavaScript Module Systems Showdown: CommonJS vs AMD vs ES2015 - auth0.com/blog - 20160315
Relation between CommonJS, AMD and RequireJS? - stackoverflow.com - 20130513
JavaScript modulaire pour le front-end : les bases - putaindecode.io - 20141215
Writing Modular JavaScript With AMD, CommonJS & ES Harmony - addyosmani.com - no date
ES6 modules, Node.js and the Michael Jackson Solution - medium.com/dailyjs - 20170721
JavaScript Modules: A Beginner’s Guide - Preethi Kasireddy - 20160122
JavaScript Module Pattern: In-Depth - 20100312
The Module Pattern - Learning JavaScript Design Patterns - Addy Osmani 2017
ES6+ maintenant ! (Christophe Porteneuve) - Devoxx2016
État de l'art de ES2015+ dans Node.js et le navigateur (Christophe Porteneuve) - Blend Web Mix 2016
Browserify and the Universal Module Definition - 20130614
BazaarJS: Module loaders e package managers - 20150628
nice UMD ex
The Current State of Implementation and Planning for ESModules - Node.js Foundation - 20171212
- We are committed to shipping ESM
- We are committed to ESM being first class in Node.js
- We are committed to having the Node.js and Web platform as first class runtimes for modules. Modules installed via npm should be able to run after installation without requiring a build step.
- We are committed to supporting our current users and offering migration paths as necessary. This can be through interoperability or APIs to improve the developer experience of working between module systems.
State of Modules in JavaScript - 20171026
focus on ES6 modules
ES modules: A cartoon deep-dive - hacks.mozilla.org - 20180328
deep description of ES6 modules
# why
- linking dependencies together (in JavaScript world it is just files and it does this with global var by default)
- encapsulation to prevent conflicts
- managing cycling ref (A deps on B who deps on C who deps on A)
- in regular JS import order matters and it is hard to maintain
// TODO refaire les exemples avec la fonction add de lodash
# IIFE
check http://falola.developpez.com/tutoriels/javascript/namespace/
// check https://zestedesavoir.com/tutoriels/358/module-pattern-en-javascript/#p83162
// my-module.js
var myModule = (function() {
return {
"add": function(a, b) {
return a + b;
}
};
})();
// index.js
myModule.add(1, 2); // 3
2
3
4
5
6
7
8
9
10
11
12
13
14
# AMD
AMD is for Asynchronous Module Definition. There is a specification.
Main advantage over CommonJS : Async support.
The AMD module format itself is a proposal for defining modules where both the module and dependencies can be asynchronously loaded.
This is designed to be used in browsers.
AMD module can be JavaScript object, function, constructor, string, but also files (JSON, css, ...)
// add.js
define([], function(){
function add(a, b){
return a + b;
}
return {
add: add
};
});
// index.js
require(['add'], function ( add ) {
add(1, 2); // 3
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
define
method for facilitating module definitionrequire
method for handling dependency loading
The define
signature is :
define(
module_id /*optional*/,
[dependencies] /*optional*/,
definition function /*function for instantiating the module or object*/
);
2
3
4
5
- The
module_id
string is the module name. - The
dependencies
array describe the deps to be injected in thedefinition
function. - The
definition
function is a callback called bydefine
when the deps are loaded.
AMD has several implementation :
# CommonJS
The CommonJS module proposal specifies a simple API for declaring modules server-side.
Main advantage over AMD : Compact declarative syntax.
exports
contains the objects a module wishes to make available to other modulesrequire
function that modules can use to import the exports of other modules.
CommonJS is the builtin Node.js module system.
A module exports can only be a JavaScript object. See Node.js doc.
A module is automatically wrapped in an anonymous function :
(function(exports, require, module, __filename, __dirname) {
// Module code actually lives in here
});
2
3
So top level variables in a CommonJS module are scoped to the module rather than the global object.
Notice that Node.js is caching exports, so if you exports a primitive, the value is copied by value. Cf this stackoverflow question.
Browserify is a tool built to use CommonJS for frontend development. He reads all the source files, following the require instruction, and concat all files in a single one (a bundle) to be linked in the app.
The verbose AMD syntax is not needed anymore, and we can have consistency in modules definitions between frontend and backend.
// add.js
function add (a, b) {
return a + b
}
module.exports = add;
// index.js
var add = require('add');
add(1, 2); // 3
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# ES6 Modules
The TC39 proposal for a single module definition for frontend and backen JavaScript.
// add.js
export function add (a, b) {
return a + b;
}
// index.js
import { add } from './add.js';
add(1, 2); // 3
2
3
4
5
6
7
8
9
10
11
12
13
import
declarations bind a modules exports as local variables and may be renamed to avoid name collisions/conflicts.export
declarations declare that a local-binding of a module is externally visible such that other modules may read the exports but can't modify them. Modules may export child modules but can't export modules that have been defined elsewhere.
ES6 creates a live read-only view of the modules we import. A primitive exposed outside with export
is the same variable read from outside with import
.