JS Modularization#
#Front-End/JS
Common JS#
- Modules can be loaded multiple times, but they will only run once during the first load, and the result will be cached. To run the module again, the cache must be cleared.
- Synchronous loading, module loading will block the execution of subsequent code.
- Used in server environments (nodejs).
exports
is just a reference to module.exports
, which means that Node provides an exports
variable for each module, which points to module.exports
. It is equivalent to having this line of code at the beginning of each module:
var exports = module.exports
Module Export and Import
// common-js-a.js exports the module
// Automatically adds the line var exports = module.exports
exports.a = 'hello world';
// common-js-b.js imports the module
const moduleA = require('./common-js-a');
console.log(moduleA.a)
AMD#
- Asynchronous loading
- Used in browser environments, with dependencies being pre-declared
// a.js exports the module, module1 and module2 are other pre-declared dependencies
define(['module1', 'module2'], function (m1, m2) {
return { a: 'hello world' };
})
// b.js imports the module
require(['./a.js'], function (moduleA) {
console.log(moduleA.a)
})
CMD#
- Used in browser environments
- Asynchronous loading, with dependencies being declared nearby
// Asynchronous loading with nearby dependencies
// a.js exports the module
define(function(require, exports, module) {
exports.a = 'hello CMD'
})
// b.js imports the module
define(function(require, exports, module) {
var moduleA = require('./a.js') // Dependencies are declared nearby
console.log(moduleA.a)
})
UMD#
Compatible with AMD, CommonJS, and global references
Supports running in both browser and Node environments
(function webpackUniversalModuleDefinition(root, factory) {
// Test Comment
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory(require('lodash'));
// Test Comment
else if(typeof define === 'function' && define.amd)
define(['lodash'], factory);
// Test Comment
else if(typeof exports === 'object')
exports['someLibName'] = factory(require('lodash'));
// Test Comment
else
root['someLibName'] = factory(root['_']);
})(this, function(__WEBPACK_EXTERNAL_MODULE_1__) {
// ...
});
ES6 Module#
// a.js
export const a = 'hello es6 module'
// b.js
import { a } from './a.js'
- Used in browser environments, currently requires compilation to ES5 code using Babel
export
only supports exporting objects, not values.export default
specifies the default output, which is essentially a variable nameddefault
.
Summary#
- The synchronous loading mechanism of CommonJS is mainly used on the server side, i.e. Node, but the accompanying blocking loading feature is not suitable for loading browser resources. This is why AMD and CMD specifications were created.
- Both AMD and CMD can asynchronously load modules in the browser, but in practice, the development cost of these two specifications is relatively high.
- UMD is compatible with AMD, CommonJS, and global references, and is currently the mainstream for packaging JS libraries.
- ES6 implements modularization at the language standard level, making it very convenient to use. It is currently the standard solution for the browser, and with the support of modern packaging tools, it is only a matter of time before it dominates the Node server.