Front-end modularity

Source: Internet
Author: User

Front-end Modular development One, why to be modular development 1. Naming conflicts

In the actual work, I believe that everyone has encountered such a problem: I myself test the code and the merger after the conflict between you? Clearly project needs to introduce the package are introduced how also reported missing package? ...... These problems are summed up as namespace collisions and file dependency loading order issues. For the simplest example of a namespace conflict, consider the following code:

Test.html

<! DOCTYPE html>

Module1.js

/** * Created by user on 2016/5/14. */var module=function () {    cosonle.log (' I am Module1.js ');}

Module2.js

/** * Created by user on 2016/5/14. */var module=function () {    console.log ("I am Module2.js");}

Results output when test.html is run:

Obviously because the function name in the first two JS files is consistent with the inside of the HTML, it will only execute the last module () function, and in team work you will not know whether the function or variable that you write will conflict with others, and there are some namespaces that refer to Java in order to solve such a problem:

Test.html

<! DOCTYPE html>

Module1.js

/** * Created by user on 2016/5/14. */var module1={};module1.fn={};module1.fn.utils={};module1.fn.utils.module=function () {    console.log ("I am Module1.js ");}

Module2.js

/** * Created by user on 2016/5/14. */var module2={};module2.fn={};module2.fn.utils={};module2.fn.utils.module=function () {    console.log ("I am Module2.js ");}

Then run test.html and you can enter all the values in the module.

But is it a bit verbose to write so long a namespace just to call a method? Here I'm just trying to restore the problem in the actual project development process with a longer namespace name. Build the concept of namespaces in the front-end and push Yahoo! 's YUI2 project. Here is a real code from an open source project from Yahoo!.

if (org.cometd.Utils.isString (response)) {    return Org.cometd.JSON.fromJSON (response);  }  if (Org.cometd.Utils.isArray (response)) {    return response;  }  

As the front-end industry benchmark, the YUI team is determined to solve this problem. In the YUI3 project, a new namespace mechanism was introduced.

YUI (). Use (' node ', function (Y) {    ////node module already loaded    ///The following can be called by Y to call    var foo = y.one (' #foo ');  

YUI3 is a good solution to the problem of long namespaces through the sandbox mechanism. However, new problems have also been brought about.

YUI (). Use (' A ', ' B ', function (Y) {    y.foo ();    Is the Foo method provided by module A or B?    How do I avoid collisions if modules A and B both provide the Foo method?  });  

Let's not announce how to solve such problems, and then look at the next question.

2. File dependencies

The basic principle of development is not to repeat, when there are many places in the project to use the same function, we should find a way to pull it out to make util, when needed to call it directly, But if your later code depends on Util.js and you forget to call or call the wrong order, the code will report a variety of errors, for the simplest example, we all know that Bootstrap relies on jquery, each time it is introduced to put jquery in front of Bootstrap, One or two similar dependencies you may remember, but if you have a lot of such dependencies in a huge project, can you remember that clearly? As projects become more complex, the dependencies between many files can often be maddening. The following questions, I believe, happen every day in a real way.

1. The universal group updated the front-end base class library, but it is difficult to promote the whole station upgrade.

2. The business group wanted to use a new generic component, but found that it could not be easily done with a few lines of code.

3. An old product to be new, the final evaluation can only be based on the old class library to continue to develop.

4. Company integration Business, a two product line to be merged. The results found a front-end code conflict.

5 .....

Many of these problems are due to the fact that file dependencies are not well managed. In the front page, most of the script's dependencies are still guaranteed by human flesh. When the team compares hours, there's no problem. When the team is getting bigger and the business is getting more and more complex, the dependency problem will become a big problem if not solved.

Ii. What is modular development

Modular development to reduce the coupling of code, the significance of modularity is to maximize the design reuse, with the fewest modules, components, more quickly meet more personalized needs. Because of the module, we can more easily use other people's code, want what function, load what module. But always can not write it, there must be norms to let everyone abide by it.

1. Currently, modular development is:

1. Server-side specification: CommonJs---Nodejs use of the specification,

2. Browser-side specification: AMD---requirejs foreign relative popularity (official website)

CMD--SEAJS Domestic Relative popularity (official website)

2.SeaJS vs. Requirejs:

A. For dependent modules, AMD is implemented in advance and CMD is deferred;

B. cmd is highly dependent on the nearest, AMD is highly dependent on the predecessor;

C. AMD's API default is one when multiple uses, the CMD API is strictly differentiated, advocating a single responsibility.

Third, how to use modular development

Look directly at the small computer code written below!

Test_seajs.html (The premise is to download Sea.js package Oh, I was directly using the command npm install seajs download. )

<!    DOCTYPE html>
The contents of the Calculator.js file are as follows:
/** * Created by user on 2016/5/14. *///defines a module that follows the SEAJS notation define (function (Require, exports, module) {  ///Here is the private space of the module/  /define the private member of the module/  / Load convertor.js module  var convertor = require ('./convertor.js ');  function Add (A, b) {    return Convertor.converttonumber (a) + Convertor.converttonumber (b);  }  function Subtract (A, b) {    return Convertor.converttonumber (a)-convertor.converttonumber (b);  }  function Multiply (A, b) {    return Convertor.converttonumber (a) * Convertor.converttonumber (b);  }  function Divide (A, b) {    return Convertor.converttonumber (a)/Convertor.converttonumber (b);  }  Exposing the public member of the module  exports.add = add;  Exports.subtract = subtract;  exports.multiply = multiply;  Exports.divide = divide;});
Convertor.js content is as follows:
/** * Conversion module, exporting members: Converttonumber */define (function (Require, exports, module) {  //expose some conversion logic  Exports.converttonumber = function (input) {    return parsefloat (input);  }});

Operation Result:

Summary: In Test_ Seajs.html with Seajs.use introduced Calculator.js file, and in Calcultor.js file require Convertor.js file, so do not care about each JS dependency, because in its JS internal has been loaded completed. Each introduction of a JS in its callback function to execute its JS method, thereby resolving the naming conflict problem.

Four, Seajs exposed interface

Careful classmate may have found me in the above calculator.js with exports.xx exposed the method in the JS file, if there are many many methods, with exports are listed to more trouble Ah, actually can also use Module.exports to expose its interface. As follows:

Test-exports.html

<! DOCTYPE html>

Person.js

/** * Created by user on 2016/5/14. *///defines a module that follows the SEAJS notation define (function (Require, exports, module) {     function person (name, age, gender) {       this.name = name;       This.age = age;       This.gender = gender;     }     Person.prototype.sayHi = function () {       console.log (' hi! I\ ' m a coder, my name is ' + THIS.name ';     };     Exports. Person=person;    Module.exports=person;});

At this point, the question comes again, if they both exist at the same time who should prevail? The answer is module.exports, because exports is the shortcut to Module.exports, and the original address is still pointed to. Look at the code:

<! DOCTYPE html>

Person.js

Define a module that follows the SEAJS notation define (function (Require, exports, module) {    module.exports={name: ' Haoxiaoli '};    Exports.name= ' HXL ';});

Results:

Finally, there is a return that can also expose the interface. Their priority is: Return>module.exports>exports, see case:

Person.js

Define a module that follows the SEAJS notation define (function (Require, exports, module) {    module.exports={name: ' Haoxiaoli '};    Exports.name= ' HXL ';    return {name: ' Hello world! '};});

Results:

Category: JavaScript

Front-end modularity

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.