The first and second parts of this series Introduce the prototype and theoretical concepts of Javascript modules. Today we will introduce how to apply them in practice.
I am using a very popular library require. js.
1. Why use require. js?
At the earliest time, all Javascript code was written in a file. It was enough to load the file. Later, there were more and more code, and one file was not enough. It had to be divided into multiple files and loaded in sequence. I believe many people have seen the following webpage code.
Copy codeThe Code is as follows: <script src = "1.js"> </script>
<Script src = "2.js"> </script>
<Script src = "3.js"> </script>
<Script src = "4.js"> </script>
<Script src = "5.js"> </script>
<Script src = "6.js"> </script>
This code loads multiple js files in sequence.
This writing method has many disadvantages. First, when loading, the browser will stop rendering the web page. The more files are loaded, the longer the response time for the web page will be lost. Secondly, due to the dependency between js files, therefore, the loading sequence must be strictly guaranteed (for example, in the previous example, 1. js needs to be in 2. js front), the module with the largest dependency must be placed at the end of the load, when the dependency is very complex, code writing and maintenance will become difficult.
The birth of require. js aims to solve these two problems.:
(1) asynchronous loading of js files to prevent webpage response loss;
(2) Management Module dependencies to facilitate code compilation and maintenance.
Ii. Loading of require. js
The first step to use require. js is to download the latest version from the official website.
After downloading the file, you can load it under the js subdirectory.Copy codeThe Code is as follows: <script src = "js/require. js"> </script>
Some may think that loading this file may also cause the webpage to lose response. There are two solutions: one is to load it at the bottom of the web page, and the other is written as follows:Copy codeThe Code is as follows: <script src = "js/require. js" defer async = "true"> </script>
The async attribute indicates that the file needs to be asynchronously loaded to avoid webpage response loss. IE does not support this attribute and only supports defer. Therefore, defer is also supported.
After loading require. js, the next step is to load our own code. Assume that our own code file is main. js, which is also placed under the js directory. You just need to write it as follows:Copy codeThe Code is as follows: <script src = "js/require. js" data-main = "js/main"> </script>
The data-main attribute specifies the main module of the webpage program. In the preceding example, the main. js file under the js directory is first loaded by require. js. Because the default file Suffix of require. js is js, You Can abbreviated main. js as main.
Iii. Writing of the main module
In the previous section main. js, I called it "main module", which means the portal code of the entire webpage. It is a bit like the main () function in C language, where all code starts to run.
Next let's take a look at how to write main. js.
If our code does not depend on any other module, we can directly write javascript code.
// Main. jsCopy codeThe Code is as follows: alert ("loaded successfully! ");
In this case, there is no need to use require. js. The common case is that the main module depends on other modules, and then the require () function defined by AMD specifications is used.
// Main. jsCopy codeThe Code is as follows: require (['lelea', 'leleb', 'lelec'], function (moduleA, moduleB, moduleC ){
// Some code here
});
The require () function accepts two parameters. The first parameter is an array that indicates the dependent modules. In the preceding example, ['lelea', 'leleb', 'lelec'] indicates that the main module depends on these three modules; the second parameter is a callback function. After all the modules specified in the current interface are loaded successfully, it will be called. The loaded module will pass in the function as a parameter, so that these modules can be used within the callback function.
Require () asynchronously loads moduleA, moduleB, and moduleC, And the browser does not lose the response. The callback function specified by require () runs only after the previous modules are loaded successfully, solved the problem of dependency.
Next, let's look at a real example.
Assuming that the main module depends on jquery, underscore, and backbone, main. js can write as follows:Copy codeThe Code is as follows: require (['jquery ', 'underscore', 'backone'], function ($, _, backbone ){
// Some code here
});
Require. js loads jQuery, underscore, and backbone first, and then runs the callback function. The code of the main module is written in the callback function.
Iv. Module Loading
In the last example in the previous section, the main module's dependency module is ['jquery ', 'underscore', 'backone']. By default, require. js assumes that the three modules are in the same directory as main. js. The file names are jquery. js, underscore. js, and backbone. js, and then load them automatically.
Using the require. config () method, we can customize the loading behavior of the module. Require. config () is written in the header of the main module (main. js. The parameter is an object. The paths attribute of this object specifies the loading path of each module.Copy codeThe Code is as follows: require. config ({
Paths :{
"Jquery": "jquery. min ",
"Underscore": "underscore. min ",
"Backbone": "backbone. min"
}
});
The above Code provides the file names of the three modules. The path is in the same directory (js subdirectory) as main. js by default ). If these modules are in other directories, such as the js/lib directory, there are two writing methods. One is to specify paths one by one.Copy codeThe Code is as follows: require. config ({
Paths :{
"Jquery": "lib/jquery. min ",
"Underscore": "lib/underscore. min ",
"Backbone": "lib/backbone. min"
}
});
The other is to directly change the base Directory (baseUrl ).Copy codeThe Code is as follows: require. config ({
BaseUrl: "js/lib ",
Paths :{
"Jquery": "jquery. min ",
"Underscore": "underscore. min ",
"Backbone": "backbone. min"
}
});
If a module is on another host, you can directly specify its url, for example:Copy codeThe Code is as follows: require. config ({
Paths :{
"Jquery": "https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min"
}
});
Require. js requires that each module is a separate js file. In this way, if multiple modules are loaded, multiple HTTP requests will be sent, which will affect the webpage loading speed. Therefore, require. js provides an optimization tool. After the module is deployed, you can use this tool to merge multiple modules into one file to reduce the number of HTTP requests.
V. AMD module writing
The modules loaded by require. js adopt AMD specifications. That is to say, the module must be written according to AMD regulations.
Specifically, the module must be defined using a specific define () function. If a module does not depend on other modules, it can be directly defined in the define () function.
Suppose there is a math. js file, which defines a math module. Then, math. js should write as follows:
// Math. jsCopy codeThe Code is as follows: define (function (){
Var add = function (x, y ){
Return x + y;
};
Return {
Add: add
};
});
The loading method is as follows:
// Main. jsCopy codeThe Code is as follows: require (['Math'], function (math ){
Alert (math. add (1, 1 ));
});
If this module depends on other modules, the first parameter of the define () function must be an array that specifies the dependency of this module.Copy codeThe Code is as follows: define (['mylib'], function (myLib ){
Function foo (){
MyLib. doSomething ();
}
Return {
Foo: foo
};
});
When the require () function loads the above module, it loads the myLib. js file first.
6. Load nonstandard modules
Theoretically, the modules loaded by require. js must be defined by the define () function according to AMD specifications. But in fact, although some popular function libraries (such as jQuery) Comply with AMD specifications, more libraries do not.So can require. js load nonstandard modules?
The answer is yes.
Before such modules are loaded with require (), use the require. config () method to define some of their features.
For example, neither underscore nor backbone libraries are written in AMD specifications. To load them, you must first define their features.Copy codeThe Code is as follows: require. config ({
Shim :{
'Underscore ':{
Exports :'_'
},
'Background ':{
Deps: ['underscore ', 'jquery'],
Exports: 'backone'
}
}
});
Require. config () accepts a configuration object. In addition to the paths attribute mentioned earlier, this object also has a shim attribute, which is used to configure incompatible modules. Specifically, each module must define (1) the exports value (output variable name), indicating the name used for external calls of this module; (2) deps array, indicating the dependency of this module.
For example, jQuery plug-ins can be defined as follows:Copy codeThe Code is as follows: shim :{
'Jquery. scroll ':{
Deps: ['jquery '],
Exports: 'jquery. fn. scroll'
}
}
VII. require. js plug-in
Require. js also provides a series of plug-ins to implement some specific functions.
The domready plug-in allows the callback function to run after the DOM structure of the page is loaded.Copy codeThe Code is as follows: require (['domainready! '], Function (doc ){
// Called once the DOM is ready
});
The text and image extensions allow require. js to load text and image files.Copy codeThe Code is as follows: define ([
'Text! Review.txt ',
'Image! Cat.jpg'
],
Function (review, cat ){
Console. log (review );
Document. body. appendChild (cat );
}
);
Similar plug-ins include json and mdown, which are used to load json files and markdown files.
(End)