As we all know, JavaScript does not have the concept of modules. At the beginning, JavaScript appeared as a simple scripting language to realize simple page logic. However, with the development of the Internet and the advent of the Web 2.0 era, front-end code presented a spurt of development. The problem of missing modules is becoming more and more obvious, and the JavaScript community is doing a lot of exploring.
So what is a module?
Module refers to the collection of program statements (i.e., the collection of program code and data structure) that can be named separately and independently accomplish certain functions.
Therefore, the core of a module is to accomplish a specific function, and an important part of it is to solve the problem of reference dependencies and dependencies.
function
By definition, a function can also be considered a module.
Add the following functions to mymodule.js
function add(x, y) {
return x + y;
}
function minus(x, y) {
return x - y;
}
Copy the code
You can use the functions in mymodule.js directly after importing them with the script tag
<script src="myModule.js"></script>
<script>
console.log(add(1, 2)) // 3
console.log(minus(2, 1)) // 1
</script>
Copy the code
In myModule.js, each function can be considered a module. There are two main defects in defining modules by function: first, it will pollute global variables and cannot guarantee that variable names among modules do not conflict; If a module in mymodule.js needs to depend on another module (such as jQuery), that module (jQuery) needs to be referenced before myModule.js.
CommonJS
Since the birth of NodeJS in 2009, JavaScript modular programming formally entered people’s vision, and NodeJS modular system is implemented according to CommonJS specification.
In the CommonJS specification, a file is a module, and each module has its own scope, that is, variables and functions in a module are private and cannot be accessed externally.
Inside the module, the module variable object represents the current module, and its exports property is also an object that represents the interface to the outside world, so we put what we want to expose into the module.exprots object. The reference module uses the require function.
To define the myModule module using the CommonJS specification, write the following code in myModule.js
function add(x, y) {
return x + y;
}
function minus(x, y) {
return x - y;
}
module.exports = {
add: add,
minus: minus
}
Copy the code
Reference the myModule module in main.js
var myModule = require('./myModule.js');
console.log(myModule.add(1.2)); / / 3
console.log(myModule.minus(2.1)); / / 1
Copy the code
However, the way require loads modules synchronously in the CommonJS specification makes it unsuitable for browser-side use. When loading modules synchronously on the server, the waiting time depends on the reading time of the hard disk, while when loading modules synchronously on the browser, the waiting time depends on the speed of the network. As a result, the browser will be in a state of suspended animation during the loading process.
AMD (Asynchronous Module Definition)
AMD is asynchronous module definition, which is the standardized output of RequireJS module definition in the promotion process. Again, it states that a file is a module, and the filename is the module name.
AMD uses the define function to define modules. Use the require function to reference the module.
The define function is used as follows
define(id? , dependencies? , factory);Copy the code
Define the mymodule.js module
define(['depenModule'].function (depenModule) {
//do something
});
Copy the code
Require takes two arguments, the first of which is an array of dependent module identifiers; The second argument is the callback function after the dependent module is loaded.
Reference the myModule module in main.js
require(['myModule'].function (myModule){
//do something
});
Copy the code
AMD advocates dependency preloading, which requires asynchronous loading of the required dependency module before executing the code in the corresponding callback function.
CMD (Common Module Definition)
CMD, the common module definition, is the normalized output of SeaJS module definition in the promotion process. Again, it states that a file is a module, and the filename is the module name.
It uses the define function to define modules; Use the require function to reference the module.
The define function is used as follows
define(factory)
Copy the code
Define the mymodule.js module
define(function(require, exports, module) {
//do something
});
Copy the code
Reference the myModule module in main.js
var myModule = require('./myModule.js');
//do something
Copy the code
CMD advocates dependency proximity, requiring as many dependencies as it needs during code writing.
AMD and CMD load dependent modules asynchronously. The biggest difference is that the execution timing of dependent modules is handled differently.
AMD dependency front, browser will immediately load its dependency module; CMD, on the other hand, is dependent nearby, requiring modules to be parsed into strings to confirm their dependencies and load them, which is a sacrifice of performance for ease of development.
UMD (Universal Module Definition)
UMD, or common module definition, is a specification that can work in virtually any module environment.
A typical PIECE of UMD code is shown below
(function (global, factory) {
typeof exports === 'object'&& typeof module ! = ='undefined' ? factory(exports) : // CMD
typeof define === 'function' && define.amd ? define(['exports'], factory) : // AMD
(factory((global['module'] = {}))); // Browser globals
}(this, (function (exports) {
'use strict';
exports.x = x;
Object.defineProperty(exports, '__esModule', { value: true });
})));
Copy the code
The principle is through the judgment of different circumstances to do the corresponding processing.
ES6 module
In ES6, JavaScript finally has the concept of a true module of its own. ES6 in the language standard level, the realization of module function, and the implementation is quite simple, can completely replace the previous specification, become a common browser and server module solution.
In the ES6 module system, export and export default commands are used to specify the external interface of the module, and the import command is used to input functions provided by the module.
MyModule. Js
function add(x, y) {
return x + y;
}
function minus(x, y) {
return x - y;
}
export {
add,
minus
}
Copy the code
In the main. Js
import { add, minus } from './myModules.js';
console.log(add(1, 2)) // 3
console.log(minus(2, 1)) // 1
Copy the code
For details on ES6 modules, see Introduction to ECMAScript 6 by Master Nguyen Yifeng.
Write in the last
In the exploration of JavaScript modularization, there are many excellent specifications and frameworks. In addition to the representative specifications mentioned above, there are other excellent specification frameworks such as YUI and KMD.
Although the development history of JavaScript modularity (or, more accurately, the development history of JavaScript) has been full of difficulties, we can actually see that it is on the right path and getting better and better. We sincerely hope that JavaScript will become more and more powerful in the future. Can let us meet more possibilities in the future.
The resources
The past and present of JavaScript modules