JavaScript Modular Development Explanation and example tutorial

Source: Internet
Author: User
Tags extend instance method json jquery library

Use require to load jslite, Zepto, and jquery methods, which are the same type of libraries so they are loaded, and here is an instance.

Requirejs Reference instance method

The goal of Requirejs is to encourage the modularity of code, which uses a script loading step that differs from the traditional <script> tag. It can be used to speed up and optimize the code, but its main purpose is to modularize the code. It encourages replacing the URL address with a module ID when using script.

1. Requirejs for GitHub
Https://github.com/jrburke/requirejs
2. Requirejs official website
http://requirejs.org/
3. Jslite 1.1.5
Https://github.com/JSLite/JSLite/releases

directory Structure

Go to Requirejs official website to download, put Require.js into lib directory, download jslite 1.1.5 into lib directory.

├──app.js
├──index.html
└──lib
├──jslite.js
├──extend-jslite.js
└──require.js

File Contents

App.js

Requirejs.config ({
Paths: {
Jslite: ' Lib/extend-jslite ',
Zepto: ' Lib/zepto '
}
});
Require ([' jslite '], function (j) {
Console.log ("z,$:", J (' body '))
});

Index.html

<! DOCTYPE html>
<meta charset= "UTF-8" >
<title>Document</title>
<script type= "Text/javascript" data-main= "App.js" src= "Lib/require.js" ></script>
<body>
</body>

Extend-jslite.js

Define ([
' Lib/jslite '
], function (a) {
"Use strict";
Window. Jslite = Jslite
If ' $ ' or ' jQuery ' isn't yet defined, point them to ' jslite '
' $ ' in window | | (window.$ = jslite)
' JQuery ' in Window | | (Window.jquery = jslite)
return jslite;
});

noun explanation

Commonjs

COMMONJS is the specification of the server-side module, which Node.js adopted.

According to the COMMONJS specification, a separate file is a module. The load module uses the Require method, which reads a file and executes it, and finally returns the exports object inside the file.

Module file Foobar.js

Private variable
var test = 123;
Public method
function Foobar () {
This.foo = function () {
Do someing ...
}
This.bar = function () {
Do someing ...
}
}

The methods and variables on the exports object are common
var foobar = new Foobar ();
Exports.foobar = Foobar;

The Require method reads the Foobar.js file by default and can omit the JS suffix

var test = require ('./foobar '). Foobar;
Test.bar ();

The COMMONJS load module is synchronized, so only the load completes to perform the subsequent operation. Like Node.js is mainly used for server programming, loaded module files are generally already existing local hard disk, so load faster, do not consider the way of asynchronous loading, so the COMMONJS specification is more applicable. However, if the browser environment, to load the module from the server, this is the asynchronous mode must be used. So there is the AMD CMD solution. A Gentle Browserify Walkthrough

AMD

AMD (Asynchromous module definition) is requirejs in the promotion process of the modular definition of the standard output AMD asynchronous loading module. Its modules support various types of modules, such as Object function constructor string json.

Application of the AMD specification to the Define method definition module.

By introducing dependencies through arrays, the callback function passes in the form parameter to the dependency
define ([' SomeModule1 ', ' someModule2 '], function (SomeModule1, someModule2) {

function foo () {
Someing
Somemodule1.test ();
}

return {Foo:foo}
});

The AMD specification allows the output module to be compatible with the COMMONJS specification, when the Define method is as follows:

Define (function (Require, exports, module) {

var reqmodule = require ("./somemodule");
Requmodule.test ();

Exports.asplode = function () {
Someing
}
});

CMD

CMD is the normalized output of seajs in the process of popularization.

The difference between CMD and AMD has the following points:

1. For dependent modules AMD is ahead of schedule, CMD is deferred execution. However, Requirejs from 2.0, also changed to be able to delay the execution (according to the different writing, the processing method does not pass).

2.CMD is highly reliant on proximity, AMD is highly reliant on front-end.

Amd
define (['. a ', './b '], function (A, b) {

Rely on writing it from the beginning.
A.test ();
B.test ();
});

Cmd
Define (function (Requie, exports, module) {

Reliance can be written near
var a = require ('. a ');
A.test ();

...
Soft dependent
if (status) {

var B = Requie ('./b ');
B.test ();
}
});

Although AMD also supports CMD notation, relying on the predecessor is the default module definition of the official document.

The 3.AMD API default is one when multiple uses, cmd strict distinction is highly respected responsibility single. For example: AMD require is divided into global and local. CMD does not have the global require, provides the seajs.use () to implement the module system loading to start. Each API in CMD is simple and pure. A detailed explanation of the difference

UMD

UMD is a blend of AMD and COMMONJS
AMD browsers The first principle of the development of asynchronous loading modules.
COMMONJS module with the first principle of server development, the choice of synchronous loading, its module without packaging (unwrapped modules).
This forces people to come up with another more general pattern UMD (Universal Module Definition). Want to resolve Cross-platform solutions.

UMD first determines whether the Node.js module (exports) is present or not, and the Node.js module mode is used.
In determining whether or not to support AMD (define exists), the presence of AMD is used to load modules.

(function (root, factory) {
var jslite = factory (root);
if (typeof define = = ' function ' && define.amd) {
Amd
define ([], factory);
Define (' Jslite ', function () {return jslite;});
else if (typeof exports = = ' object ') {
Node.js
Module.exports = Jslite;
} else {
Browser Globals
Root. Jslite = Jslite;
}
} (this, function () {
Module ...
});


JavaScript Modular Programming

the writing of the module

As Web sites become "Internet apps," JavaScript code embedded in Web pages is growing larger and more complex.

Web pages are more and more like desktop programs, need a team division of work, progress management, unit testing and so on ... Developers have to use the software engineering approach to manage the business logic of Web pages.

JavaScript modular programming has become an urgent requirement. Ideally, developers only need to implement the core business logic, and others can load the modules that others have already written.

However, JavaScript is not a modular programming language, and it does not support "classes" (class), not to mention "modules" (module). (The sixth edition of the ECMAScript Standard, which is being developed, will formally support "classes" and "modules", but it still takes a long time to put into practice.) )

The JavaScript community has made a lot of effort to implement the "module" effect in the existing operating environment. This paper summarizes the best practices of current "JavaScript modular Programming", and explains how to put it into practice. Although this is not a beginner's tutorial, you can understand just a little bit about the basic syntax of JavaScript.

first, the original wording

A module is a set of methods for implementing a particular function.

Just put the different functions (and the variables of the record state) simply together, even a module.

function M1 () {
//...
}

function m2 () {
//...
}

The above function m1 () and M2 () to form a module. When used, call directly on the line.

The disadvantage of this approach is obvious: "pollution" of the global variable, can not guarantee that no variable name conflicts with other modules, and module members do not see a direct relationship.

Ii. The wording of the object

To solve the above shortcomings, the module can be written as an object, all module members are placed inside this object.

var module1 = new Object ({

_count:0,

M1:function () {
//...
},

M2:function () {
//...
}

});

The functions above M1 () and M2 () are encapsulated in the Module1 object. When used, the object's properties are invoked.

MODULE1.M1 ();

However, such writing exposes all module members and the internal state can be externally rewritten. For example, external code can directly change the value of an internal counter.

Module1._count = 5;

third, immediately execute function writing

You can achieve the purpose of not exposing private members by using the Execute function now (immediately-invoked function Expression,iife).

var Module1 = (function () {

var _count = 0;

var m1 = function () {
//...
};

var m2 = function () {
//...
};

return {
M1:M1,
M2:m2
};

})();

Using the above notation, the external code cannot read the internal _count variable.

Console.info (Module1._count); Undefined

Module1 is the basic writing of JavaScript modules. Below, and then to the processing of this writing.

Four, enlarge the mode

If a module is large, it must be divided into several parts, or a module needs to inherit another module, then it is necessary to adopt the "magnification mode" (augmentation).

var Module1 = (function (mod) {

MOD.M3 = function () {
//...
};

return mod;

}) (Module1);

The above code adds a new method M3 () to the Module1 module, and then returns the new Module1 module.

v. Wide magnification mode (Loose augmentation)

In a browser environment, parts of a module are usually retrieved from the web, and sometimes it is not possible to know which part will be loaded first. If the previous section is written, the first part of the execution may load a nonexistent object, and the "wide magnification mode" is used.

var Module1 = (function (mod) {

//...

return mod;

}) (Window.module1 | | {});

In contrast to "zoom mode", the "wide magnification mode" is the "execute function now" argument can be an empty object.

vi. input Global Variables

Independence is an important feature of the module, it is best not to interact directly with other parts of the program.

In order to call global variables inside a module, you must explicitly enter the other variables into the module.

var Module1 = (function ($, YAHOO) {

//...

}) (JQuery, YAHOO);

The above Module1 modules need to use the jquery library and Yui Library, the two libraries (in fact, two modules) as a parameter input module1. In addition to ensuring the independence of the module, it makes the dependencies between the modules become apparent.

AMD Specifications

Specification of Modules

First think about why the module is important?

Because of the module, we can more easily use other people's code, want what function, loaded what module.

However, this has a prerequisite, that is, we must write the same way the module, otherwise you have your writing, I have my writing, it is not a mess of the set! This is even more important given the fact that JavaScript modules are not yet officially regulated.

At present, there are two kinds of standard JavaScript modules: Commonjs and AMD. I mainly introduce AMD, but first start with Commonjs.

Eight, Commonjs

2009, US programmer Ryan Dahl created the Node.js project, which uses JavaScript language for server-side programming.

This sign "JavaScript modular Programming" is officially born. Because frankly speaking, in the browser environment, no module is not particularly big problem, after all, the complexity of the Web page program is limited, but on the server side, must have a module, and the operating system and other applications to interact, or simply can not program.

The modular system of Node.js is realized by reference to COMMONJS specification. In Commonjs, there is a global method require (), which is used to load modules. Assuming there is a mathematical module math.js, you can load it like this.

var math = require (' math ');

You can then invoke the method provided by the module:

var math = require (' math ');

Math.add (2,3); 5

Because this series is mainly for browser programming, does not involve node.js, so to Commonjs do not do more introduction. As long as we know here, require () is used to load the module.

Nine, browser environment

With the server-side module, it's natural for everyone to want the client module. And it's best to be compatible, a module that doesn't have to be modified, can run on both the server and the browser.

However, due to a significant limitation, the COMMONJS specification does not apply to the browser environment. or the previous section of the code, if run in the browser, there will be a big problem, you can see it?

var math = require (' math ');

Math.add (2, 3);

The second line, Math.add (2, 3), runs after the first line require (' math '), so the math.js load must be completed. In other words, if the load time is very long, the entire application will stop there and so on.

This is not a problem for the server side, because all the modules are stored on the local hard drive, can be completed synchronously, waiting time is the hard disk read time. However, for browsers, this is a big problem, because the module is placed on the server side, waiting time depends on the speed of the network, may have to wait for a long time, the browser in the state of "suspended animation."

Therefore, the browser-side module cannot be "Synchronous load" (synchronous) and can only be used for "asynchronous loading" (asynchronous). This is the background of the birth of AMD specification.

10, AMD

AMD is the abbreviation for "Asynchronous module definition", meaning "asynchronous modular definition". It loads the module asynchronously, and the load of the module does not affect the operation of the statement behind it. All statements that rely on this module are defined in a callback function, and the callback function will not run until the load is complete.

AMD also uses the Require () statement to load modules, but unlike COMMONJS, it requires two parameters:

Require ([module], callback);

The first parameter [module], which is an array whose members are the modules to be loaded, and the second parameter callback, is the callback function after the success of the load. If you rewrite the previous code into AMD, this is the following:

Require ([' math '], function (math) {

Math.add (2, 3);

});

Math.add () is not synchronized with the math module, and the browser does not feign death. So it's clear that AMD is better suited to the browser environment.

Currently, there are two JavaScript libraries that implement AMD specifications: Require.js and Curl.js.

the use of Require.js

One, why should use Require.js?

At the earliest, all of the JavaScript code was written in a file, and it was enough to load the file. Later, more and more code, a file is not enough, must be divided into multiple files, sequentially loaded. The following page code, I believe many people have seen.

<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 sequentially.

There are a lot of drawbacks to this way of writing. First of all, when loading, the browser will stop the page rendering, the more loading files, the longer the page will lose the response time, and secondly, because the JS file dependencies, Therefore, we must strictly ensure the loading sequence (such as the above example of the 1.js to be in front of 2.js), the most dependent module must be put to the last load, when the dependency is very complex, code writing and maintenance will become difficult.

The birth of require.js is to solve these two problems:

1 to achieve the asynchronous loading of JS files, to avoid web page loss of response;
2 management of the dependencies between modules, easy to write code and maintenance.

second, the loading of require.js

The first step in using Require.js is to go to the official website and download the latest version first.

After downloading, assume that it is placed under the JS subdirectory, you can load.

<script src= "Js/require.js" ></script>

One might think that loading the file could also cause the web to lose its response. There are two solutions, one is to put it at the bottom of the page load, the other is written as follows:

<script src= "js/require.js" defer async= "true" ></script>

The Async property indicates that the file needs to be loaded asynchronously to prevent the Web page from losing its response. IE does not support this property, only support defer, so put the defer also write.

After loading the require.js, the next step is to load our own code. Suppose our own code file is Main.js, also placed under the JS directory. Well, just write the following:

<script src= "Js/require.js" data-main= "Js/main" ></script>

The function of the Data-main property is to specify the main module of the Web page program. In the above example, is the JS directory below the main.js, this file will be the first to be require.js loaded. Because the require.js default file suffix name is js, you can abbreviate main.js to main.

third, the main module of the formulation

The main.js in the previous section, which I call the "main module", means the entry code for the entire page. It's kind of like the C language main () function, where all the code starts running.

Here is a look, how to write Main.js.

If our code does not rely on any other modules, you can write JavaScript code directly.

Main.js

Alert ("Load succeeded!") ");

But in this case, there is no need to use require.js. The real common scenario is that the main module relies on other modules, and the Require () function defined by the AMD specification is used.

Main.js

Require ([' Modulea ', ' Moduleb ', ' Modulec '], function (Modulea, Moduleb, Modulec) {

Some code here

});

The Require () function accepts two parameters. The first argument is an array, represents the dependent module, the example is [' Modulea ', ' Moduleb ', ' Modulec '], where the main module relies on these three modules; The second parameter is a callback function, which is invoked when the module specified by the current plane is successfully loaded. The loaded modules are passed in as arguments to the function, which can be used inside the callback function.

Require () asynchronously loads Modulea,moduleb and Modulec, the browser does not lose its response, and its specified callback function, which runs only after the previous module has been successfully loaded, solves the dependency problem.

Next, let's look at a practical example.

Assuming that the main module relies on the three modules of jquery, underscore, and backbone, Main.js can write this:

Require ([' jquery ', ' underscore ', ' backbone '], function ($, _, backbone) {

Some code here

});

Require.js will load jquery, underscore, and backbone before running the callback function. The code for the main module is written in the callback function.

four, the module loading

In the last example of the previous section, the main module's dependency module is [' jquery ', ' underscore ', ' backbone ']. By default, Require.js assumes that these three modules are in the same directory as main.js, the file names are jquery.js,underscore.js and Backbone.js, and then are automatically loaded.

Using the Require.config () method, we can customize the loading behavior of the module. Require.config () is written on the head of the main module (main.js). The parameter is an object that specifies the load path of each module in the paths property of the object.

Require.config ({

Paths: {

"jquery": "Jquery.min",
"Underscore": "Underscore.min",
"Backbone": "Backbone.min"

}

});

The above code gives the file name of three modules, the path defaults to main.js in the same directory (JS subdirectory). If these modules are in other directories, such as the Js/lib directory, there are two ways to do it. One way is to specify the path.

Require.config ({

Paths: {

"jquery": "Lib/jquery.min",
"Underscore": "Lib/underscore.min",
"Backbone": "Lib/backbone.min"

}

});

The other is to change the base directory directly (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 specify its URL directly, for example:

Require.config ({

Paths: {

"jquery": "Https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min"

}

});

Require.js requirements, each module is a separate JS file. This way, if you load multiple modules, you emit multiple HTTP requests that affect the speed at which the Web page loads. As a result, Require.js provides an optimization tool that, when deployed, can be used to merge multiple modules into a single file, reducing the number of HTTP requests.

Five, the AMD module's formulation

Require.js loaded modules, using AMD specifications. In other words, the module must be written in accordance with AMD rules.

Specifically, the module must be defined with a specific define () function. If a module does not rely on other modules, it can be directly defined in the Define () function.

Suppose you now have a math.js file that defines a math module. So, Math.js is going to write this:

Math.js

Define (function () {

var add = function (x,y) {

return x+y;

};

return {

Add:add
};

});

The loading method is as follows:

Main.js

Require ([' math '], function (math) {

Alert (Math.add (1,1));

});

If the module also relies on other modules, then the first parameter of the Define () function must be an array that indicates the dependency of the module.

define ([' mylib '], function (mylib) {

function foo () {

Mylib.dosomething ();

}

return {

Foo:foo

};

});

When the require () function loads the above module, the Mylib.js file is loaded first.

Vi. loading non-canonical modules

In theory, Require.js loaded modules must be in accordance with the AMD specification, using the Define () function defined modules. But in fact, although there are already some popular libraries (such as jquery) that conform to AMD specifications, more libraries do not match. So is require.js capable of loading non-standard modules?

The answer is OK.

Such modules must first define some of their characteristics using the Require.config () method before they are loaded with require ().

For example, both the underscore and backbone libraries are not written using the AMD specification. If you want to load them, you must first define their characteristics.

Require.config ({

Shim: {

' Underscore ': {
Exports: ' _ '
},

' Backbone ': {
Deps: [' underscore ', ' jquery '],
Exports: ' Backbone '
}

}

});

Require.config () accepts a configuration object that, in addition to the previously mentioned paths attribute, has a shim property that is specifically configured to configure incompatible modules. Specifically, each module defines (1) The exports value (the output variable name) indicating the name of the module outside the call, and (2) the Deps array, indicating the module's dependencies.

For example, the jquery plug-in can be defined as:

Shim: {

' Jquery.scroll ': {

Deps: [' jquery '],

Exports: ' JQuery.fn.scroll '

}

}

Seven, Require.js plug-ins

Require.js also offers a range of plug-ins to implement certain features.

The Domready plug-in allows the callback function to run after the page DOM structure has completed loading.

Require ([' domready! '], function (DOC) {

Called Once the DOM is ready

});

The text and image plug-ins are allowed to load require.js and picture files.

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.

Related Article

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.