Understanding the Module specification in JS (commonjs,amd,cmd)

Source: Internet
Author: User

With the rapid development of the Internet, front-end development is more and more complex. This article will start with the problems encountered in the actual project, and tell me about the problems that can be solved by modularization, and how to use sea.js for the modularization development of the front end.

annoying naming conflicts

We start with a simple habit. When I do projects, I often abstract some common, low-level functions into functions, such as

function each (arr) {  //  Implementation code }function log (str) {  //  Implementation code }

and smarty pants These functions uniformly in the util.js. When needed, the file is introduced. It all worked well and my colleagues thanked me for providing such a handy kit. It was not until the team grew bigger that people started complaining.

Xiao Yang: I want to define a each method to traverse the object, but the page header of the util.js has already defined A, I can only call eachobject, good helpless.

Xiao Gao: I have customized a log method, why the code written by Xiao Ming is a problem? Somebody help me.

Complaining more and more. After a heated discussion, the team decided to refer to the Java approach and introduce a namespace to solve. So the code in Util.js became

var org == = = Function (arr) {  //  implementation code  = function (str) {  //  implementation code };

Don't assume that the code above is intentionally fabricated to write this article. 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;}

Through namespaces, it is true that conflicts can be greatly mitigated. But often see the above code, can not help but full of sympathy. In order to invoke a simple method, it is necessary to remember such a long namespace, which increases the memory burden while depriving a lot of coding fun.

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 loaded well   / /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?   // if modules A and B both provide the Foo method, how do you avoid collisions? });

Seemingly simple naming conflicts, it is not easy to actually solve them. How to solve it more gracefully? Let's take a look at the other FAQs first.

cumbersome file-dependent

Continue with the above story. Based on Util.js, I started developing a common component of the UI layer so that project team colleagues wouldn't have to reinvent the wheel. One of the most popular components is Dialog.js, which is easy to use.

<script src="util.js"></script><script src="dialog.js  " ></script><script>  */* }); </script>

However, no matter how I write the document, and how solemnly e-mail announcement, from time to time there will always be colleagues to ask why dialog.js problems. Through some troubleshooting, we find that the cause of the error is often

<script src="dialog.js"></script><script>  /* */ }); </script>

Util.js was not introduced before Dialog.js, so Dialog.js did not work properly. Also do not think that my above story is fictitious, in the company that I have been in, still have similar foot this newspaper wrong, especially in a variety of Quick production marketing page.

The above file dependencies are still within the control range. 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. 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 it couldn't be done simply by a few lines of code.
    3. A new feature for an old product, the final evaluation can only be based on the old class library to continue to develop.
    4. Company integration Business, a certain two product lines 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.

file dependencies, currently in the vast majority of class library framework, such as foreign YUI3 framework, the domestic Kissy and other class libraries, is now through the configuration of the way to solve.

Yui.add ('my-module', function (Y) {  //  ... ' 0.0.1 ' , {    requires: ['node'event' ]});

The above code requires specifies the dependencies of the current module, in other ways. This can largely solve the dependency problem, but it's not elegant enough. When the module is many, the dependence is very complex, cumbersome configuration will bring a lot of hidden trouble.

Naming conflicts and file dependencies are two classic issues in the front-end development process. Let's see how we can solve this through modular development. To facilitate the description, we use sea.js as a modular development framework.

use Sea.js to solve

Sea.js is a mature open source project with the core goal of providing a simple, ultimate modular development experience for front-end development. Here is not much to do with the introduction, interested can visit seajs.org to view official documents.

With Sea.js, the CMD (Common module definition) Module definitions specification is required when writing files. A file is a module.

The util.js in the previous example becomes

define (function (require, exports) {  = function (arr) {    //  Implementation code   } ;   = function (str) {    //  Implementation code   };});

exportsinterfaces can be provided outward through. In this way, the Dialog.js code becomes

define (function (require, exports) {  var util = require ('./util.js' ) );   = function () {    //  Implementation code   };});

The key part is here! We require(‘./util.js‘) can get through exports the exposed interface through the Util.js . the require here can be thought of as a syntax keyword added to the JavaScript language by Sea.js, which can be used to require obtain interfaces provided by other modules.

It's not really magical at all. As a front-end engineer, you must be familiar with CSS code.

@import url ("base.css"); #id {...}. class { ... }

Sea.js added require syntax keywords, as in the CSS file @import , gives our source code to rely on the introduction function.

If you are a back-end development engineer, not unfamiliar. Java, Python, C # and so on, all have include , and import so on. The JavaScript language itself has similar functionality, but is still in the draft phase and needs to wait until the ES6 standard is supported by the mainstream browser.

This makes it very easy to use dialog.js in a page.

<script src="sea.js"></script><script>seajs.use ('  dialog', Function (dialog) {  dialog.init (/**/ );}); </script>

The first is to introduce the Sea.js file in the page, which is generally controlled through the page header, and also facilitates the maintenance of updates. When you want to use a component in a page, simply call through the seajs.use method.

Think about the above code, I believe you have seen the two major benefits of Sea.js:

1, through the exports exposed interface. This means that no namespaces are required, and global variables are not required. This is a thorough naming conflict solution.

2, through the require introduction of dependency. This allows for built-in dependencies, developers only need to be concerned about the current module dependencies, and other things sea.js will be handled automatically. For module developers, this is a good separation of concerns, allowing programmers to enjoy coding more.

Summary

In addition to resolving naming conflicts and dependency management, using sea.js for modular development can also provide many benefits:

1, the version of the module management. With the configuration of aliases, it is easy to implement the version management of the module with the build tool.

2, improve maintainability. Modularity allows each file to have a single responsibility and is very useful for code maintenance. Sea.js also provides NoCache, debug and other plug-ins, with on-line debugging and other functions, can be more obvious to improve efficiency.

3, front-end performance optimization. Sea.js is useful for page performance by loading modules asynchronously. Sea.js also provides combo, flush and other plug-ins, with the service side, can be good for page performance tuning.

4, cross-environment sharing module. The CMD module definition specification is very similar to node. JS's module specification. With the Sea.js node. js version, it is easy to implement modules across server and browser sharing.

Modular development is not new, but in the WEB domain, front-end development is a freshman post, has been in a relatively primitive era of slash and burn. Until the last two or three years, with the popularization and popularity of Dojo, YUI3, node. JS and other communities, the concept of the front-end modular development was gradually rooted.

The modular construction of the front end can be divided into two main categories. One kind is the cathedral pattern represented by Dojo, YUI3, the kissy of the domestic and so on. In the cathedral mode, all components are granular and modular, and the components are layered and interlocking. Another kind is the market pattern based on jQuery, Requirejs, domestic sea.js, ozjs and other kinds of libraries. In market mode, all components are independent and have a single responsibility, and the components are combined loosely coupled to develop together.

There are application scenarios for these two types of modular construction methods. In the long run, small and beautiful are more tolerant and competitive, more able to form a vibrant ecological circle.

In short, modularity can bring many benefits to front-end development. If you haven't tried it, you might as well start with a trial sea.js.

the principle and necessity of module session:

If you've ever heard of JS modularity, then you should have heard or commonjs or AMD or even cmd, and I've heard it before, but I've heard it before. Now look at what these specs are, and why.

First, CommonJS

COMMONJS is for the performance of JS to make specifications, because JS has no module function so Commonjs came into being, it wants JS can run anywhere, not just the browser.

CommonJS can have a certain influence, I feel absolutely inseparable from the popularity of Node, but oh, Node,commonjs, browser and even the internet is what the relationship between, I found an appropriate diagram:

|--------------------Browser-----------------------| |--------------------------CommonJS----------------------------------|

|       BOM | |        DOM | |         ECMAScript | |           FS | |         TCP | |        Stream | |          Buffer | |........|

|-------------------| |-----------------------------------------------Node--------------------------------------------------|

Commonjs defined module is divided into: {Module reference (require)} {module definition (exports)} {module identification (modules)}

Require () is used to introduce external modules; The exports object is used to export the method or variable of the current module, the only export, and the module object represents the modules themselves.

For example, we can use it like this:

// sum.jsexports.sum = function () {... Do add Operation ...}; // Calculate.js var math = require ('sum'= function (n) {    return  math.sum (val,n);};

Although node follows Commonjs's specifications, it has made some trade-offs and filled in some new things. However, said Commonjs also said node, then I think I have to understand the NPM. NPM, as node's package Manager, is not to help node with the installation of the dependency package, it must also follow the COMMONJS specification, which follows the package specification (or theory).

Second, AMD

Commonjs is mainly for JS in the back end of the performance of the formulation, he is not suitable for the front-end, why so to say?

This needs to analyze the browser-side JS and server-side JS are the main things to do, what is different:

----------------------------------------------server-side JS | Browser-side JS--------------------------------------------------

The same code needs to be executed multiple times | Code needs to be distributed from one server side to multiple client execution

CPU and memory resources are bottlenecks | Bandwidth is a bottleneck

Loading from disk when loaded | Load needs to be loaded over the network

--------------------------------------------------------------------------------------------------------------- ------------------------

Thus, AMD (asynchronous module definition) appears, it is mainly for the front-end JS performance specifications.

AMD has only one interface: define (id?,dependencies?,factory);

It's going to make all the dependencies (DEP) when declaring the module, and it's going to be passed as a parameter to factory, like this:

define (['dep1','dep2'],function (DEP1,DEP2) {...});

If there is no dependency, define a simple module, the following is OK:

define (function () {    var exports = {};     = function () {...};     return exports;});

Here have define, wrap things up, that node implementation how did not see there is define keyword, it also want to wrap things up ah, in fact, it is only node implicit packaging just ....

Requirejs is the implementation of the AMD specification.

This has the Chinese version of the wiki of AMD, said a lot of pretty detailed things, when used to see: AMD Wiki Chinese version

Third, CMD

The name of the Yuber wrote Seajs, is to follow his proposed CMD specification, and AMD pretty similar, but used to feel more convenient, the most important is the Chinese version.

Define (function (Require,exports,module) {...});

Understanding the Module specification in JS (commonjs,amd,cmd)

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.