Home > Article > Web Front-end > A brief analysis of modular writing of js require.js
requirejs is a JavaScript file and module loader. requireJS allows you to separate your JavaScript code into files and modules while managing the dependencies between each module.
The goal of RequireJS is to encourage modularization of code, and it uses a script loading step that is different from the traditional "script" tag. Using RequireJS to load modular scripts will improve the loading speed and quality of your code.
1. Why use require.js?
In the earliest days, all Javascript codes were written in one file, and it was enough to load this one file. Later, there were more and more codes, and one file was no longer enough. It had to be divided into multiple files and loaded in sequence. I believe many people have seen the following web page code:
<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 way of writing has great shortcomings.
First of all, when loading, the browser will stop rendering the web page. The more files are loaded, the longer the web page will lose response.
Due to dependencies between js files, it must Strictly ensure the loading order (for example, 1.js in the above example must be before 2.js), and the module with the greatest dependency must be loaded last. When dependencies are complex, code writing and maintenance will become difficult. .
require.js was born to solve these two problems:
Realize asynchronous loading of js files to avoid web pages losing response;
Manage dependencies between modules It makes it easier to write and maintain code.
2. Loading require.js
The first step to use require.js is to download the latest version from the official website.
After downloading, it is assumed that it is placed under the js subdirectory and it can be loaded.
7c439788e166f531c8ad0b30265c71032cacc6d41bbb37262a98f745aa00fbf0
Some people may think that loading this file may also cause the web page to lose response. There are two solutions:
One is to load it at the bottom of the web page, and the other is to write it as follows:
6a7b16acd5fd2d3ee2a4cf732fecd7662cacc6d41bbb37262a98f745aa00fbf0
async attribute indicates that this file needs to be loaded asynchronously to avoid the web page becoming unresponsive. IE does not support this attribute and only supports defer, so defer is also written.
After loading require.js, the next step is to load our own code. Assume that our own code file is main.js and is also placed under the js directory. Then, just write it as follows:
35be17e58c59207c30045b58673f385a2cacc6d41bbb37262a98f745aa00fbf0
The data-main attribute is used to specify the main module of the web program.
In the above example, it is main.js under the js directory. This file will be loaded by require.js first. Since the default file extension of require.js is js, main.js can be abbreviated to main.
3. How to write the main module
The main.js in the previous section, I call it the "main module", which means the entry code of the entire web page. It's a bit like the main() function in C language, all code starts running from here.
Let’s take a look at how to write main.js.
If our code does not depend on any other modules, we can write javascript code directly.
// main.js alert("加载成功!"); 但这样的话,就没必要使用require.js了。真正常见的情况是,主模块依赖于其他模块,这时就要使用AMD规范定义的的require()函数。 // main.js require(['moduleA', 'moduleB', 'moduleC'], function (moduleA, moduleB, moduleC){ // some code here });
require() function accepts two parameters. The first parameter:
An array indicating the modules it depends on. The above example is ['moduleA', 'moduleB', 'moduleC'], that is, the main module depends on these three modules;
A callback function, which will be called after all the previously specified modules are loaded successfully. Loaded modules will be passed into this function as parameters, so these modules can be used inside the callback function.
require() loads moduleA, moduleB and moduleC asynchronously, and the browser will not lose response; the callback function it specifies will only run after the previous modules are loaded successfully, solving the dependency problem.
Below, let’s look at a practical example.
Assuming that the main module depends on the three modules jquery, underscore and backbone, main.js can be written like this:
require(['jquery', 'underscore', 'backbone'], function ($, _, Backbone){ // some code here });
require.js will first load jQuery, underscore and backbone, and then run Callback. The code of the main module is written in the callback function.
4. Module loading
In the last example of the previous section, the dependent modules of the main module are ['jquery', 'underscore', 'backbone']. By default, require.js assumes that these three modules are in the same directory as main.js, with the file names being jquery.js, underscore.js and backbone.js, and then loads them automatically.
Using the require.config() method, we can customize the loading behavior of the module. require.config() is written at the head of the main module (main.js). The parameter is an object, and the paths attribute of this object specifies the loading path of each module.
require.config({ paths: { "jquery": "jquery.min", "underscore": "underscore.min", "backbone": "backbone.min" } });
The above code gives the file names of the three modules. The path defaults to the same directory as main.js (js subdirectory). If these modules are in other directories, such as the js/lib directory, there are two ways to write them.
One is to specify the paths one by one.
require.config({ baseUrl: "js/lib", paths: {"jquery": "jquery.min", "underscore": "underscore.min", "backbone": "backbone.min"} });
The other is to directly change the base directory (baseUrl).
require.config({ baseUrl: "js/lib", paths: { "jquery": "jquery.min", "underscore": "underscore.min", "backbone": "backbone.min" } });
If a module is on another host, you can also directly specify its URL, such as:
require.config({ paths: { "jquery": "https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min" } });
require.js要求:
每个模块是一个单独的js文件。这样的话,如果加载多个模块,就会发出多次HTTP请求,会影响网页的加载速度。因此,require.js提供了一个优化工具,当模块部署完毕以后,可以用这个工具将多个模块合并在一个文件中,减少HTTP请求数。
五、AMD模块的写法
require.js加载的模块,采用AMD规范。也就是说,模块必须按照AMD的规定来写。
具体来说,就是模块必须采用特定的define()函数来定义。如果一个模块不依赖其他模块,那么可以直接定义在define()函数之中。
假定现在有一个math.js文件,它定义了一个math模块。那么,math.js就要这样写:
// math.js define(function (){ var add = function (x,y){ return x+y; }; return { add: add }; });
加载方法如下:
// main.js require(['math'], function (math){ alert(math.add(1,1)); });
如果这个模块还依赖其他模块,那么define()函数的第一个参数,必须是一个数组,指明该模块的依赖性。
define(['myLib'], function(myLib){ function foo(){ myLib.doSomething(); } return { foo : foo }; });
当require()函数加载上面这个模块的时候,就会先加载myLib.js文件。
六、加载非规范的模块
理论上,require.js加载的模块,必须是按照AMD规范、用define()函数定义的模块。但是实际上,虽然已经有一部分流行的函数库(比如jQuery)符合AMD规范,更多的库并不符合。那么,require.js是否能够加载非规范的模块呢?
回答是可以的。
这样的模块在用require()加载之前,要先用require.config()方法,定义它们的一些特征。
举例来说,underscore和backbone这两个库,都没有采用AMD规范编写。如果要加载它们的话,必须先定义它们的特征。
require.config({ shim: { 'underscore': { exports: '_' }, 'backbone': { deps: ['underscore', 'jquery'], exports: 'Backbone' } } });
require.config()接受一个配置对象,这个对象除了有前面说过的paths属性之外,还有一个shim属性,专门用来配置不兼容的模块。具体来说,每个模块要定义(1)exports值(输出的变量名),表明这个模块外部调用时的名称;(2)deps数组,表明该模块的依赖性。
比如,jQuery的插件可以这样定义:
shim: { 'jquery.scroll': { deps: ['jquery'], exports: 'jQuery.fn.scroll' } }
七、require.js插件
require.js还提供一系列插件,实现一些特定的功能:
domready插件,可以让回调函数在页面DOM结构加载完成后再运行。
require(['domready!'], function (doc) { // called once the DOM is ready });
text和image插件,则是允许require.js加载文本和图片文件。
define([ 'text!review.txt', 'image!cat.jpg' ], function (review, cat) { console.log(review); document.body.appendChild(cat); } );
类似的插件还有json和mdown,用于加载json文件和markdown文件。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,同时也希望多多支持PHP中文网!
更多浅析js的模块化编写 require.js相关文章请关注PHP中文网!