Complete high-frequency question bank warehouse address: github.com/hzfe/awesom…
IO /awesome-int hzfe.github.
Issues related to
- What are the main types of JavaScript modularity specifications
- What are the similarities and differences between AMD/CMD
- What is the ESM
- What problems/pain points does modularity solve
Answer key points
CommonJS
AMD
CMD
UMD
ESM
- CommonJS[1]Main is:Node.jsUse, pass
require
synchronousLoad the module,exports
Export content. - AMD[2]Main is:The browserUse, pass
define
Define modules and dependencies,require
asynchronousLoading modules is recommendedRely on the pre –. - CMD[3]: Similar to AMD, mainlyThe browserUse, pass
require
asynchronousLoad the module,exports
Export content, praiseRely on nearby. - UMD[4]: Generic module specification, which is a great fusion of CommonJS and AMD specifications, and a cross-platform solution.
- ESM[5]: Official modular specification,Modern browser native supportThrough the
import
asynchronousLoad the module,export
Export content.
Knowledge depth
1. Why modularity and modularity specifications
Modularization can solve the naming conflict/pollution problem of variables, functions and objects between codes. Good modularization design can reduce the coupling relationship between codes and improve the maintainability, extensibility and reuse of codes.
The function of modular specification is to standardize the definition and loading mechanism of JavaScript modules, export and load modules in a unified way, reduce the cost of learning and using, and improve the efficiency of development.
2. Details of various modular specifications
2.1 CommonJS
CommonJS is mainly used by Node.js, which loads modules synchronously through require, exports. Under the CommonJS specification, each JS file is an independent module, each module has its own scope, and the local variables in the module are private.
The sample
// hzfe.js
const hzfeMember = 17;
const getHZFEMember = () = > {
return `HZFE Member: ${hzfeMember}`;
};
module.exports.getHZFEMember = getHZFEMember;
// index.js
const hzfe = require("./hzfe.js");
console.log(hzfe.getHZFEMember()); // HZFE Member: 17
Copy the code
Usage scenarios
CommonJS is mainly used on the server (such as Node.js) or can be used on the browser after being packaged by the packaging tool.
Loading way
CommonJS loads modules synchronously, caching the results for the first load and directly reading the cached results for subsequent loads.
The advantages and disadvantages
advantages
- Simple and easy to use
- It could be anywhere
require
The module - Support for circular dependencies
disadvantages
- Synchronous loading does not work on the browser side
- Browser-side use requires packaging
- Difficult to support module static analysis
2.2 AMD (Asynchronous Module Definition)
AMD, for asynchronous module definition. AMD defines a set of JavaScript module dependency asynchronous loading standards to solve the browser side of the module loading problem. AMD is mainly used by the browser side, through define module and dependency, require asynchronous loading module, advocate dependency preloading.
AMD modules are defined in closures via the define function:
/**
* define
* @param Id Module name *@param Dependencies List *@param The details of the factory module/implementation */define(id? :string, dependencies? :string[].factory: Function | Object);
Copy the code
The sample
// hzfe.js
define("hzfe"[],function () {
const hzfeMember = 17;
const getHZFEMember = () = > {
return `HZFE Member: ${hzfeMember}`;
};
return {
getHZFEMember,
};
});
// index.js
require(["hzfe"].function (hzfe) {
// Rely on prefixes
console.log(hzfe.getHZFEMember()); // HZFE Member: 17
});
Copy the code
Usage scenarios
AMD is primarily used on the browser side, loading modules through AMD-compliant JavaScript libraries such as RequireJs.
Loading way
AMD loads modules asynchronously, and each module load actually loads the corresponding JS file.
The advantages and disadvantages
advantages
- Rely on asynchronous loading for faster startup speed
- Support for circular dependencies
- Support plugins
disadvantages
- Relatively complex syntax
- Dependency loader
- Difficult to support module static analysis
The specific implementation
- RequireJs
2.3 CMD (Common Module Definition)
CMD, the generic module definition. CMD defines a set of JavaScript module dependency asynchronous loading standards to solve the browser side of the module loading problem. CMD is mainly used by the browser side. It defines modules and dependencies through define. Require asynchronously loads modules and advocates dependency nearby.
The CMD module is defined in a closure through the define function:
/**
* define
* @param Id Module name *@param Dependencies List *@param The details of the factory module/implementation */define(id? :string, dependencies? :string[].factory: Function | Object);
Copy the code
The sample
// hzfe.js
define("hzfe"[],function () {
const hzfeMember = 17;
const getHZFEMember = () = > {
return `HZFE Member: ${hzfeMember}`;
};
exports.getHZFEMember = getHZFEMember;
});
// index.js
define(function (require.exports) {
const hzfe = require("hzfe"); // Rely on nearby
console.log(hzfe.getHZFEMember()); // HZFE Member: 17
});
Copy the code
Usage scenarios
CMD is primarily used on the browser side, loading modules through cmD-compliant JavaScript libraries such as sea-js.
Loading way
CMD loads modules asynchronously. Loading a module actually loads the corresponding JS file.
The advantages and disadvantages
advantages
- Rely on asynchronous loading for faster startup speed
- Support for circular dependencies
- Rely on nearby
- Great compatibility with CommonJS
disadvantages
- Relatively complex syntax
- Dependency loader
- Difficult to support module static analysis
The specific implementation
- Sea.js
2.4 UMD (Universal Module Definition)
UMD, common module definition. UMD is a cross-platform solution designed to solve the problem of common code under CommonJS and AMD specifications. It also supports module mounting globally.
The sample
// hzfe.js
(function (root, factory) {
if (typeof define === "function" && define.amd) {
// AMD
define(["exports"."hzfe"], factory);
} else if (
typeof exports= = ="object" &&
typeof exports.nodeName ! = ="string"
) {
// CommonJS
factory(exports.require("hzfe"));
} else {
// Browser globals
factory((root.commonJsStrict = {}), root.hzfe);
}
})(typeofself ! = ="undefined" ? self : this.function (exports, b) {
const hzfeMember = 17;
const getHZFEMember = () = > {
return `HZFE Member: ${hzfeMember}`;
};
exports.getHZFEMember = getHZFEMember;
});
// index.js
const hzfe = require("./hzfe.js");
console.log(hzfe.getHZFEMember()); // HZFE Member: 17
Copy the code
Usage scenarios
UMD can be used on both server side and browser side.
Loading way
How UMD loads modules depends on the environment, with Node.js loading synchronously and browser loading asynchronously.
The advantages and disadvantages
advantages
- Cross-platform compatibility
disadvantages
- Slightly too much code
2.5 the ESM (ECMAScript Module)
ESM stands for ESModule and ECMAScript Module. Official modular specification, modern browser native support, import to load modules, export to export content. The sample
// hzfe.js
const hzfeMember = 17;
export const getHZFEMember = () = > {
return `HZFE Member: ${hzfeMember}`;
};
// index.js
import * as hzfe from "./hzfe.js";
console.log(hzfe.getHZFEMember()); // HZFE Member: 17
Copy the code
Usage scenarios
The ESM can be used directly on supported browsers, and compiled/packaged on unsupported browsers.
Loading way
How ESM loads modules also depends on the environment. Node.js loads modules synchronously and browser loads modules asynchronously.
The advantages and disadvantages
advantages
- Supports synchronous and asynchronous loading
- Grammar is simple
- Support module static analysis
- Support for circular references
disadvantages
- Poor compatibility
Further reading
1. Static analysis
Static program analysis is a method of analyzing programs without running them. Static program Analysis – Wiki
In short, static analysis, as mentioned above, is the ability to determine which code is being used and which is not before you run the code.
2. Modular and engineering: Webpack
Webpack supports packaging of CommonJS, AMD and ESM modular specifications. Webpack processes modules into different artifacts depending on the specification.
CommonJS
(function (module.exports) {
const hzfeMember = 17;
const getHZFEMember = () = > {
return `HZFE Member: ${hzfeMember}`;
};
module.exports = getHZFEMember;
});
Copy the code
AMD
(function (module.exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_ARRAY__, // Dependency list
__WEBPACK_AMD_DEFINE_RESULT__; // factory returns the value
__WEBPACK_AMD_DEFINE_ARRAY__ = [];
/ / the factory
__WEBPACK_AMD_DEFINE_RESULT__ = function () {
const hzfeMember = 17;
const getHZFEMember = () = > {
return `HZFE Member: ${hzfeMember}`;
};
return {
getHZFEMember,
};
}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__); __WEBPACK_AMD_DEFINE_RESULT__ ! = =undefined &&
(module.exports = __WEBPACK_AMD_DEFINE_RESULT__);
});
Copy the code
ESM
(function (module, __webpack_exports__, __webpack_require__) {
__webpack_require__.r(__webpack_exports__);
__webpack_require__.d(__webpack_exports__, "getHZFEMember".function () {
return getHZFEMember;
});
const hzfeMember = 17;
const getHZFEMember = () = > {
return `HZFE Member: ${hzfeMember}`;
};
});
Copy the code
3. Modularity and Engineering: Tree Shaking
Tree shaking is a term commonly used to describe the act of removing dead-code from a JavaScript context. It relies on the import and export statements in ES2015 to detect whether code modules are exported, imported, and used by JavaScript files. Tree Shaking – MDN
Simply put, Tree Shaking is a feature that relies on static analysis of ESM modules to safely remove unused parts of code at compile time. (WebPack 5 also supports CommonJS, but I won’t go into detail here.)
The resources
- Modules: CommonJS modules
- Asynchronous module definition
- Common Module Definition
- Universal Module Definition
- Modules: ECMAScript modules
- Module Semantics