Getting Started with JavaScript modularity Ⅰ: Understanding Modules

Source: Internet
Author: User

As a JS beginner. If you hear a few terms like "Modular Build & Modular Loading" "webpack&browserify" or "Amd&cmd", it's definitely a messy moment.


The modularity of JavaScript sounds esoteric, but it is particularly useful for developers to understand.


In this article, I will try to translate these esoteric terms into easy-to-understand words (plus some code examples). I hope you can learn a lot from it.


In order to avoid lengthy, the whole content will be divided into two articles, this is the first part, mainly describes what modularity is, why use the module. The second chapter then describes how to package JS modules, as well as various build tools.


To explain exactly what is modular


A competent writer divides his book into chapters and passages; a good programmer divides his code into modules.


Just like a chapter in a book, a module is just a piece of code.


Good code module Segmentation of the content must be very reasonable, so that you increase the reduction or modification of functions, without affecting the entire system.


Why use a module


Modularity can make your code low-coupling, and the function modules do not affect each other directly. I personally think that modularity has the following advantages:


1. Maintainability: By definition, each module is independent. A well-designed module will try to get rid of the external code so that it can be improved and maintained independently. Maintaining a separate module is a lot easier than a messy piece of code.


2. Namespaces: In JavaScript, variables defined outside the highest-level functions are global variables (which means that everyone can access them). Because of this, when unrelated code happens to use the same name variable, we encounter "namespace pollution" problems.


Such problems are to be avoided in the course of our development.


I will also give some concrete examples to illustrate this in the following sections.


3. reusability: In reality, in our daily work we often copy the code we wrote before into a new project.


Copy and paste although it is very convenient, but can't we find a better way? If...... Is it wonderful to have a reusable module?


How to introduce modules


There are many ways to introduce modules, and here are some of the things we'll introduce:


Module mode


Module mode is typically used to emulate the concept of classes (because native JavaScript does not support classes, although the newest ES6 introduces class but not yet popular) so that we can store public and private methods and variables in an object-- This is just like the way we use classes in Java or Python. This allows us to encapsulate private variables and methods within a closure scope while exposing API calls.


There are many ways to implement the module pattern, the following example is the method of anonymous closure function. (in JavaScript, a function is the only way to create a scope.) )


Example 1: Anonymous closure function

Getting Started with JavaScript modularity Ⅰ: Understanding Modules


With this construct, our anonymous function has its own scope or "closure." This allows us to hide variables from the parent (global) namespace.


The advantage of this approach is that you can use local variables inside a function without accidentally overwriting a global variable with the same name, but still have access to the global variable as follows:

Getting Started with JavaScript modularity Ⅰ: Understanding Modules


It is important to note that the anonymous function must be wrapped in parentheses, the statement beginning with the keyword function will always be interpreted as a functional declaration (JS does not allow unnamed function declarations), and after the parentheses, the internal code will be recognized as a function expression. In fact, this is also called the immediate execution function (Iife) Interested students can learn more here


Example 2: Global Introduction


Another popular approach is the global introduction of some library uses such as jquery. Similar to the anonymous closure function we just gave you, it's just a different way of passing in a global variable:

Getting Started with JavaScript modularity Ⅰ: Understanding Modules


In this example, GlobalVariable is the only global variable. The benefit of this approach is that you can pre-declare global variables to make your code more readable.


Example 3: Object interface


As in the following, there is also a way to create a module that uses a separate object interface:

Getting Started with JavaScript modularity Ⅰ: Understanding Modules


Example 4: Revealing module pattern revealing


This is very similar to our previous implementation, except that it ensures that all variables and methods remain private until they are exposed:

Getting Started with JavaScript modularity Ⅰ: Understanding Modules


Here, in fact, we only talk about the module mode of the iceberg. Interested friends can read more detailed information:

In-depth understanding of JavaScript module patterns

In-depth understanding of the JavaScript series (3): Fully parse module mode


CommonJS & AMD


All of the solutions above have one thing in common: use a single global variable to include all the code within a function, thereby creating a private namespace and closure scope.


Although each method is more effective, it also has its own short plates.


One thing, as a developer, you have to have a clear understanding of the correct order in which to introduce dependent files. Take Backbone.js for example, to use backbone you have to introduce backbone source files in your page.


However, backbone relies on underscore.js, so the introduction of backbone must be followed.


At work, these dependency management can often become a headache for people.


At the other point, these methods may also cause namespace collisions. For example, what if you happen to write a module with two duplicate names? Or what if you need two versions of a module at the same time?


Is there no modular approach that does not implement the global scope?


Of course there is.


Next, there are two popular solutions: CommonJS and AMD.


CommonJS


CommonJS extends the API of the JavaScript declaration module.


The Commonjs module makes it easy to export an object so that they can be introduced by other modules through require statements. If you write about node. js, you should be familiar with the syntax.


With Commonjs, each JS file stores the contents of its module independently (just like a closed packet enclosed). In this scope, we use the Module.exports statement to export the object as a module and then introduce it through the Require statement.


Let me give you a visual example:

Getting Started with JavaScript modularity Ⅰ: Understanding Modules


By specifying the name of the exported object, the Commonjs module system can identify how the module should be interpreted when it is introduced into other files.


Then, when someone wants to call mymoudle, they just need to require:

Getting Started with JavaScript modularity Ⅰ: Understanding Modules


This implementation has two advantages over module mode:

Avoid global namespace pollution

Identify dependencies between code


And this writing style is very comfortable and friendly, I like it.


One thing to keep in mind is that the COMMONJS load the module in a server-first way, and if we introduce three modules, they will be loaded in one place.


It's cool to use on the server side, but it's not as efficient in the browser. After all, it takes more time to read a file on the network than it does locally. As long as it is still reading the module, the browser-loaded page will remain stuck. (In the next part of the tutorial we will discuss how to solve this problem)


Amd


Commonjs is pretty good, but what if we want to implement an asynchronous load module? The answer is asynchronous module definition (asynchronous Module definitions specification), referred to as AMD.


The code that is loaded into the module by AMD is generally written like this:

Getting Started with JavaScript modularity Ⅰ: Understanding Modules


Here we use the Define method, the first parameter is the dependent module, these modules will be loaded in the background without blocking, the second parameter as a completed callback function.


The callback function will use the loaded module as the parameter. In this case, Mymoudle and myothermodule. Finally, the modules themselves need to be defined by define keywords.


Take MyModule to give an example:

Getting Started with JavaScript modularity Ⅰ: Understanding Modules


Again, unlike COMMONJS,AMD, a solution for an asynchronous load module that is a priority browser. (Remember, many people think that loading small files is inefficient, and we'll explain how to pack the modules in the next article)


In addition to asynchronous loading, another advantage of AMD is that you can use objects, functions, constructors, strings, JSON, or other data types in modules, and COMMONJS only supports objects.


To add, AMD does not support some of the other server-side features such as IO, file system, and so on in node. In addition, the syntax is more difficult to write than Commonjs.


Umd


In some projects that require both AMD and COMMONJS functionality, you need to use a different specification: Universal module definition (Generic module definitions specification).


UMD creates a method that uses both specifications, and also supports global variable definitions. So UMD modules can be used both on the client and the server side.


Here's an example that explains its functionality:

Getting Started with JavaScript modularity Ⅰ: Understanding Modules


For more examples of UMD, see the official repo on GitHub.


Native JS


I hope you keep reading. Now, let's end with a way to define the module.


You may have noticed that none of the above methods are supported by JS native. It is either modeled in a modular mode or using COMMONJS or AMD.


Fortunately, in JS's latest specification ECMAScript 6 (ES6), the module function is introduced.


ES6 's modular capabilities draw on the benefits of Commonjs and AMD, with concise syntax and support for asynchronous loading, and many other better support.


My favorite feature of the ES6 module is that the import is read-only in real time. (CommonJS is just the equivalent of copying the exported code).


See Example:

Getting Started with JavaScript modularity Ⅰ: Understanding Modules


In this example, we have created two instances of the module, one at the time of export, and one at the time of introduction.


The example in Main.js is completely irrelevant to the original module. This also explains why the call to Counter.increment () still returns 1. Because we introduced the counter variables and the modules are two different instances.


So calling the Counter.increment () method only changes the counter in the module. To modify the introduced counter only manually:

Getting Started with JavaScript modularity Ⅰ: Understanding Modules


With the import statement, you can introduce real-time read-only modules:

Getting Started with JavaScript modularity Ⅰ: Understanding Modules

This looks pretty cool, doesn't it? This makes it possible for us to separate the modules in different files, and then merge them together without affecting their functionality.

Manuscripts: Custom Development www2.qixoo.com

Getting Started with JavaScript modularity Ⅰ: Understanding Modules

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.