Meaning of modularity

Break the code up into separate pieces, and then connect those pieces using the modular pattern to achieve different functions.

Just like the jigsaw puzzle as a child, different pieces can be put together to form any shape.

The idea behind this pattern is simple: divide logic into chunks, encapsulate it, and isolate it from each other, while determining which external modules to introduce and which to expose.

This basic idea is the foundation of all JavaScript module systems.

Code case address: github.com/AnsonZnl/JS…

Benefits of modularity

  • Avoiding naming conflicts (reducing namespace pollution)
  • Better separation, load on demand
  • Higher reusability
  • High maintainability

JS common modules

IIFE mode: Anonymous function self-invocation (closure)

It is mainly used in the browser.

Using the principle of closures to create a unique function scope to hold private variables, to achieve modular effect.

use

HTML

<script type="text/javascript" src="module.js"></script>
<script type="text/javascript">
  console.log(myModule.get()); // output-data
  myModule.set("new data"); // Set the internal data
  console.log(myModule.data); //output-undefined (no access to module internal data)
  myModule.data = "xxxx"; // Not the data inside the modified module
  console.log(myModule.get()); //output-new data Specifies the new value
</script>
Copy the code

JS

/ / module. Js file
(function(window) {
  let data = "data";
  // Get data
  function get() {
    return data;
  }
  // Modify the data
  function set(val) {
    data = val;
  }
  // Expose behavior
  window.myModule = { get, set, }; }) (window);
Copy the code

CommonJS

It is mainly used on the server side, but if you run it on the browser side you need to use another tool (Browserify).

Exports = value or exports.xx = value(exports is an exported object)

Import the module: require(xx). If it is a third-party module, XXX is the module name. If it is a custom module, XXX is the file path of the module.

The characteristics of

  • All code runs in the module scope and does not pollute the global scope.
  • Modules can be loaded multiple times, but only run once on the first load, and then the results are cached and read directly from the cache when they are loaded later. For the module to run again, the cache must be cleared.
  • The order in which modules are loaded, in the order they appear in the code.

Install the uniq function in Node.

npm init
npm install uniq --save
Copy the code
// module.js
let arr = [1.2.2.3.3];
module.exports = {
  arr,
};
Copy the code
// app.js
let module1 = require("./module.js");
let uniq = require("uniq");

console.log(uniq(module1.arr)); / / [1, 2, 3]
Copy the code

AMD

Asynchronous Module Definition – Asynchronous Module Definition

Unlike CommonJS, AMD loads modules asynchronously.

The basic grammar

Defining exposure modules

// Define modules with no dependencies
define(function() {
  returnModule; });// Define dependent modules
define(["module1"."module2"].function(m1, m2) {
  returnModule; });Copy the code

Introducing usage modules

require(["module1"."module2"].function(m1, m2) {use m1 and m2; });Copy the code

Use case

<! -- index.html -->
<body>
  <! -- import require.js and specify the entry to the js main file -->
  <script
    data-main="main"
    src="https://cdn.bootcdn.net/ajax/libs/require.js/2.3.6/require.js"
  ></script>
</body>
Copy the code
// main.js
(function() {
  require(["module.js"].function(module) {
    let currentUrl = module.getUrl();
    alert("Current page URl:"+ currentUrl); }); }) ();Copy the code
// module.js
// Define the module
define(function() {
  let url = window.location.href;

  function getUrl() {
    return url.toUpperCase();
  }
  // Expose the module
  return {
    getUrl,
  };
});
Copy the code

For more information, see requirejs.org/

CMD

CMD is the standardized output of the module definition in the promotion process of SeaJS. It is a synchronous module definition and a standard of SeaJS. SeaJS is an implementation of CMD concept and SeaJS is aJS framework for module development provided by Taobao team.

When it’s used, when it’s used, when it’s returned, it’s a synchronization concept.

Features: CMD is a specification improved on the basis of AMD, and AMD is different in the implementation mechanism of the dependency module is different, CMD is the nearest dependency, and AMD is the front dependency.

Environment: browser environment

Grammar:

  • Define (function(require, exports, module){})
  • Define (function(){return ‘value ‘})

use

// main.js
define(function(require.exports.module) {
  var moduleA = require("./module.js");
  alert(moduleA.a); // Print: hello world
});
// module.js
define(function(require.exports.module) {
  exports.a = "hello world";
});
Copy the code
<body>
  <script
    data-main="main"
    src="https://cdn.bootcdn.net/ajax/libs/require.js/2.3.6/require.js"
  ></script>
</body>
Copy the code

Please refer to the Sea. Js usage: seajs. Making. IO/seajs/docs /

UMD

Universal Module Definition is compatible with AMD and CommonJS specifications, and compatible with global introduction.

Environment: server environment and browser side

The implementation principle of UMD is simple:

  • Check whether AMD is supported (define exists). If AMD exists, load the module.
  • Then check whether the node.js module format is supported (whether exports exist). If yes, use node.js module format.
  • If neither exists, expose the module globally (window or Global)

use

(function(root, factory) {
  if (typeof define === "function" && define.amd) {
    //AMD
    define(["jquery"], factory);
  } else if (typeof exports= = ="object") {
    //Node, CommonJS, etc
    module.exports = factory(require("jquery"));
  } else {
    // Browser global variables (root = window)
    root.returnExports = factory(root.jQuery);
  }
})(this.function($) {
  / / method
  function myFuncA() {} // Private method, because there is no return
  function myFuncB() {} // Public method because it is returned

  // Expose public methods
  return {
    myFuncB,
  };
});
Copy the code

Everyone at ordinary times is the introduction of jQuery CND UMD, source code can be viewed: cdn.bootcdn.net/ajax/libs/j…

ES6 Module

Before ES6, modularity was mainly promoted by the community, resulting in CommonJS and AMD, the former for the server and the latter for the browser. ES6 module will completely replace CommonJS and AMD specifications, and become a common solution for browsers and servers.

The ES6 module is designed to be as static as possible, so that the module dependencies, as well as the input and output variables, can be determined at compile time. Both CommonJS and AMD modules can only determine these things at runtime. For example, a CommonJS module is an object, and you have to look for object properties when you enter it.

Features:

  • Load on demand (load at compile time)
  • Import and export commands can only be at the top of the module, not in code blocks (e.g., if statements), and import() statements can be loaded asynchronously and dynamically on demand in code blocks

Environment: server environment and browser side

Grammar:

  • Import:Import {modules1,modules1,} from 'modulespath'
  • Export:exportorexport default
  • Dynamic import:Import (' module path ').then(..)

use

Install Babel in Node first:

NPM install --save-dev @babel/core @babel/cli @babel/preset-env @babel/node NPM install --save @babel/polyfill # and run npx babel-node main.jsCopy the code
// modules/double.js
let mes = "Hello Modules for double";
function sum(value) {
  return `${mes} - ${value * 2}`;
}
export default {
  mes,
  sum,
};
// main.js
import module from "./modules/double";
console.log(module.sum(10)); // Hello Modules for double - 20
Copy the code

The browser

The difference between

  • Differences with CommonJS:

    • The CommonJS module outputs a copy worth while the ES6 module outputs a reference to the value
    • The CommonJS module is run time loaded, and the ES6 module is compile time output interface
    • The CommonJS module require() is a synchronously loaded module, while the ES6 module import command is asynchronously loaded, with a separate module-dependent parsing phase.

Disadvantages Browser and server support is not very good at the moment, use of some tools (Babel).

  • Browser support: It can be used in a later version of the browser, such as Chrome<script type="module" src="./foo.js"></script>writing
  • Server support (Node) has two modes, ES6 module and CommonJS respectively.
    • Starting from Node.js V13.2, ES6 modules are supported by default, but required.mjsFor a suffix, or inpackage.jsonChanges in thetypeField ismodule(recommended)
    • To use CommonJS, you need to use.cjsThe suffix can also be setpackage.jsonChanges in thetypeField iscommonjs(Recommended).

It’s best not to mix the two. For more information, see es6.ruanyifeng.com/#docs/modul…

conclusion

  • The CommonJS specification is mainly used for server-side programming, loading modules are synchronous, which is not suitable in a browser environment because synchronization means blocking loading and browser resources are loaded asynchronously, hence the AMD CMD solution.
  • The AMD specification loads modules asynchronously in the browser environment, and multiple modules can be loaded in parallel. However, AMD specifications are expensive to develop, code is difficult to read and write, and semantics are not smooth in the way modules are defined.
  • The CMD specification is similar to the AMD specification in that it is used for browser programming, relies on proximity, executes lazily, and can be easily run in Node.js. However, depending on SPM packaging, the loading logic of modules is biased
  • ES6 in the language standard level, the realization of module function, and the implementation is quite simple, can completely replace CommonJS and AMD specifications, become a common browser and server module solution.

reference

  • Front-end modular details
  • JS module
  • Introduction to the UMD specification in javascript
  • ES6 Modules
  • An understanding of front-end modularity: AMD, CMD, CommonJS, ES6