Chapter 4. Modular Code

As your project's code grows, the number of scripts in the project will be more and more, incrementing script-loading complexity. The classic way to load JavaScript files is to write a<script> tags for every script you have, but you have to do it in the right order; if you don't, your code could stop working. That's not an efficient way for medium-size projects.

What happens if you forget the order of loading? What if you make a refactorization on the code and the order of the script changes? It will be a pain to fix it and keep track of all the code and its dependencies.

This problem has been addressed in different ways. One is to create a module syntax to create, load, and declare explicitly the dependencies of modules; the syntax is called AMD (Asynchronous Module Definition). The AMD modules define a list of module dependencies, and the code inside the module will be executed only after the dependencies are fully loaded.

The dependencies are loaded asynchronously; that means that you don't need to load all the scripts in the HTML page through <script> tags. AMD modules are better than plain JavaScript because they define dependencies explicitly and can be loaded automatically.

Although AMD modules are better than <script> tags, working with AMD modules can be a pain when unit testing comes in because you need to know the intricacies of how the library loads the modules; when you want to do unit testing, you need to isolate the pieces of code under test, but is hard to do it in RequireJS, and even if you do it the result can be buggy.

Recently another module loader and dependency manager has arrived; Browserify seems to be the most popular at the moment. However, it is not the only one; there are many other potentially strong choices such as jspm and steal.js.

In this book, we will work with Browserify because of its popularity, so you can find a lot of information and documentation about it on the Web; another good reason is that many projects have been built with it, which demonstrates its maturity and that it's production-ready. Browserify uses the same Node module syntax to define modules and dependencies, so that if you already know about Node you can go directly to the Browserify section.

CommonJS modules

In recent years, Node has been gaining popularity in the software industry; indeed it is becoming a very popular choice for backend development in a full JavaScript technology stack. If you don't know about Node, you can think about it as JavaScript used in the server instead of a browser.

Node uses the CommonJS module syntax for its modules; a CommonJS module is a file that exports a single value to be used for other modules. It is useful to use CommonJS because it provides a clean way to manage JavaScript modules and dependencies.

To support CommonJS, Node uses the require() function. With require() you can load JavaScript files without the need to use <script> tags, instead calling require() with the name of the module/dependency that you need and assigning it to a variable.

To illustrate how CommonJS modules work, let's write a Node module and see how to use the require() function. The following code shows a simple module that exposes a simple object with the method sayHello():

hello = {
  sayHello(name) {
    name = name || 'world';
    console.log('hello', name);
  }
}

module.exports = hello;

This script can be placed in a file named hello.js, for example. The hello module can be loaded from another module by calling the require() function, as shown in the following code:

var hello = require('./hello');
hello.sayHello('world); // prints "hello world"

When we require a script with the require() function we don't need to add the .js extension, Node will do it for us automatically. Note that, if you add the extension to the script name, Node will add the extension anyway and you will get an error because the hello.js.js file does not exist.

That's the way you can define CommonJS modules for your projects: we just export the variable that we want to expose to the outside of the module with module.exports and then load the module where needed with require().

CommonJS modules are singletons, which means that every time you load a module you will get the same instance of the object. Node will cache the returned value when it's called for the first time and will reuse it for the next calls.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.35.194