JS Modular Development--front-end modularity

Source: Internet
Author: User

In the early stages of JavaScript development is to achieve simple page interaction logic, a few words can be, now CPU, browser performance has been greatly improved, many page logic migrated to the client (form validation, etc.), With the advent of the web2.0 era, Ajax technology has been widely used, jquery and other front-end libraries emerge, the front-end code is expanding

This is when JavaScript is anchored as an embedded scripting language, and JavaScript does not provide any obvious help for the organization's code, not even the concept of classes, let alone modules. JavaScript's extremely simple code organization specification is not enough to harness such a large scale of code

Module

Since JavaScript cannot handle such a large-scale code, we can learn from how other languages deal with large-scale programming, there is an important concept in Java-- package logically related code organized into the same package, within the package is a relatively independent kingdom, Don't worry about naming conflicts or anything, what if you use them externally? Directly import corresponding to the package can be

import java.util.ArrayList;

Unfortunately JavaScript is positioned at design time and does not provide similar functionality, and developers need to emulate similar capabilities to isolate and organize complex JavaScript code, which we call modularity.

A module is to implement a specific function of the file, with the module, we can more easily use other people's code, want what function, load what module. Module development needs to follow certain specifications, fragmentation is all messed up

The process of the formation of norms is painful, the pioneer of the front-end in the slash-and-burn, nascent stage, the development to take shape now, a simple understanding of this extraordinary course

function encapsulation

When we talk about functions, a function is a function of a set of statements that implement a particular logic, and the scope of JavaScript is based on functions, so it is natural to take the function as the first step of modularization, and to write several related functions in a file is the first module.

function fn1(){statement}function fn2(){statement}

So after the need to clip in the function of the file, call the function can be

The disadvantage of this approach is obvious: polluting global variables, there is no guarantee that the variable name conflicts with other modules, and there is no relationship between module members.

Object

In order to solve the above problem, the object's writing came into being, and all the module members can be encapsulated in an object.

var myModule = {var1: 1,var2: 2,fn1: function(){},fn2: function(){}}

This allows us to refer to the corresponding file when we want to invoke the module, and then

myModule.fn2();

This avoids the variable pollution, as long as the module name is only guaranteed, and members within the same module have a relationship

Seemingly good solution, but also flawed, external can be arbitrarily modified internal members

myModel.var1 = 100;

This can lead to unexpected security problems.

Execute function immediately

The purpose of hiding details can be achieved by executing functions immediately.

var myModule = (function(){var var1 = 1;var var2 = 2;function fn1(){}function fn2(){}return {fn1: fn1,fn2: fn2};})();

It's not possible to modify variables and functions outside of the module that we haven't exposed.

The above approach is the basis of our modularity, currently, there are two main types of JavaScript module specification: CommonJS andAMD

CommonJS

We start with COMMONJS, because there is no modular programming on the web side is only the page JavaScript logic complex, but also can work, on the server side must have modules, so although JavaScript in the web-side development for so many years, The first popular modular specification was brought in by the server-side JavaScript application, and the COMMONJS specification was carried forward by Nodejs, marking the formal stage of JavaScript modular programming.

    1. Defining modules
      According to the COMMONJS specification, a single file is a module. Each module is a separate scope, meaning that variables defined inside the module cannot be read by other modules unless defined as properties of the global object

    2. Module output:
      Module has only one exit, module.exports object, we need to put the content that the module wants to output into the object

    3. Load module:
      The load module uses require a method that reads a file and executes it, returning an object inside the file module.exports

Look at an example.

//模块定义 myModel.jsvar name = ‘Byron‘;function printName(){console.log(name);}function printFullName(firstName){console.log(firstName + name);}module.exports = {printName: printName,printFullName: printFullName}//加载模块var nameModule = require(‘./myModel.js‘);nameModule.printName();

Different implementations of the require when the path has different requirements, the general situation can omit the js extension name, you can use a relative path, you can use absolute path, or even omit the path directly to use the module name (if the module is a system built-in module)

Awkward browser

Looking closely at the code above, you will find that require it is synchronous. The module system needs to read the module file contents synchronously and compile execution to get the module interface.

This is simple and natural to implement on the server side, however, there are a lot of problems to be implemented on the browser side.

On the browser side, the best and easiest way to load JavaScript is to insert tags into the document script . But script tags are inherently asynchronous, and traditional COMMONJS modules do not load properly in a browser environment.

One of the solutions is to develop a server-side component that makes static analysis of the module code and returns the module to the browser side, along with its dependency list. This works well, but requires the server to install additional components and therefore adjusts a series of underlying architectures.

Another solution is to encapsulate the module definition with a set of standard templates, but the difference between how the module should be defined and how it should be loaded:

Amd

AMD that Asynchronous Module Definition is, the Chinese name is the meaning of the asynchronous module definition . It is a specification for modular development on the browser side

Because it is not JavaScript native support, the use of the AMD Specification for page development requires the corresponding library functions, that RequireJS is, the famous, in fact, AMD is requirejs in the promotion process of the module definition of the normalized output

Requirejs mainly solves two problems

    1. Multiple JS files may have dependencies, the dependent files need to be loaded into the browser earlier than the files that depend on it
    2. JS load when the browser will stop the page rendering, loading more files, the page lost response time longer

See an example of using Requirejs

// 定义模块 myModule.jsdefine([‘dependency‘], function(){var name = ‘Byron‘;function printName(){console.log(name);}return {printName: printName};});// 加载模块require([‘myModule‘], function (my){

My.printname ();
});

Grammar

Requirejs defines a function define, which is a global variable used to define the module

define(id?, dependencies?, factory);
    1. ID: Optional parameter that defines the identity of the module, if not provided, the script file name (minus extension)
    2. Dependencies: is an array of module names that are dependent on the current module
    3. Factory: Factory method, module initializes the function or object to execute. If it is a function, it should only be executed once. If it is an object, this object should be the output value of the module

Using require functions to load modules on a page

require([dependencies], function(){});

The Require () function accepts two parameters

    1. The first parameter is an array that represents the module on which it is dependent
    2. The second parameter is a callback function that will be called when the module specified by the current polygon is loaded successfully. The loaded module passes in the function as a parameter, allowing the modules to be used inside the callback function

The Require () function is loaded asynchronously when the dependent function is loaded, so that the browser does not lose its response, it specifies the callback function, and only the previous modules are loaded successfully, which solves the dependency problem.

Cmd

CMD is the Common Module Definition Universal module definition, the CMD specification is developed at home, just like AMD has a Requirejs,cmd browser implementation seajs,seajs to solve the same problem and Requirejs, just in the module definition mode and module loading (can say run, resolution) is different in timing

Grammar

Sea.js respect a module a file, follow the uniform wording

Define
define(id?, deps?, factory)

Because CMD respected

    1. A file is a module, so you often use the file name as the module ID
    2. CMD respected dependent on the nearest, so generally do not write in the parameters of define dependency, write in factory

Factory has three parameters

function(require, exports, module)
Require

Require is the first parameter of the factory function

require(id)

Require is a method that accepts the module identity as a unique parameter to obtain the interface provided by other modules

Exports

Exports is an object used to provide a module interface to the outside

Module

The module is an object that stores some of the properties and methods associated with the current module

Demo
// 定义模块  myModule.jsdefine(function(require, exports, module) {  var $ = require(‘jquery.js‘)  $(‘div‘).addClass(‘active‘);});// 加载模块seajs.use([‘myModule.js‘], function(my){});
difference between AMD and CMD

On the difference between the two online can search out a bunch of articles, a simple summary

The most obvious difference is that the process of dependency is different when the module is defined.

    1. AMD is highly dependent on the pre-set and declares its dependent modules when defining the module
    2. CMD respected the nearest dependency, only when using a module to go to require

This difference has the pros and cons, only the grammatical gap, and Requirejs and SEAJS support each other's writing

The biggest difference between AMD and CMD is that the timing of the dependent modules is different, not the timing or the way of loading.

Many people say that Requirejs is an asynchronous loading module, SEAJS is a synchronous loading module, so understanding is actually not accurate, in fact, the loading module is asynchronous, but AMD relies on the front, JS can easily know who the dependent module is, immediately loaded, and cmd nearest to the dependency, Need to use to turn the module into a string to understand the dependencies of those modules, which is also a lot of people criticized the CMD, sacrificing performance to bring the convenience of development, in fact, the parsing module time is short enough to ignore

Why do we say that the two difference is dependent on the timing of the module execution, why many people think that ADM is asynchronous, CMD is synchronous (except for the name of the reason ...). )

The same is the asynchronous loading module, AMD after the loading module completes the module will be executed, all modules loaded after execution will enter the require callback function, the execution of the main logic, the effect is dependent on the module execution sequence and writing order is not necessarily consistent, see the network speed, which first downloaded down, which first executed, But the master logic must be executed after all dependent loads have been completed.

CMD does not execute after loading a dependent module, just download it, after all the dependent modules are loaded to enter the main logic, when encountering the Require statement to execute the corresponding module, so that the module execution sequence and writing order is exactly the same

This is also a lot of people say that the AMD user experience is good, because there is no delay, the dependency module executes ahead of time, cmd performance is good, because only the user needs to execute the reason

JS Modular Development--front-end modularity

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.