Introduction and use of Sea.js

Source: Internet
Author: User
Tags script tag

Before a blog very detailed introduction of the Sea.js loading process, as well as the source code implementation, link address: http://www.cnblogs.com/chaojidan/p/4123980.html

This blog I mainly talk about the introduction and use of sea.js.

First, the following sea.js of the CMD specification, and other specifications of the difference.

CommonJS originally called Serverjs, launched modules/1.0 specification, in node. JS and other environments have made a very good practice.

In the second half of 09, the energetic lads wanted to extend Serverjs's successful experience to the browser, so the community was renamed CommonJS and the next edition of Modules was hotly debated. The emergence of differences and conflicts has resulted in three major schools:

    1. modules/1.x genre. The idea is that the 1.x specification is sufficient, as long as it is ported to the browser. The mainstream representative is the developer of the service side.
    2. Modules/async genre. This view that the browser has its own characteristics, should not be directly used modules/1.x specifications. The typical representative of this view is the AMD specification and its implementation Requirejs.
    3. modules/2.0 genre. This view that the browser has its own characteristics, should not be directly used modules/1.x specifications, but should be consistent with the modules/1.x specification as far as possible. The typical representative of this view is the author of Bravojs and Flyscript. The BRAVOJS author's contribution to CommonJS's community was great, and the Modules/2.0-draft specification took a lot of thought. Flyscript's author puts forward the modules/wrappings specification, which is the predecessor of the CMD specification. Unfortunately, Bravojs too college School, Flyscript later did self-castration, the entire site (flyscript.org) offline.

Second Genre: AMD and Requirejs

Define (["Require"], function (require) {

//Here, module A has been downloaded and executed well

var a = require ("./a") //Here is just a exports of module a

})

AMD-style, passing parameters into the dependency module, destroys the principle of the nearest statement (when needed, only declared). Like what:

define (["A", "B", "C", "D", "E", "F"], function (A, B, C, D, E, f) {
 //equals all modules to be used are declared and initialized at the front
if (false) {
Even though it didn't work for a module B, B was executed in advance.
B.foo ()
   }
})

Third Genre: modules/2.0 cmd module

Under AMD, the default recommended module format is

define ([' A ', ' B '], function (A, b) {     //Enter function, A/b module is loaded and executed well
Do STH
})

CMD, the default recommendation is

The Define (function (Require, exports, module) {     //a,b module is only downloaded, and only the Define method in the module is executed, The function in the Define method is not executed until require .
var a = require (' a ');
var B = require (' B ');        
Do STH
})

There is also a core difference related to the nearest principle, is lazy principle

In AMD

define ([' A ', ' B '], function (A, b) {
Modules A and B are all executed and available here.
})

In CMD.

Define (function (require, exports) {
Module A runs here to execute (function in define)
if (false) {
When certain conditions are false, module B will never execute (function in define)
}
})

CMD can reduce the complexity of the build time.

Currently Sea.js has Plugin-combo plug-ins, the integration of modules can be put on-line dynamic do. In some cases (relatively easy to appear), the address of the dynamic combo will be very long:

Https://a.alipaybojects.com/??path/to/a.js,path/to/b.js..................path/to/long-url.js

When the URL address is long, more than 2083 (as if this is the value), in IE and some server configuration, too long URLs will be problematic. The classic solution is to split the URL into multiple segments:

Https://a.alipaybojects.com/??path/to/a.js,path/to/b.js..................path/to/u.js

Https://a.alipaybojects.com/??path/to/f.js,path/to/g.js..................path/to/long-url.js

After splitting, under the CMD specification, the above two URLs can be requested concurrently, and the first person to return is no problem. But under AMD, the above requirements are hanging up and hard to achieve.

You would say that Requirejs encourages projects to be built before they go online, without the need for online combo, and without encountering the above problems.

It is feasible for the CMD module to put the sea.js more broadly, to merge well in advance, or to dynamically combo the line. Many times, combo really easy, also more natural. Front-end development does not have to introduce a rigorous build process like Java everywhere.

CMD's lazy execution strategy is also more conducive to page performance.

Requirejs 2.0, a lot of ideas are also quietly changing, and now seems to support lazy implementation.

Then, introduce the method and use of the next sea.js.

Type= "Text/javascript" src= "js/seajs/2.0.0/sea-debug.js?t=123" data-config= "sea-js-config.js?t=123"

The data-config above refers to the path of the Sea.js configuration file. There is also a property of Data-main, which is the starting module of the project, and if it is defined, the module is executed first. Data-main is an optional option.

First, let's take a look at sea-js-config.js

Seajs.config ({
//Configure plugins
Plugins: [' Shim '],
//Configure aliases
Alias: {
//Configure jquery's shim configuration so that we can get jquery through require (' jquery ')
' jquery ': {
SRC: ' libs/jquery/1.9.1/jquery.js ', //Note that this is where you start looking for files from the previous two sections of the directory where Sea.js is located
Exports: ' JQuery '
}
}
});

The plugins option configures the plugin, where the shim plugin is used. Since jquery is not a standard cmd module , it is wrong to load jquery directly. Using the shim plugin, jquery is automatically converted into a standard CMD module. Do not manually change the jquery source code. Alias is a configuration alias that is easy to load.

Look at an example:


Project Main module App.js
Define (function (Require, exports, module) {
    //Load jquery and set it to global variable
window.$ = Window.jquery = $ = require (' jQuery ');
//define a global module load function. module name, options parameter
Exports.script_load = function (module, options) {
//Use Require.async to load the module asynchronously. The module needs to provide a fixed external calling interface, defined here as run.
Require.async (' modules/' + module, function (module) {
if (typeof (module.run) = = = ' function ') {
Module.run (options);
}
});
}
Window.script_load = Exports.script_load
});
We loaded jquery above and defined a module load function. Now let's add the following code to the HTML page:
<script type= "Text/javascript" >
Seajs.use (' Modules/app ', function (APP) {
App.script_load (' index ');
});
</script>
When the use method executes, it loads the app module, loads and executes, enters function, then calls the App.script_load method, which loads the index module, executes the code in index after the load is completed, The Run method is returned in index. When index is finished, the callback method for Require.async is called:

if (typeof (module.run) = = = ' function ') {
Module.run (options);
}

Therefore, the Run method is returned in the index module, so the Run method in index is executed.

Index.js
Define (function (Require, exports, module) {
Exports.run = function () {
$ (' #alert '). Click (function () {
Alert (' Pop up a box! ‘);
});
}
});

Using the "define" function in Seajs to define a module, define can receive three parameters,
The parameters that define can receive are module IDs, module arrays, and Factory functions, respectively.
I read the source code and found that define for the number of different parameters of the parsing rules are as follows:
If there is only one argument, assign the value to factory.
If there are two parameters, the second is assigned to factory, and the first one is assigned to Deps if it is an array, otherwise it is assigned to the ID.
If there are three parameters, the values are assigned to Id,deps and factory respectively.
ID is the identity string of a module, and when define has only one parameter, the ID is assigned by default to the absolute path of this JS file.
If the module is defined using define in the A.js file under example.com, the ID of this module is assigned to Http://example.com/a.js, and there is no specific recommendation not to pass in the ID. Deps generally do not need to pass in, the module needs to be loaded with require.
Factory function functions are the main body and focus of the module. When passing only one parameter to define (recommended notation), this parameter is the factory function, at which point the three parameters of the factory function are:
The require--module load function is used to record dependent modules.
A exports--interface point that exposes data or methods to external calls when they are defined on them.
The metadata for the module--module.
The module is an object that stores the meta information of the modules, as follows:
The ID of the module.id--module.
module.dependencies--An array that stores the list of IDs for all modules that this module relies on.
module.exports--and exports point to the same object.

Three modes of writing modules:

The first mode to define the module is based on the exports mode:

Define (function (Require, exports, module) {
var a = require (' a '); Introduction of a module
var B = require (' B '); Introducing the B module

var data1 = 1; Private data

var func1 = function () {//Private method
Return A.run (DATA1);
}

EXPORTS.DATA2 = 2; Public data

EXPORTS.FUNC2 = function () {//Public method
return ' Hello ';
}
});

Above is a model that is more "authentic" than the module definition. In addition to attaching common data and methods to exports, you can also return an object representation module directly, as the following code functions the same as the code above: (second type)

Define (function (Require, exports, module) {
var a = require (' a '); Introduction of a module
var B = require (' B '); Introducing the B module

var data1 = 1; Private data

var func1 = function () {//Private method
Return A.run (DATA1);
}

return {
Data2:2,
Func2:function () {
return ' Hello ';
}
};

});

If the module definition has no other code and returns only one object, you can also have the following simplified notation. The third approach is appropriate for modules that define pure JSON data.

Define ({

Data:1,

Func:function () {

return ' Hello ';

}

});

Absolute address-gives the absolute path to the JS file. Such as

Require ("http://example/js/a");

The representative is loaded into the http://example/js/a.js.

Base Address--if the load string identifies a relative address that is neither an absolute path nor a "./", it is addressed relative to the "base" in the SEAJS global configuration.

Note that there is no need to pass the suffix ". js" when loading the module, SEAJS will automatically add ". js". However, the following three scenarios are not added:

When loading CSS, such as

Require ("./module1-style.css");

The path contains "?" When, such as

Require (<a href= "Http://example/js/a.json?cb=func" >http://example/js/a.json?cb=func</a>);

When the path ends with "#", such as

Require ("http://example/js/a.json#");

Depending on the scenario, SEAJS provides three load module APIs, namely Seajs.use,require and Require.async.

The seajs.use is mainly used for loading the ingress module. The ingress module is the main function of the C program, and it is also the root of the entire module dependency tree. Seajs.use usage is as follows:

Single mode

Seajs.use ('./a ');

// Callback Mode

Seajs.use ('. A ', function (a) {

A.run ();

});

Multi-module mode

Seajs.use (['./a ', './b '], function (A, b) {

A.run ();

B.run ();

});

The general Seajs.use is used only on the page to load the Ingress module, and SEAJS will parse all dependent modules along the Ingress module and load them. If there is only one entry module, you can omit seajs.use by adding the "Data-main" attribute to the script tag that introduces Sea.js, for example,

<! DOCTYPE html>

<meta charset= "UTF-8" >

<title>TinyApp</title>

<body>

<p class= "Content" ></p>

<script src= "./sea.js" data-main= "./init" ></script>

</body>

The path identifier passed to require must be a string literal and cannot be an expression, as the following method of using require is wrong:
Require (' module ' + ' 1 ');
Require (' Module '. toLowerCase ());
This will cause the SEAJS to fail to perform the correct regular match to download the corresponding JS file.
As mentioned above Seajs will be in the HTML page open through static analysis, one-time download all the required JS files, if you want a JS file to download, you can use Require.async.

Require.async ('/path/to/module/file ', function (m) {
 Code of Callback ...
});
This is only used in this module, the corresponding JS file will be downloaded, but also the implementation of the JavaScript code on-demand loading.

SEAJS provides a Seajs.config method to set the global configuration and receive a configuration object that represents the global configuration.
Seajs.config ({
Base: ' path/to/jslib/',
Alias: {
' app ': ' path/to/app/'
},
CharSet: ' Utf-8 ',
timeout:20000,
Debug:false
});
Where base represents the base address path when the base address is addressed. For example, if base is set to http://example.com/js/3-party/, the
var $ = require (' jquery ');
Will load into the http://example.com/js/3-party/jquery.js.
Alias can set abbreviations for longer common paths.
CharSet represents the CharSet property of the script tag when downloading JS.
Timeout indicates the maximum length of time, in milliseconds, to download a file.
Debug indicates whether it is working in debug mode.
To use an existing JS library, such as jquery and Seajs, you simply encapsulate an existing library based on the module definition rules of SEAJS. For example, here's how to encapsulate jquery:
Define (function () {

{{{{} jquery Legacy code starts

}}}jquery Legacy Code End

return $.noconflict ();
});

Special NOTE: The following wording is wrong!
Define (function (require, exports) {

 Error usage!!!
Exports = {
Foo: ' Bar ',
Dosomething:function () {}
};

});
The correct notation is to use return or assign a value to Module.exports:
Define (function (Require, exports, module) {

  Correct wording
Module.exports = {
Foo: ' Bar ',
Dosomething:function () {}
};

});
Tip: Exports is just a reference to Module.exports. The value of Module.exports is not changed when the exports is re-assigned within factory. The assignment to exports is therefore invalid and cannot be used to change the module interface.
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:
Define (function (Require, exports, module) {

  Exports is a reference to Module.exports
Console.log (Module.exports = = = exports); //True

 Re-assigning module.exports to a value
Module.exports = new SomeClass (); //When the interface of a module is an instance of a class

Exports no longer equals module.exports
Console.log (Module.exports = = = exports); //False

});
Note: The assignment to the module.exports needs to be performed synchronously and cannot be placed in the callback function. The following is not possible:

Define (function (Require, exports, module) {

 Error usage
SetTimeout (function () {
Module.exports = {A: "Hello"};
}, 0);

});
Seajs.config ({
Alias: {
' jquery ': ' Jquery/1.7.2/jquery-debug.js '
}
});

Seajs.use (['./a ', ' jquery '],function (a,$) {
var num = a.a;
$ (' #J_A '). Text (num);
})

The use method will be viewed from our config configuration information, whether there are modules that need to be loaded beforehand. If so, load the A and jquery modules without loading them first.

Introduction and use of Sea.js

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.