官术网_书友最值得收藏!

Node modules

JavaScript has turned out to be a powerful language with some unique features that enable efficient yet maintainable programming. Its closure pattern and event-driven behavior have proven to be very helpful in real-life scenarios, but like all programming languages, it isn't perfect, and one of its major design flaws is the sharing of a single global namespace.

To understand the problem, we need to go back to JavaScript's browser origins. In the browser, when you load a script into your web page, the engine will inject its code into an address space that is shared by all the other scripts. This means that when you assign a variable in one script, you can accidently overwrite another variable already defined in a previous script. While this could work with a small code base, it can easily cause conflicts in larger applications, as errors will be difficult to trace. It could have been a major threat for Node.js evolution as a platform, but luckily a solution was found in the CommonJS modules standard.

CommonJS modules

CommonJS is a project started in 2009 to standardize the way of working with JavaScript outside the browser. The project has evolved since then to support a variety of JavaScript issues, including the global namespace issue, which was solved through a simple specification of how to write and include isolated JavaScript modules.

The CommonJS standards specify the following three key components when working with modules:

  • require(): This method is used to load the module into your code.
  • exports: This object is contained in each module and allows you to expose pieces of your code when the module is loaded.
  • module: This object was originally used to provide metadata information about the module. It also contains the pointer of an exports object as a property. However, the popular implementation of the exports object as a standalone object literally changed the use case of the module object.

In Node's CommonJS module implementation, each module is written in a single JavaScript file and has an isolated scope that holds its own variables. The author of the module can expose any functionality through the exports object. To understand it better, let's say we created a module file named hello.js that contains the following code snippet:

var message = 'Hello';

exports.sayHello = function(){
  console.log(message);
}

Also, let's say we created an application file named server.js, which contains the following lines of code:

var hello = require('./hello');
hello.sayHello();

In the preceding example, you have the hello module, which contains a variable named message. The message variable is self-contained in the hello module, which only exposes the sayHello() method by defining it as a property of the exports object. Then, the application file loads the hello module using the require() method, which will allow it to call the sayHello() method of the hello module.

A different approach to creating modules is exposing a single function using the module.exports pointer. To understand this better, let's revise the preceding example. A modified hello.js file should look as follows:

module.exports = function() {
  var message = 'Hello';

  console.log(message);
}

Then, the module is loaded in the server.js file as follows:

var hello = require('./hello');
hello();

In the preceding example, the application file uses the hello module directly as a function instead of using the sayHello() method as a property of the hello module.

The CommonJS module standard allows the endless extension of the Node.js platform while preventing the pollution of Node's core; without it, the Node.js platform would become a mess of conflicts. However, not all modules are the same, and while developing a Node application, you will encounter several types of modules.

Note

You can omit the .js extension when requiring modules. Node will automatically look for a folder with that name, and if it doesn't find one, it will look for an applicable .js file.

Node.js core modules

Core modules are modules that were compiled into the Node binary. They come prebundled with Node and are documented in great detail in its documentation. The core modules provide most of the basic functionalities of Node, including filesystem access, HTTP and HTTPS interfaces, and much more. To load a core module, you just need to use the require method in your JavaScript file. An example code, using the fs core module to read the content of the environment hosts file, would look like the following code snippet:

fs = require('fs');

fs.readFile('/etc/hosts', 'utf8', function (err, data) { 
  if (err) { 
    return console.log(err);
  }

  console.log(data);
});

When you require the fs module, Node will find it in the core modules folder. You'll then be able to use the fs.readFile() method to read the file's content and print it in the command-line output.

Note

To learn more about Node's core modules, it is recommended that you visit the official documentation at http://nodejs.org/api/.

Node.js third-party modules

In the previous chapter, you learned how to use NPM to install third-party modules. As you probably remember, NPM installs these modules in a folder named node_modules under the root folder of your application. To use third-party modules, you can just require them as you would normally require a core module. Node will first look for the module in the core modules folder and then try to load the module from the module folder inside the node_modules folder. For instance, to use the express module, your code should look like the following code snippet:

var express = require('express');
var app = express();

Node will then look for the express module in the node_modules folder and load it into your application file, where you'll be able to use it as a method to generate the express application object.

Node.js file modules

In previous examples, you saw how Node loads modules directly from files. These examples describe a scenario where the files reside in the same folder. However, you can also place your modules inside a folder and load them by providing the folder path. Let's say you moved your hello module to a modules folder. The application file would have to change, so Node would look for the module in the new relative path:

var hello = require('./modules/hello');

Note that the path can also be an absolute path, as follows:

var hello = require('/home/projects/first-example/modules/hello');

Node will then look for the hello module in that path.

Node.js folder modules

Although this is not common with developers that aren't writing third-party Node modules, Node also supports the loading of folder modules. Requiring folder modules is done in the same way as file modules, as follows:

var hello = require('./modules/hello');

Now, if a folder named hello exists, Node will go through that folder looking for a package.json file. If Node finds a package.json file, it will try parsing it, looking for the main property, with a package.json file that looks like the following code snippet:

{
  "name" : "hello",
  "version" : "1.0.0",
  "main" : "./hello-module.js"
}

Node will try to load the ./hello/hello-module.js file. If the package.json file doesn't exist or the main property isn't defined, Node will automatically try to load the ./hello/index.js file.

Node.js modules have been found to be a great solution to write complex JavaScript applications. They have helped developers organize their code better, while NPM and its third-party modules registry helped them to find and install one of the many third-party modules created by the community. Ryan Dahl's dream of building a better web framework ended up as a platform that supports a huge variety of solutions. But the dream was not abandoned; it was just implemented as a third-party module named express.

主站蜘蛛池模板: 连云港市| 安阳市| 鸡西市| 锡林郭勒盟| 洞头县| 曲阳县| 平乐县| 玛曲县| 通辽市| 彩票| 广饶县| 浮梁县| 莱西市| 青浦区| 祁东县| 营山县| 会泽县| 延庆县| 镶黄旗| 兰州市| 娄底市| 诏安县| 雅安市| 左权县| 枣强县| 惠来县| 宝丰县| 镇沅| 彭山县| 通榆县| 武山县| 公主岭市| 钟山县| 吉林省| 汝阳县| 永川市| 乌审旗| 原阳县| 那坡县| 武功县| 微山县|