DEV Community

Mohammed Ali
Mohammed Ali

Posted on

Modules 2/2

  • Module Pattern was used before ES6 Modules.
  • Goal: Encapsulate functionality, suport private data, expose public API and all this is achieved by using IIFEs.

IIFE: Ex. (function(){})();

// IIFE Goal: Create a new scope, return the data just once. All of data inside IIFE will be private as it would inside the fn scope. 
// Using this way, we don't need to call it separately. And it ensures its called only once.
// IIFE is created only once, goal is 'NOT TO REUSE' by executing it multiple times.

// Result of running an IIFE is stored, or else it will disappear simply.
const ShoppingCart2 = (function(){
  const cart = [];
  const shippingCost = 10;
  const totalPrice = 237;
  const totalQuantity = 10;

  const addToCart = function(product, quantity){
    cart.push({product, quantity});
    console.log(`${quantity} ${product} added to cart. Shipping cost is ${shippingCost}`);
  };

  const orderStock = function(product, quantity){
    console.log(`${quantity} ${product} ordered from supplier`);
  };
  // Need to return something, in order to return a public API. For that, an object is returned containing stuff which needs to be made public.
  return {
    addToCart,
    cart, 
    totalPrice,
    totalQuantity
  };
})();
// Everything inside the above module is private to the module.
// The above fn returns the object mentioned inside return statement and assign it to the ShoppingCart2 variable mentioned at the start of fn. This IIFE is returned then long ago.
// All this is possible because of closures. Hence, addToCart can acccess the cart variable.

ShoppingCart2.addToCart('apple', 4);
ShoppingCart2.addToCart('pizza', 5);
ShoppingCart2;
ShoppingCart2.shippingCost; // inaccessible.

Enter fullscreen mode Exit fullscreen mode

The Module pattern has been working even before ES6 modules.

Disadv:

  1. Now if we want one module per file, like we have with ES6 modules then multiple scripts need to be created and linked inside the HTML file.
  2. The order of the script loading will also matter.
  3. All those variables will be living in global scope.

Beside native ES6 modules & module pattern, JS also supported other module systems which were not native to JS. Ex. AMD, CommmonJS
Ex. CommonJS modules are used in Node.js for all of its existance. Recently ES6 modules have been implemented in Node.js
All modules on npm repository still use the commonJS module system as npm was originally intended for node. Only later, npm became the repository for the whole JS world. Hence, we are basically stuck with CommonJS. So, CommonJS still needs to be paid attention to as its impt in Node.js
Just like ES6 module, 1 file is 1 module in CommonJS.
The commonJS code won't work in browser, but it will work in node.js
ES Modules will replace all module system eventually but as of now we need to use commonjs also.

export keyword is an object, which is not defined in our code as well as in browser.

// EXPORT
export.addToCart = function(product, quantity){
    cart.push({product, quantity});
    console.log(`${quantity} ${product} added to cart. Shipping cost is ${shippingCost}`);
};

// IMPORT: is similar to ES Modules but would use a require fn.
// require is not defined in browser env but its defined in node env as its a part of commonjs
const addToCart = require('./shoppingCart.js')
Enter fullscreen mode Exit fullscreen mode

Top comments (0)