Use Requirejs to load JavaScript files that do not conform to AMD specifications: How shim is used and how it is implemented

Source: Internet
Author: User

We know that there are 2 ways to define global variables in JavaScript, essentially equivalent, by injecting properties or methods into a Window object.

Global.jsvar g_name = "Aty"; window.g_age = 25;
when global.js loads, the browser's Global object window will have 2 more properties: G_name and G_age.


We write a JS tool class or a JS framework, usually in 2 ways:
Way 1:dateutil.js

(function (window) {var dateutils = {};D ateutils.tostring = function () {alert ("toString");};//global Variable window. Dateutils = dateutils;  }) (window);
This approach is most commonly used, such as jquery, underscore and other frameworks are written in this structure.

Way 2:stringutil.js

global variable var stringutils = {}; Stringutils.touppercase = function (input) {alert ("toUpperCase");}

It's obvious that stringUtil.js and dateutil.js are not compliant with the AMD specification, now let's look at how to load through Requirejs. The project directory structure is as follows:
Index.htmlmain.jslibs--dateutil.js--stringutil.js


the implementation codes for index.html and Main.js are as follows:

<!doctype html>

Requirejs.config ({    baseUrl: ' Libs '}) require (["Dateutil", "stringutil"], function (dateutil,stringutil) {    alert (dateutil===undefined);//true});

run index.html, observed through F12:


It is obvious that dateutil.js and stringutil.js can be loaded by Requirejs normally, but the return value of these 2 modules cannot be obtained. We modify the next index.html, register the event handler function with the Div, and invoke the method provided by Stringutil.js in the event handler function:

<!doctype html>Click Div1 to see that the test () function does not error. That is, Requirejs loading JS files that do not conform to AMD specifications, with us directly in HTML via <script> tag loading, there is not much difference. The global variables introduced in the JS file will still exist and can still be used normally. 


Let's take a look at the use of the shim parameter, we will main.js modify the following:

Requirejs.config ({    baseUrl: ' Libs ', shim:{dateutil:{  deps:[],  exports: ' Dateutils '},stringutil:{  Deps:[],  exports: ' StringUtils '}}); require (["Dateutil", "stringutil"], function (dateutil,stringutil) {    Stringutil.touppercase ();d ateutil.tostring ();});
This code works as you can see: The shim parameter helps us to use modules that do not conform to AMD's specifications in the form of AMD modules. Below are the following: the meanings of deps and exports. Exports is well understood, that is, the return value of the module. The value of exports in Main.js must be consistent with the names of the global variables exposed in dateutil.js and stringutil.js. It is clear that the return values of the 2 modules of the Dateutil.js and Stringutil.js are the exposed global variables window.dateutils and the WINDOW.STRINGUTILS,REQUIREJS framework that return the values of these global variables as a result of the module's return. If multiple global variables are exposed in dateutil.js or stringutil.js, then exports can specify any one of them as the result of the module's return. However, the general framework uses only 1 global variables, which reduces the likelihood of collisions, after all, the fewer global variables the better.

The dateutil.js and stringutil.js that we have written above do not depend on other JS modules, so the specified deps is an empty array. The Aplugin.js and bplugin.js we have written below depend on the module util.js.

Aplugin.js (function (window,util) {var a = {};a.tostring = function () {alert ("a=" +util.add);};//global variable WINDOW.A = A;  }) (Window,util);
Bplugin.jsvar B = {};b.tostring = function () {alert ("b=" +util.add);}
Util.jsvar util = {};util.add = function (v1,v2) {return v1+v2;};
main.js code as follows, only set the correct dependency order, the use of the time will not be a problem.

Requirejs.config ({    baseUrl: ' Libs ', shim:{dateutil:{  deps:[],  exports: ' Dateutils '},stringutil:{  Deps:[],  exports: ' StringUtils '},aplugin:{  deps:["util"],  exports: ' A '},bplugin:{  deps:[' util '] ,  exports: ' B '}}), require (["Stringutil", "Dateutil", "Aplugin", "bplugin"], function (string,date) {    // String.tostring ();//date.tostring (); var aPl = require ("Aplugin"); var bPl = require ("Bplugin"); apl.tostring (); Bpl.tostring ();});
Obviously Util.js also does not conform to the AMD specification, if the A module depends on the B module, a module does not conform to the AMD specification (using global variables), then the B module must also use global variables, otherwise it will error. That is, if you change the util.js to comply with the AMD specification, then Aplugin.js and Bplugin.js will be unable to find the Util object and error.

AMD compliant Util.jsdefine (function () {function Add (v1,v2) {return v1+v2;} return {"Add": add};});

Finally, we look at the role of Init in the shim configuration parameters. Init can specify that a function is primarily used to avoid collisions between class libraries. Because of a JS file that does not conform to the AMD specification, global variables are used. So there is a possibility of name collisions when loading multiple modules. For example, jquery, underscore and other frameworks will provide a noconflict () function to avoid name collisions, noconflict () Implementation principle can refer to this article.

We write a module conflict.js that does not conform to the AMD specification, uses the global variable $e, and provides the Noconflict method.

(function (window) {///save data var _$e = window. $E; var myplugin = {"Name": "aty"};myplugin.noconflict = function () {window. $E = _$e;return myplugin;};/ /register $ewindow with the Global object. $E = Myplugin;}) (window);

Modify the index.html as follows to define a global variable $e before the Requirejs is loaded.

<!doctype html>the code in Main.js is as follows:

Requirejs.config ({    baseUrl: ' Libs ', shim:{conflict:{  deps:[],  exports: ' $E ',  init:function () { Return $E. Noconflict ();}}}  ); Require (["conflict"], function (mayconflict) {    alert (mayconflict.name); alert (window. $E);//before});
running index.html, you can see that conflict.js can coexist with the previously defined global variables $e, avoiding conflicts, which is achieved through INIT. If you do not define INIT, you can see that the value printed by alert (window. $E) is undefined.


Use Requirejs to load JavaScript files that do not conform to AMD specifications: How shim is used and how it is implemented

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.