CommonJS - JavaScript & Modules
Gopalakrishnan Subramani
Big Data Engineering | Trainer | Architect & Consultant | 20 Years | Analytics | Integration | DataBricks | Spark | Flink | Kafka | NiFi | ETL | AWS | Azure | ML | Java | Scala | Micro Service
CommonJS is quite popular now, widely used not only in Node.js applications but also for Front End, Single page applications developed in Angular, React frameworks. This article, I have published in my new JavaScript specific blog JavaScript.SH
Why CommonJS?
JavaScript known widely for its use as Browser based language, alone with HTML5, CSS, Dynamic DOM until we had Node.js, a JavaScript runtime, which allows developers to write independent JavaScript Server applications. Browsers use HTML, <Script src="..." /> tag to load the JavaScript files into Browsers.
When an application has multiple files, developers have to place the script tag in right order so that file dependencies are resolved, browser can load the application files in right order without breaking.
We have few limitations in JavaScript.
- JavaScript (ES5) has no namespace or package concept like the one found in C++/C# or in Java.
- JavaScript has only two level of scoping. One is Global Scope and second is function level scope.
- Global scope is painful when application introduced same variable name in two different files (collision) either one can exists.
While global variables issues can be resolved by using closures ie wrapping the JavaScript code with in the function.
Lack of packages/namespace is really problem for Node.js applications, especially, we have a lot of files in application, a tons of 3rd party libraries have to be referenced in application.
CommonJS has solution for above mentioned problems.
What is CommonJS?
CommonJS is a specification, you shall not find a specific JavaScript library by the that name. A group of independent developers started working on solving problem mentioned above, ie loading of one file into another JavaScript files, global variables, they came up with specification.
CommonJS introduced below specs.
- Each JavaScript file is a Module
- A Module (JavaScript file) may have local variables/functions at local scope, that shall not collide with similar variable/function name defined in another module (aka JavaScript file)
- A module can have reusable functions/variables which can be used in another file, that must be exported from that file (module.exports, exports)
- One module can refer another module by using require statement.
//math.js
function log(message) {
console.log("math ", message)
}
module.exports.add = function(a, b) {
log("add");
return a + b;
};
exports.sub = function(a, b) {
log("sub");
return a - b;
}
In the math.js file, log function is strictly local to math.js file, not exposed outside the file.
add, sub methods are exposed outside math.js, those functions can be used in other files. CommonJS introduced module.exports and exports (both are same, no differences) for exporting functions, variables outside file.
To use the add,sub methods in another file, CommonJS introduced require function
//calc.js
var math = require("./math")
function log(message) {
console.log("calc ", message)
}
log(math.add(1,2))
log(math.add(10 - 5))
The above code shall print
math add calc 3 math sub calc 5
Both files contains, log function, which is local to the specific file. CommonJS avoid name collision between files. We require("./math") basically load the math.js file in the current directory (./)
How it works in Node.js?
Node.js implements Common.JS specification for module dependencies. When we use the require statement, Node.js basically loads the content of JavaScript file to memory, then wrap the file content into a function body (Closure) to avoid global variable conflicts, node.js passes the module, exports as function parameters.
Closer look how how Node.js CommonJS require implementation works
function (module, exports) {
//below content inserted from math.js file
function log(message) {
console.log("math ", message)
}
module.exports.add = function(a, b) {
log("add");
return a + b;
};
exports.sub = function(a, b) {
log("sub");
return a - b;
}
//
return exports;
}
Since CommonJS Modules are not part of ES5 language spec, browsers do not support exports, module.exports and require function.
Support in Browsers
If we want to use CommonJS styled modules in browsers, we have various options through external libraries.
- SystemJS (Works at client side, download files and wrap them in browser)
- Browserify (runs on node.js, creates a browser loadable, single javascript bundle file from all javascript files referred in require() function.
- Webpack (runs on node.js, works similar to Browserify, but with various other features)
Modern Web Applications that are built using Angular, React frameworks, using ES6, TypeScript languages (Babel, TypeScript transpilers) use CommonJS as default one, while generating ES6 to ES5 or TypeScript to ES5.
Check my upcoming Exclusive JavaScript specific blog site JavaScript.SH
M365 Technical Service Delivery Manager
8 年super Da...??????