Home >Web Front-end >JS Tutorial >Understand front-end modularity (CommonJs, AMD and CMD)
There are three front-end module specifications: CommonJs, AMD and CMD.
CommonJs is used on the server side, AMD and CMD are used in the browser environment.
AMD is the standardized output of module definitions during the promotion process of RequireJS.
CMD is the standardized output of module definition during the promotion process of SeaJS.
AMD: Advance execution (asynchronous loading: dependencies are executed first) + delayed execution
CMD: Delayed execution (run to load, execute in sequence)
FunctionWriting
function f1(){ //... } function f2(){ //... }
A module is a file that implements a specific function. Putting several functions in a file constitutes a module . Load this file when needed and call the functions in it.
But doing so will pollute the global variables, there is no guarantee that variable names will not conflict with other modules, and there is no relationship between module members.
ObjectHow to write
var module = { star : 0, f1 : function (){ //... }, f2 : function (){ //... } }; module.f1(); module.star = 1;
The module is written as an object, and the module members are encapsulated in the object. By calling the objectproperty, you can access the module members. But at the same time, the module members are exposed, and the internal state of the module can be modified by the outside world.
Execute function immediately
var module = (function(){ var star = 0; var f1 = function (){ console.log('ok'); }; var f2 = function (){ //... }; return { f1:f1, f2:f2 }; })(); module.f1(); //ok console.log(module.star) //undefined
Internal private variables cannot be accessed from the outside
CommonJS is a specification for server-side modules, promoted and used by Node. Due to the complexity of server-side programming, it is difficult to interact with the operating system and other applications without modules. The usage is as follows:
math.js exports.add = function() { var sum = 0, i = 0, args = arguments, l = args.length; while (i < l) { sum += args[i++]; } return sum; }; increment.js var add = require('math').add; exports.increment = function(val) { return add(val, 1); }; index.js var increment = require('increment').increment; var a = increment(1); //2
According to the CommonJS specification:
A single file is a module. Each module has a separate scope, that is to say, variables defined within the module cannot be read by other modules unless they are defined as attributes of the global object.
#The best way to export module variables is to use the module.exports object.
Load the module using the require method, which reads a file and executes it, returning the module.exports object inside the file
Look at the above carefully code, you'll notice that require is synchronous. The module system needs to synchronously read the contents of the module file, compile and execute it to obtain the moduleinterface.
However, there are many problems on the browser side.
On the browser side, the best and easiest way to load JavaScript is to insert the 3f1c4e4b6b16bbbd69b2ee476dc4f83a tag in the document. However, script tags are inherently asynchronous, and traditional CommonJS modules cannot be loaded normally in the browser environment.
One of the solutions is to develop a server-side component, perform static analysis on the module code, and return the module and its dependency list to the browser. This works well, but requires additional components to be installed on the server and therefore a number of underlying architecture adjustments.
Another solution is to use a set of standard templates to encapsulate the module definition:
define(function(require, exports, module) { // The module code goes here });
This set of template code provides the opportunity for the module loader to load the module before the module code is executed. , statically analyze the module code and dynamically generate a dependency list.
math.js define(function(require, exports, module) { exports.add = function() { var sum = 0, i = 0, args = arguments, l = args.length; while (i < l) { sum += args[i++]; } return sum; }; }); increment.js define(function(require, exports, module) { var add = require('math').add; exports.increment = function(val) { return add(val, 1); }; }); index.js define(function(require, exports, module) { var inc = require('increment').increment; inc(1); // 2 });
AMD is the abbreviation of "Asynchronous Module Definition", which means "asynchronous module definition". Since it is not natively supported by JavaScript, page development using AMD specifications requires the use of corresponding library functions, which is the famous RequireJS. In fact, AMD is the standardized output of module definitions during the promotion process of RequireJS
It adopts The module is loaded asynchronously, and the loading of the module does not affect the execution of subsequent statements. All statements that depend on this module are defined in a callback function. This callback function will not run until the loading is completed.
RequireJS mainly solves two problems
Multiple js files may have dependencies, and the dependent files need to be loaded into the browser earlier than the files that depend on it
When js is loaded, the browser will stop page rendering. The more files loaded, the longer the page will lose response time
RequireJs also uses require() The statement loads the module, but unlike CommonJS, it requires two parameters:
The first parameter [module] is an array, and the members inside are the modules to be loaded; the second The parameter callback is the callback function after successful loading. Math.add() and math module loading are not synchronized, and the browser will not freeze.
require([module], callback); require([increment'], function (increment) { increment.add(1); });
define() function
RequireJS定义了一个函数 define,它是全局变量,用来定义模块:
define(id?, dependencies?, factory);
参数说明:
id:指定义中模块的名字,可选;如果没有提供该参数,模块的名字应该默认为模块加载器请求的指定脚本的名字。如果提供了该参数,模块名必须是“顶级”的和绝对的(不允许相对名字)。
依赖dependencies:是一个当前模块依赖的,已被模块定义的模块标识的数组字面量。
依赖参数是可选的,如果忽略此参数,它应该默认为["require", "exports", "module"]。然而,如果工厂方法的长度属性小于3,加载器会选择以函数的长度属性指定的参数个数调用工厂方法。
工厂方法factory,模块初始化要执行的函数或对象。如果为函数,它应该只被执行一次。如果是对象,此对象应该为模块的输出值。
来举个例子看看:
define("alpha", ["require", "exports", "beta"], function (require, exports, beta) { exports.verb = function() { return beta.verb(); //Or: return require("beta").verb(); } });
RequireJs使用例子
require.config是用来定义别名的,在paths属性下配置别名。然后通过requirejs(参数一,参数二);参数一是数组,传入我们需要引用的模块名,第二个参数是个回调函数,回调函数传入一个变量,代替刚才所引入的模块。
main.js //别名配置 requirejs.config({ paths: { jquery: 'jquery.min' //可以省略.js } }); //引入模块,用变量$表示jquery模块 requirejs(['jquery'], function ($) { $('body').css('background-color','red'); });
引入模块也可以只写require()。requirejs通过define()定义模块,定义的参数上同。在此模块内的方法和变量外部是无法访问的,只有通过return返回才行.
math.js define('math',['jquery'], function ($) {//引入jQuery模块 return { add: function(x,y){ return x + y; } }; });
将该模块命名为math.js保存。
require(['jquery','math'], function ($,math) { console.log(math.add(10,100));//110 });
main.js引入模块方法
CMD 即Common Module Definition通用模块定义,CMD规范是国内发展出来的,就像AMD有个requireJS,CMD有个浏览器的实现SeaJS,SeaJS要解决的问题和requireJS一样,只不过在模块定义方式和模块加载(可以说运行、解析)时机上有所不同。
在 CMD 规范中,一个模块就是一个文件。代码的书写格式如下:
define(function(require, exports, module) { // 模块代码 });
require是可以把其他模块导入进来的一个参数;而exports是可以把模块内的一些属性和方法导出的;module 是一个对象,上面存储了与当前模块相关联的一些属性和方法。
AMD是依赖关系前置,在定义模块的时候就要声明其依赖的模块;
CMD是按需加载依赖就近,只有在用到某个模块的时候再去require:
// CMD define(function(require, exports, module) { var a = require('./a') a.doSomething() // 此处略去 100 行 var b = require('./b') // 依赖可以就近书写 b.doSomething() // ... }) // AMD 默认推荐的是 define(['./a', './b'], function(a, b) { // 依赖必须一开始就写好 a.doSomething() // 此处略去 100 行 b.doSomething() ... })
seajs使用例子
// 定义模块 myModule.js define(function(require, exports, module) { var $ = require('jquery.js') $('p').addClass('active'); exports.data = 1; }); // 加载模块 seajs.use(['myModule.js'], function(my){ var star= my.data; console.log(star); //1 });
The above is the detailed content of Understand front-end modularity (CommonJs, AMD and CMD). For more information, please follow other related articles on the PHP Chinese website!