Previous words
CMD ( Common Module Definition)
denotes a generic module definition, the specification is developed domestically, by Ali's Yuber. Just like AMD has a requirejs,cmd with a browser that implements SEAJS,SEAJS and Requirejs, is a modular solution for JavaScript. This article describes the cmd and seajs in detail
Cmd
In Sea.js, all JavaScript modules follow the cmd (Common module definition) module definition specification. This specification clarifies the basic writing format and basic interaction rules of the module.
The AMD specification is simple enough to have only one API, the Define function
define ([Module-name], [array-of-dependencies?], [Module-factory-or-object]);
Module-name: module identification, can be omitted
Array-of-dependencies: The dependent module can be omitted
Module-factory-or-object: The implementation of a module, or a JavaScript object
The CMD specification is similar, except that the third parameter factory is implemented in a different way. In the CMD specification, a module is a file. The code is written in the following format
Define (ID?, Deps?, Factory)
Similar to the AMD specification, define is a global function for defining modules. id
the string represents the module identity, and the array deps
is module dependent. These two parameters can be omitted, usually generated automatically by the build tool
Typically, the third parameter of the Define () method factory is a function that represents the construction method of the module. By executing this construction method, you can get the interface that the module provides to the outside. factory
The default method is to pass in three parameters when it executes: require
, exports
andmodule
[Note that the parameters of the]factory () method can be omitted if not required, but cannot be modified, such as ' A ', ' B ', ' C ', or the order of its parameters. Inside the function, the parameter name cannot be re-assigned, such as ' var a = require; ‘
Define (function (Require, exports, module) { //Modules code});
"Require"
require
Is factory
the first parameter of a function. require
is a method that accepts a module identity as a unique parameter that is used to obtain the interfaces provided by other modules. In layman's words, the properties or methods of other modules are invoked through the Require () method
Define (function (Require, exports, module) { //Gets the interface of module a var a = require ('./a '); Call module A's method a.dosomething ();});
The implementation and functionality of this require () method are particularly similar to the Require () method in Commonjs. Perhaps, some people will have doubts, require () is not a synchronous method? In Commonjs yes, it can be said in Seajs, but it is not complete. It should be more reasonable to say that the synchronous loading within the module, the actual performance of the module a pre-download
For example, the following code, even if you do not click on the page, A.js will be pre-downloaded. After clicking on the page, the console outputs ' a ' and ' a.test ' in turn
Main.jsdefine (function (Require, exports, module) { Document.onclick = function () { var a = require (' js/a '); A.test (); } }); Define (function (Require, exports, module) { console.log (' a '); Exports.test = function () { console.log (' a.test ');} })
Can you download it when you are done? Similar to lazy loading. Yes, use the Require.async () method. require.async
method is used to load the module asynchronously inside the module and executes the specified callback after the load is completed
Main.jsdefine (function (Require, exports, module) { Document.onclick = function () { require.async ('. a '), function (a) { a.test (); }); } ); /a.jsdefine (function (Require, exports, module) { console.log (' a '); Exports.test = function () { console.log (' a.test ');} })
"Exports"
exports
is an object that is used to provide a module interface to the outside. Similar to the exports function of Commonjs
Define (function (require, exports) { //externally provided foo attribute Exports.foo = ' bar '; Externally available DoSomething method exports.dosomething = function () {};});
In addition to exports
adding members to an object, you can also use a direct out-of-the- return
way interface, which is similar to Requirejs
Define (function (require) { //via return directly provides interface return { foo: ' Bar ', dosomething:function () {} }} ;});
If the return
statement is a unique code in a module, it can also be simplified to
Define ({ foo: ' Bar ', dosomething:function () {}});
"Module"
module
is an object that stores some of the properties and methods associated with the current module
Main.jsdefine (['./a '],function (require, exports, module) { console.log (module);})
Module.uri represents the absolute path of a module based on the path resolution rules of the module system
Module.id is a unique identifier for a module, and in general there is no handwritten ID parameter in define, the value of Module.id is Module.uri, and the two are identical
Module.dependencies is an array that represents the dependencies of the current module
Module.exports is the interface provided externally by the current module. The exports parameter passed to the factory constructor method is a reference to the Module.exports object. Interfaces are provided only through the exports parameter, and sometimes not all of the developer's needs are met. For example, when the interface of a module is an instance of a class, it needs to be implemented by Module.exports
[note] The assignment of the pair needs to be module.exports
executed synchronously and cannot be placed in the callback function. This is not going to work.
Define (function (Require, exports, module) { //Error usage setTimeout (function () { module.exports = {A: "Hello"}; }, 0);});
Entrance
The Requirejs is set through Data-main, and Seajs is set by Sea.use (). Sea.js when the download is complete, the Portal module is loaded automatically
Seajs.use (ID, callback?)
[Note] callback
Parameter optional, omitted, means no callback required
<script src= "Sea.js" ></script><script> seajs.use (' Js/main ');</script>
Load a single dependency, run the following code after the console output ' test '
Index.html<script src= "Sea.js" ></script><script> seajs.config ({ base: ' JS ' }); Seajs.use ("main", function (a) { a.test (); }); </script>//main.jsdefine (['. A '],function (require, exports, module) { return { test:function () { Console.log (' Test ');}} )
Load multiple dependencies
Load module A and Module B concurrently, and execute the specified callback Seajs.use (['./a ', './b ') when both are loaded, and function (A, c) { a.init (); B.init ();});
"Domready"
seajs.use
Has nothing to do with the DOM ready
event. If certain operations are to be DOM ready
performed later, you need to use jquery
class libraries to ensure that
Seajs.use ([' jquery ', './main '], function ($, main) { $ (document). Ready (function () { main.init (); });});
Packaging
sea.js
when introduced, it can be sea.js
packaged with other files, can be merged in advance, or dynamically merged with the combo service. Either way, in order for the sea.js
internal to quickly get to its own path, it is recommended to manually add id
attributes
<script src= "Path/to/sea.js" id= "Seajsnode" ></script>
Adding seajsnode
A value allows you sea.js
to get directly to your own path without having to get it automatically through other mechanisms. This has a certain increase in performance and stability, and the recommended default is to add
Configuration
Path
If you do not configure the path, in Requirejs, the default path is Data-main directory, such as data-main= ' Js/main ', then the path is ' JS ' directory
And Seajs is different, its default path is the directory of the Seajs file, such as the Seajs file is located in the ' demo ' directory, after the following entry settings
Seajs.use (' Js/main ');
Description Main.js's directory is ' Demo/js/main.js '. If Main.js relies on a.js, and A.js is in the same directory as main.js, the following two types of notation are correct
1, ' demo ' + ' js/a ' = ' demo/js/a.js '
Main.jsdefine ([' js/a '],function (Require, exports, module) { })
2, './' means the current directory, that is ' demo/js ', so './a ' = ' demo/js/a.js '
Main.jsdefine (['./a '],function (require, exports, module) { })
Use BaseURL in Requirejs to configure the base path, and use base in Seajs. After the following configuration, the real path is ' demo ' + ' JS ' + ' main ' = ' demo/js/main.js '
<script src= "Sea.js" ></script><script> seajs.config ({ base: ' JS ' }); Seajs.use ("main");</script>
Alias
When the module identifier is long, it can be used alias
to simplify
Seajs.config ({ alias: { ' jquery ': ' Jquery/jquery/1.10.1/jquery ', ' app/biz ': ' http://path/to/app/ Biz.js ', }});
Directory
Can be used paths
to simplify writing when the directory is deep or if you need to call the module across directories
Seajs.config ({ paths: { ' gallery ': ' Https://a.alipayobjects.com/gallery ', ' app ': ' Path/to/app ', }});
Difference from AMD
AMD is the normalized output of the module definition in the Requirejs process, and CMD is the normalized output of the module defined by SEAJS during the promotion process. The implementation of these specifications can achieve the purpose of browser-side modular development
There are two main differences between AMD and CMD.
1, the implementation time of the dependent module
For dependent modules, AMD is executed ahead of time, and Cmd is deferred execution
AMD will execute the module after the module is loaded, all modules will go into the require after the execution of the callback function, the execution of the main logic, the effect is dependent on the module execution order and writing order is not necessarily consistent, see the network speed, which first downloaded, which first executed, But the master logic must be executed only after all dependent loads have been completed. However, the new version of Requirejs can also be deferred
CMD does not execute after loading a dependent module, just download it, after all the dependent modules are loaded to enter the main logic, when encountering the Require statement to execute the corresponding module, so that the module execution sequence and writing order is exactly the same. If you use the Require.async () method, you can implement lazy loading of the module, that is, do not load
2, the CMD respected rely on the nearest, AMD respected the reliance on the predecessor
Cmddefine (function (Require, exports, module) { var a = require ('./a ') a.dosomething () //Omit 100 rows here var B = require ('./b ')//dependency can be written near b.dosomething () ///...})
Amddefine (['./a ', './b '), function (A, b) { //dependency must be written in the first place a.dosomething () //100 lines omitted here b.dosomething () ...})
Of course, AMD also supports the syntax of CMD, while also supporting the passing of require as a dependency
At last
CommonJS, Requirejs, seajs these three kinds of modular schemes, and there is no high and low points. With the continuous upgrading of the various programs, the language aspects of mutual reference, the use of the difference gradually become smaller. The above three library-level modular scheme, need to introduce additional libraries, and the following specifications are not established by the standard organization, the authority is insufficient
As ES6 begins to support modularity at the language level, ES6 's modular notation is the future modular standard
CMD and Seajs