What is Modularization

Let’s take a bicycle for an illustration. A bicycle is made up of several parts, each of these parts is made up of various components. All of these parts are put together to form a bicycle.


In software development, this concept is termed REUSABILITY.


Since a bicycle is composed of small parts, each of those parts can be built or repaired by engineers while not hindering one another.Also, if some of its parts get damaged, instead of replacing the whole bicycle, just the damaged parts have to be replaced. In software development, this concept is termed ISOLATION.


The benefit of these concepts holds the same in software development.



Why Modules in JavaScript?

A typical real program grows gradually. New pieces of functionality are added as new needs come up.This will make the parts of the program to become deeply entangled.


If you want to use any of the functionality from such a program in another situation, rewriting it may be easier than trying to disentangle it from its context (i.e issues with the reusability of code).


JavaScript Module Formats

When it comes to Cypress, there are two module formats in JavaScript, CommonJS and ES6 Modules format.

CommonJS

Loading a CommonJS module is a synchronous operation. That means that when the require (module-name) function call returns, the module has been located and completely read into memory and is ready for use.

var Math=require('math');
var add=require('./add.js');

The module is cached in memory so that subsequent require (module-name) calls return immediately, and all return the exact same object. Objects and functions can be exposed from a CommonJS module using module and exports.

exports.add = function() { 
// your function
};
// module.exports.add = function() { .. };

ES6

Loading a ES6 module is an asynchronous operation. ES6 module format makes use of the import and export keyword and its import happens before a module’s script starts running.

The export keyword is used to export function, class, or binding definition. It may appear in front of a function, class, or binding definition ( let, const, or var ).

Also, the import keyword is used to import function, class, or binding definition. It is possible to rename imported bindings using the word as:

import {months as monthNames} from "date-names";

Example Given

Open your favourite code editor and create a folder “modular code”. Create a file module_1.js with the following code.

let count = 0;
export function increment () { return ++count; }
function decrement () { return --count; }
export function hello () {
return "Hello, world!";
}
export default function() { return count; }
export const meaning = 42;
export let numberOfCount = -1;
export { decrement };

The export keyword is used to make items available outside a module while the import keyword is used to import items into another module. The statement in line 2, 4, 8 and 9 are named export, meaning the exported thing has a name, and that code outside the module uses that name to access the object.

Named exports are used if we don’t want to import everything the module is exporting. As we see here, named exports can be functions or objects, and they may also be class definitions.

Using export default as seen in line 7 can be done once per module, and is the default export from the module. Now let’s see how to use this ES module. Create a module_2.js file with the following:

import * as sample_1 from './module_1.js';
console.log(sample_1.hello());
console.log(`${sample_1.increment()} ${sample_1.hello()}`);
export function firstName () {
return "Natalie"
}
export function lastName () {
return "Selina"
}
export default function count () { return count; }

The asterisk symbol in line one means all the exported items. Notice the difference between the console.log statement in line 2 and line 3 the later is using javascript template literals for interpolation. When you use a named default export, that changes how you import that module. Instead of using the * or using named imports, you just use import name from ./path. Let’s import the count function from module_2.js file.


Module Formats in Cypress

ES6 in Cypress ( brower )

Cypress will loading all the functions in your ***.util.js,if you use import months from “date-names” to import function, which may cause loading too much time before starting.

We establish several rules to avoid this situation:

  1. When you need to use all the functions in ***.util.js
    • Write your ***.util.js like this:
      var function_name = {
      function_name: function () {
      // your function
      }
      }
      export default function_name
    • And write your ***.spec.js** like this:
      import function_name from './example.util.js'

      function_name.function_name()

  2. When you just need to use serveral functions in ***.util.js
    • Write your ***.util.js like this:
      var function_name_1 = function () {
      // your function_1
      }

      var function_name_2 = function () {
      // your function_2
      }

      var function_name_3 = function () {
      // your function_2
      }

      export { function_name_1, function_name_2, function_name_3 }
    • Or you can also write like this:
      export function_name_1 = function () {
      // your function_1
      }

      export function_name_2 = function () {
      // your function_2
      }

      export function_name_3 = function () {
      // your function_2
      }
    • And write your ***.spec.js** like this:
      import { function_name_2 } from  './example.util.js'

      function_name.function_name2()

CommonJS in Cypress ( server )

This article can tell the difference: https://blog.logrocket.com/commonjs-vs-es-modules-node-js/

We establish this rule:

  1. When you write Node.js, you need to use CommonJS.
    • By default, Node.js treats JavaScript code as CommonJS modules, while ES modules are the standard for JavaScript.