SoFunction
Updated on 2025-03-08

Detailed explanation of modules, loads and bundles in Javarscript

Introduction to JS modules

js modularity, simply put, separate the system or function into separate code snippets that do not affect each other. After strictly defining the interface, the modules do not affect each other and can be used for other purposes.

Common modularities include include (.h) files in C, imports in Java, etc.

Why JS needs modules

Obviously, we can implement the same function without modules. Why do we still need to use modules to write js code? The following points are some changes that modularity brings to us:

  • Abstract code: When we use modules to call an API, we don’t have to know how it is implemented internally, and avoid understanding the complex code inside;
  • Encapsulation code: Without the need to modify the code again, we can hide its specific implementation inside the module;
  • Reused code: Some commonly used and general functions can be implemented using modules to avoid excessive duplication of code;
  • Management dependencies: You can manage the implementation of functions by simply modifying dependencies without re-modifying your own internal code implementation.

ES5 and previous module systems

In ES5 and previous versions, there is no native module syntax. However, this does not mean that before ES5, the front-end did not use modules. A brief introduction to two types: IIFE and Revealing Module.

IIFE

Immediately Invoked Function Expression, execute function expressions immediately.

(function(){
  // ...
 })()

Looking at the above code, IIFE can be said to be an anonymous function that is executed when defined. Note that the function is wrapped first by "()", and then followed by "()" to indicate the execution of the function. If it is the following code, an error will be reported:

function(){
  ('test');
 }()
 // => Uncaught SyntaxError: Unexpected token )

This way of writing means that an anonymous function is defined first, and then parsing "()". Since "function" appears at the first position on the first line, it means that a function is defined here, followed by "()", which means that "()" is parsed separately, and the above error message will be reported, so the function definition needs to be wrapped first.
The writing method of "(function…)" means executing the internal code of "()" and returns the execution result of the statement. The return result here is the function, followed by "()" means executing the function. IIFE can help us:

  • You don't need to understand the specific code implementation to achieve the desired effect;
  • Variables defined internally do not pollute the global scope.

Obviously, this encoding method does not provide a good mechanism to solve the dependency management problem.

Revealing Module

According to the literal literal interpretation, it is a reveal mode, similar to the IIFE form, but provides a return value. Convenient to centrally manage public APIs, making modules and public APIs more concise and clear.

// Expose module as global variable
 var singleton = function(){
  // Inner logic
  function sayHello(){
  ('Hello');
  }
  // Expose API
  return {
  sayHello: sayHello
  }
 }()

Pay a little attention, we did not use "()" to wrap the code above because the keyword "function" is not at the beginning of the line.

We can use module api like this:

// Access module functionality
 ();
 // => Hello

Of course, we can also export it in the form of a constructor:

// Expose module as global variable
 var Module = function(){
  // Inner logic
  function sayHello(){
  ('Hello');
  }
  // Expose API
  return {
  sayHello: sayHello
  }
 }

Please note that the above function was not executed when it was defined.

We can use it like this:

var module = new Module();
(); // => Hello

Like IIFE, revealing patterns do not provide a good solution to dependency management.

More modular solutions

ES6 or ES2015 comes with native module syntax.

Before this, there were several common solutions for modularity:

  • AMD
  • CMD
  • CommonJs
  • UMD
  • ES6

AMD

AMD, Asynchronous Module Definition, asynchronous module definition. The AMD form is used on the browser side, using "define" to define module dependencies:

//Calling define with a dependency array and a factory function
 define(['dep1', 'dep2'], function (dep1, dep2) {
  //Define the module value by returning a value.
  return function () {};
 });

CMD

CMD, Common Module Definition, general module definition. This specification was proposed by the domestic great god Yu Bo. The difference from AMD is that it is preceded by the dependency relationship with AMD. If there is such a dependency, the dependency must be loaded first, and CMD is loaded on demand.

// CMD
 define(function(require, exports, module) {
 var a = require('./a')
 ()
 // 100 rows are omitted here var b = require('./b') // Reliance can be written nearby ()
 // ...
 })
 // AMD's default recommendation is define(['./a', './b'], function(a, b) { // Dependencies must be written from the beginning ()
 // 100 rows are omitted here ()
 ...
 })

CommonJs

CommonJs are used more often, using "require" to define dependencies, and using "" to define modules:

var dep1 = require('./dep1');
 var dep2 = require('./dep2');
  = function(){
  // ...
 }

UMD

UMD, Universal Module Definition, Universal Module Definition. Can be used for browser end and end:

(function (root, factory) {
  if (typeof define === 'function' && ) {
  // AMD. Register as an anonymous module.
   define(['b'], factory);
  } else if (typeof module === 'object' && ) {
  // Node. Does not work with strict CommonJS, but
  // only CommonJS-like environments that support ,
  // like Node.
   = factory(require('b'));
  } else {
  // Browser globals (root is window)
   = factory();
  }
 }(this, function (b) {
  //use b in some fashion.
  // Just return a value to define the module export.
  // This example returns an object, but the module
  // can return a function as the exported value.
  return {};
 }));

The original intention of the method design is mainly to support ES6 module syntax in ES5:

import { p as q } from './dep';
 var s = 'local';
 export function func() {
  return q;
 }
 export class C {
 }

ES6 module

ES6 comes with native module syntax, and use the keyword "export" to export the module's public API:

// 
 // Export the function
 export function sayHello(){
  ('Hello');
 }
 // Do not export the function
 function somePrivateFunction(){
  // ...
 }

Import the module with the keyword "import":

import { sayHello } from './lib';
 sayHello();
 // => Hello

Currently, the support for ES6 is different in each browser, so we now need to use a compiler, such as Babel, to compile ES6 code into ES5.

Module loader

A module loader can understand the module and load the module in a fixed form.

The module loader works at runtime, and the process is roughly as follows:

  • You run the module loader in your browser;
  • You tell the module loader which main file to load;
  • The module loader downloads and parses the main file;
  • The module loader loads other files as needed.

Some of the more common module loaders are:

  • RequireJS: Load modules in AMD style;
  • SeaJS: Load modules in CMD style;
  • SystemJS: Load modules in AMD, CommonJS, UMD or style;
  • jspm: jspm is based on SystemJS, is a module loader, and also has browser-side package management function.

Module packaging

Module packaging can replace the module loader.

However, compared to module loaders, the module packaging action is run at compile time:

  • Use module packaging to generate a js file during compilation; (for example)
  • Load the file in the browser.

Up to now, there are two common module packaging solutions:

  • Browserify: Package for CommonJS module;
  • Webpack: Package for AMD, CommonJS, and ES6 modules.

Summarize

In order to better use these tools in a modern js development environment, you first need to know the differences between modules, modular solutions, module loading, and module packaging.

A module is a piece of encapsulated code that can be exported in the form of a common API and loaded and called in other codes;

Modular solutions or modular ideas actually mean the syntax that defines a module. Due to differences in definition syntax, the commonly used ones currently include AMD, CMD, CommonJS, UMD, etc.;

Module loading, parsing and loading modules during runtime. Common ones include RequireJS, SeaJS, SystemJS and jspm;

Module packaging, which replaces the concept of module loading, generates a file after all code is integrated during compilation. Common ones are Browserify and Webpack.

Okay, the above is the entire content of this article. I hope the content of this article will be of some help to everyone's study or work. If you have any questions, you can leave a message to communicate. Thank you for your support.