|
| 1 | +# Modules |
| 2 | + |
| 3 | +As our application grows bigger, we want to split it into multiple files, so called “modules”. A module may contain a class or a library of functions for a specific purpose. |
| 4 | + |
| 5 | +# CommonJS |
| 6 | + |
| 7 | +CommonJS is a volunteer working group that designs and implements JavaScript APIs for declaring modules. |
| 8 | + |
| 9 | +A CommonJS module is essentially a reusable piece of JavaScript which exports specific objects, making them available for other modules to `require` in their programs. |
| 10 | + |
| 11 | +With CommonJS, each JavaScript file stores modules in its own unique module context (just like wrapping it in a closure). In this scope, we use the module.exports object to expose modules, and require to import them. |
| 12 | + |
| 13 | +The require() function is only available by default on Node.js environment. |
| 14 | + |
| 15 | +When you’re defining a CommonJS module, it might look something like this: |
| 16 | + |
| 17 | +```javascript |
| 18 | +function myModule() { |
| 19 | + this.hello = function () { |
| 20 | + return 'hello!'; |
| 21 | + }; |
| 22 | + |
| 23 | + this.goodbye = function () { |
| 24 | + return 'goodbye!'; |
| 25 | + }; |
| 26 | +} |
| 27 | + |
| 28 | +module.exports = myModule; |
| 29 | +``` |
| 30 | + |
| 31 | +We use the special object module and place a reference of our function into module.exports. |
| 32 | +Then when someone wants to use myModule, they can require it in their file, like so: |
| 33 | + |
| 34 | +```javascript |
| 35 | +var myModule = require('myModule'); |
| 36 | + |
| 37 | +var myModuleInstance = new myModule(); |
| 38 | +myModuleInstance.hello(); // 'hello!' |
| 39 | +myModuleInstance.goodbye(); // 'goodbye!' |
| 40 | +``` |
| 41 | + |
| 42 | +multiple exports |
| 43 | + |
| 44 | +```javascript |
| 45 | +const method = () => { |
| 46 | + // your method logic |
| 47 | +}; |
| 48 | + |
| 49 | +const otherMethod = () => { |
| 50 | + // your method logic |
| 51 | +}; |
| 52 | + |
| 53 | +module.exports = { |
| 54 | + method, |
| 55 | + otherMethod, |
| 56 | + // anotherMethod |
| 57 | +}; |
| 58 | +``` |
| 59 | + |
| 60 | +**NOTE** that CommonJS takes a server-first approach and **synchronously loads modules**. This matters because if we have three other modules we need to require, it’ll load them one by one. |
| 61 | + |
| 62 | +# ES6 Modules |
| 63 | + |
| 64 | +A module is just a file. One script is one module. As simple as that. |
| 65 | + |
| 66 | +Modules can load each other and use special directives export and import to interchange functionality, call functions of one module from another one: |
| 67 | + |
| 68 | +```javascript |
| 69 | +// 📁 sayHi.js |
| 70 | +export function sayHi(user) { |
| 71 | + alert(`Hello, ${user}!`); |
| 72 | +} |
| 73 | + |
| 74 | +// 📁 main.js |
| 75 | +import { sayHi } from './sayHi.js'; |
| 76 | + |
| 77 | +alert(sayHi); // function... |
| 78 | +sayHi('John'); // Hello, John! |
| 79 | +``` |
| 80 | + |
| 81 | +## Multiple named exports |
| 82 | + |
| 83 | +```javascript |
| 84 | +//------ lib.js ------ |
| 85 | +export const sqrt = Math.sqrt; |
| 86 | +export function square(x) { |
| 87 | + return x * x; |
| 88 | +} |
| 89 | +export function diag(x, y) { |
| 90 | + return sqrt(square(x) + square(y)); |
| 91 | +} |
| 92 | + |
| 93 | +//------ main.js ------ |
| 94 | +import { square, diag } from 'lib'; |
| 95 | +console.log(square(11)); // 121 |
| 96 | +console.log(diag(4, 3)); // 5 |
| 97 | +``` |
| 98 | + |
| 99 | +You can also import the complete module: |
| 100 | + |
| 101 | +```javascript |
| 102 | +//------ main.js ------ |
| 103 | +import * as lib from 'lib'; |
| 104 | +console.log(lib.square(11)); // 121 |
| 105 | +console.log(lib.diag(4, 3)); // 5 |
| 106 | +``` |
| 107 | + |
| 108 | +## Single default export |
| 109 | + |
| 110 | +There can be a single default export. For example, a function: |
| 111 | + |
| 112 | +```javascript |
| 113 | +//------ myFunc.js ------ |
| 114 | +export default function () { ··· } // no semicolon! |
| 115 | + |
| 116 | +//------ main1.js ------ |
| 117 | +import myFunc from 'myFunc'; |
| 118 | +myFunc(); |
| 119 | +``` |
| 120 | + |
| 121 | +Or a class: |
| 122 | + |
| 123 | +```javascript |
| 124 | +//------ MyClass.js ------ |
| 125 | +export default class { ··· } // no semicolon! |
| 126 | + |
| 127 | +//------ main2.js ------ |
| 128 | +import MyClass from 'MyClass'; |
| 129 | +const inst = new MyClass(); |
| 130 | +``` |
| 131 | + |
| 132 | +# ES modules v/s CommonJS |
| 133 | + |
| 134 | +**The ES module format was created to standardize the JavaScript module system.** |
| 135 | + |
| 136 | + The CommonJS module system, on the other hand, is built into Node.js. Prior to the introduction of the ES module in Node.js, CommonJS was the standard for Node.js modules. As a result, there are plenty of Node.js libraries and modules written with CommonJS. |
| 137 | + |
| 138 | +**CommonJS loads modules synchronously, ES modules are asynchronous** |
| 139 | + |
| 140 | + One of the limitations of using require() is that it loads modules synchronously. This means that modules are loaded and processed one by one. |
| 141 | + |
| 142 | + As you might have guessed, this can pose a few performance issues for large-scale applications that hundreds of modules. In such a case, import might outperform require() based on its asynchronous behavior. |
| 143 | + |
| 144 | +**Node.js support for ES modules** |
| 145 | + |
| 146 | + Older Node.js versions don’t support ES modules |
0 commit comments