1. Introduction

  1. Is a platform that lets JavaScript run on the server side. It can make JavaScript run in the general server environment free from the constraints of the browser. It abandons the traditional platform to achieve high concurrency by relying on multi-line design ideas, and adopts the single-thread, asynchronous I/O, event-driven programming model

  2. Node.js has HTTP server support built in, which means you can easily combine a website with a server. Not only can the server be used to debug code, but it can itself be deployed to a production environment, and its performance is adequate

  3. Node.js can also be deployed to non-network applications, such as a command-line tool. Node.js can also call C/C++ code, which can take full advantage of existing libraries, and can also implement very high performance requirements in C/C++.

  4. Asynchronous I/O event-driven Node.js processes only one event at a time and immediately enters an event loop to check and process subsequent events. The advantage of this is that the CPU and memory focus on one thing at a time, while keeping time-consuming I/O operations as parallel as possible.

  5. Node.js replaces multithreading with asynchronous I/O and event-driven, resulting in considerable performance improvements. In addition to using V8 as a JavaScript engine, Node.js uses the efficient Libev and Libeio libraries to support event-driven and asynchronous I/O. The diagram is a schematic of the Node.js architecture. Node.js developers abstracted libuv from libev and Libeio. For POSIX1 operating systems, Libuv leverages epoll or Kqueue by encapsulating libev and Libeio. On Windows, Libuv uses the Windows IOCP(Input/Output Completion Port) mechanism to achieve the same performance on different platforms

  6. The CommonJs specification includes modules, packages, systems, binary, and modules. Console, Encodings, Filesystems, Sockets, Unit Testing, juejin.cn/post/684490…

2. Create an HTTP service

var http = require('http')
http.createServer(function( req, res ) {
    res.writeHead( 200, {'Content-Type': 'text/html'});
    res.write('<div>Node.js</div>')
    res.end('<div>Hello Word</div>')
}).listen(9988)
Copy the code

At this time, we found that if the code is modified, the page will not be updated. The Supervisor can realize this function and solve the debugging problems in the development process

npm install -g supervisor
Copy the code

Another method is the Nodemon

npm install -g nodemon
Copy the code

Run the command directly after installation, you can listen to the file changes automatically restart

nodemon app.js
Copy the code

Asynchronous I/O and event programming

I/O operations: If the disk read/write operation or network communication I/O operation takes a long time, the operating system will suspend the thread and transfer resources to other threads. This scheduling mode becomes blocking. When the I/O operation is complete, the thread will continue to execute. Is blocking I/O asynchronous I/O is I/O request is sent to the operating system, to continue executing the next statement, when the I/O completion, will be in the form of event notification to perform I/O operations of threads, thread will handle this event at a certain time, so the thread must have event loop, constantly testing whether there is a pending event, in order to deal with

var fs = require('fs')
fs.readFile('filename', function(err, data) {
    // do something
})
console.log('end')
Copy the code

In the example above, fs.readFile sends the asynchronous I/O request to the operating system, and then executes’ end ‘. After the execution, the time loop listens for the event. When FS receives the I/O request completion event, the event loop actively calls the callback function to complete the subsequent work

4. Event

1.EventEmitter

All node.js asynchronous I/O operations send an event to the event queue when they complete. From the developer’s perspective, events are provided by EventEmitter objects. The previously mentioned fs.readFile and HTTP. createServer callback functions are implemented using EventEmitter. Let’s use a simple example to illustrate the use of EventEmitter

var event = require('events')
var EventEmitter = event.EventEmitter
var eventBus = new EventEmitter()
eventBus.on('eventName', function() {
    console.log('finish event')
})
setTimeout( function() {
    eventBus.emit('eventName')
}, 2000)
Copy the code

The code above prints Finish Event after 2 seconds, the event object registers a listener for eventName, and then 2 seconds later it sends the event object eventName and the listener is called,

2.Node.js event loop mechanism

When does Node.js enter the event loop?

The answer is that node.js programs start in an event loop and end in an event loop. All logic is the event callback function, so Node.js is always in the event loop, and the program entry is the callback function of the first event in the event loop. The event callback function may issue I/O requests or emit events directly during execution. After execution, it returns to the event loop, which checks for unprocessed events in the event queue until the program ends. Node.js event loops are not visible to developers and are implemented by the L, B, E, v libraries. Supports various types of events, such as EV_IO, EV_timer, EV_signal, EV_IDLE, etc., which are encapsulated by EventEmitter in Node.js. Each iteration of the libev event loop is a Tick in Node.js. Libev continuously checks for active event listeners that can be detected. When no event listeners are detected, libev exits the event loop and the process ends.

Modules and packages

Modules and packages are the most important pillars of Node.js. Node.js provides require functions to call other modules, and modules are file-based. The mechanism is very simple and follows the CommonJs standard

1. What is a module

A module is a basic part of a Node.js application. A file corresponds to a module one by one. A Node file is a module. The HTTP used above is a module, which is internally implemented in C++ and externally wrapped in js to obtain this module through require

2. Create and load modules

In Node.js, creating a module is very simple, because a file is a module, and the only problem is how to get the module in another file. Node.js provides two objects of exports and require, where exports is the interface exposed by the module, and require is used to obtain the interface of a module from the external, that is, the exported object of the acquired module

Var name exports.setName = function(newName) {name = newName} exports.getName = function() {var name exports.setName = function(newName) {name = newName} exports.getName = function() { Console. log('name=' + name)} var moduleA = require('./moduleA.js') moduleA.setName('outName') moduleA.getName()Copy the code

SetName and getName are used as module access interfaces in moduleA via exports.

Import files import modules via require

Module.exports var name function setName (newName) {name = newName} function getName() {console.log(name)} module.exports = { setName, getName }Copy the code

Module. exports cannot be assigned directly instead of module.exports. Exports is just a variable pointing to the same object as module.exports. It is released when the module executes, but module does not, so you can only change the interface by specifying module.exports.

3. Create a package

Packages are further abstractions on a modular basis, and node.js packages are similar to C/C++ libraries or Java/.Net libraries. It encapsulates a separate function for publishing, updating, dependency management, and version control. Node.js implements the package mechanism according to CommonJS specification, and develops NPM to solve the needs of package publishing and obtaining

The node.js package is a directory that contains a package description file in JSON format, package. JSON. Packages that strictly conform to the CommonJS specification should have the following characteristics:

  1. Package. json must be in the top-level directory of the package;

  2. Binaries should be in the bin directory;

  3. JavaScript code should be in the lib directory;

  4. The document should be in doc;

  5. Unit tests should be in the test directory

    // Create a package folder and create a lib folder and create a new interface

    // interface.js exports.hello = function() { console.log(‘hello’) }

    Create package.json under package root

    // package.json { “main”: “./lib/interface.js” }

When calling a package, Node.js will first check the main field of package.json file in the package and regard it as the interface module of the package. If package.json or main field does not exist, Will try to find index.js or index.node as the interface to the package.

Package. json is a package.json file specified by CommonJS to describe packages. A package.json file that is fully compliant with the specification should contain the following fields.

  1. Name: indicates the package name. It must be unique and consists of lowercase letters, digits, and underscores (_). It cannot contain Spaces. Description: A brief description of the package.

  2. Version: version string that conforms to the semantic version recognition specification

  3. Keywords: keyword group, usually used in searches

  4. Maintainers: Array of maintainers. Each element contains name, email (optional), and Web (optional) fields. Ficol3: An array of contributors, in the same format as Maintainers. The package author should be the first element in the contributor array. Licenses array, each element containing type(license name) and URL (link to license text) repositories: Repository managed address array, each element containing type(repository type such as git), URL (repository address), and PATH (relative to repository path)

  5. Bugs: The address where bugs are submitted. This can be a web address or email address

  6. Licenses: License array, each element containing type(license name) and URL (address linked to license text)

  7. Repositories: Repository hosted array of addresses, each containing Type (repository type such as Git), URL (repository address), and Path (relative repository path)

  8. Dependencies: An associative array of package names and version numbers.

4. Create a global link

NPM provides an interesting command, NPM link, which creates symbolic links between local and global packages. We said that packages installed using global mode cannot be used directly through require, but this restriction can be broken with the NPM link command

npm link express ./node_modules/express -> /usr/local/lib/node_modules/express
Copy the code

We can find a symlink in the node_modules subdirectory that points to packages installed globally. In this way, we can use the global package as a local package

In addition to linking global packages locally, you can use the NPM link command to link local packages globally. To do this, run the NPM link command in the package.json directory. If we were to develop a package, this approach would be very convenient for testing across different projects

5. Release of packages

NPM can be very convenient to publish a package. First of all, we need to make our package conform to the specification of NPM. NPM has a package specification based on CommonJS, but it is not completely consistent with CommonJS, the main difference lies in the difference of required fields

  1. Using NPM init, you can generate a standards-compliant package.json based on interactive q&a

  2. Before the release, we still need to obtain an account for future maintenance of our own package, use NPM adduser according to, prompting to enter the user name, password, email, and wait for the account creation completion

  3. When you’re done, you can use NPM whoami to test if you’ve obtained an account.

  4. Next, run NPM publish in the package.json directory,

  5. If your package has future updates, simply change the version field in the package.json file and re-use the NPM publish command.

  6. If you are not satisfied with a published package (such as the meaningless one we published), you can use NPM unpublish to cancel the publication.

6. Debugging

1. Command line debugging

Running node debug debug.js from the command line will launch the debugging tool:

2. Debug Node.js using the Node-inspector

Most Node.js-based applications run in a browser, such as the powerful debugging tool Node-Inspector. Node-inspector is an open source online debugging tool based entirely on Node.js. It provides powerful debugging functions and a user-friendly interface. It is easy to use

First, install node-inspector using the NPM install -g node-inspector command, and then connect to the debug server for the script you want to debug using the node –debug-brk=5858 debug.js command at the end. Start node – inspector:

node-inspector
Copy the code

Open http://127.0.0.1:8080/debug? in your browser Port =5858 to display elegant Web debugging tools

6.Node.js core module

1. Global objects

  1. global

  2. Process. argv is an array of command line arguments. Process. argv is an array of command line arguments. The first element is the node execution path, the second element is the script file name, and then the parameters passed in

    Js name=node age=20 sex=male // Process. argv is ['node file path ', 'node file path ', 'name=node', 'age=20', 'sex=male']Copy the code

2. Common tool Util

  1. Util. Inherits is a function that implements object stereotype inheritance

    / / we first create a Person class var util = the require (" util ") function Person (name) {enclosing name = name | | 'Person'. This age = '1991' this.sayHello = function() { console.log( 'Hello', this.name ) } } Person.prototype.showName = function() { console.log(this.name); } function sub () {this.name = 'sub'} util.inherits(sub, Person) var Person = new Sub(); Sub only inherits functions defined on the prototype chain. Methods and properties inside the constructor are not inheritedCopy the code
  2. Util. Inspect, a method that converts any object to a string, usually used for debugging and error analysis. The first argument is object. The second argument is showHidden, true or false. The default is 2, and when null it will go through the object recursively and the fourth argument is color true and the output color will be nice

  3. util.isArray()

  4. util.isRegExp()

  5. util.isDate()

3. Events drive events

7.HTTP server and client

1. The HTTP server

HTTP.Server is an HTTP Server object in an HTTP module

  1. Request event: This event is triggered when a user client request comes in, providing two parameters req and res, which are instances of http.ServerRequest and http.ServerResponse respectively, representing the request and response information

  2. Connection: When a TCP connection is established, the change event is triggered, providing a parameter socket, which is an instance of net.socket

  3. Close: This event is triggered when the server is shut down

    // This is an explicit way of writing, Var HTTP = require(' HTTP ') var server = new http.server () server.on('request', function( req, res ) { res.write('node') res.end('hello word') }) server.listen(3000)Copy the code

HTTP.ServerRequest is HTTP Request information. ** is generally divided into two parts: Request Header and Request Body. Therefore, three events are provided to control the request body transmission

  1. Data: This event is triggered when the request body data arrives. This event provides a parameter, chunk, to represent the received data

  2. End: This event is emitted when the request body data transfer is complete, after which no more data will come

  3. Close: This event is triggered when the user’s current request ends

  4. HttpVersion: indicates the HTTP version

  5. Method: HTTP request methods GET.POST.PUT

  6. Url: The original request path

  7. Headers: indicates the HTTP request head

  8. Connection: indicates the current HTTP connection socket

    var http = require('http')
    http.createServer( function(req,res) {
        var post = ''
        req.on('data', function(chunk) {
            post += chunk
        })
        req.on('end', function() {
        
        })
    })
    Copy the code

Gets the content of the GET method request

The URL module of Node.js provides a parse function to parse the path of a GET request

var http = require('http')
var url = require('url')
http.createServer(function(req, res ){
    console.log( url.parse(req.url) )
    res.end('finish')
})
Copy the code

Gets the POST request content

The content of the POST request is all in the request body, and Node provides queryString.parse (), which formats the posted parameters

var http = require('http') var querystring = require('querystring') http.createServer( function(req,res) { var post = ''  req.on('data', function(chunk) { post += chunk }) req.on('end', function() { post = querystring.parse(post) res.end('finish') }) }).listen(3000)Copy the code

Http. serverResponse is used to return information to the client, which is also sent by http.Server’s request event

There are generally three functions that return the response header, the response content, and end the request

  1. Response. writeHead(statusCode, [headers]), writeHead(statusCode, HTTP statusCode, 200, 404, etc.); Headers represents each attribute of the response header
  2. Response.write (data, [encoding]), which sends the response to the requested client. Data is a string or Buffer. If data is a string, encoding is specified to specify the encoding, default utF-8, which can be called multiple times
  3. Response.end (data, [encoding]): ends the response and tells the client that all sending has been completed. When all contents to be returned are sent, it must be called once. If this function is not called, the client will always be in pedding state

2. The HTTP client

1. The HTTP module provides two functions, http.request and http.get, to initiate requests to the HTTP service as clients

  1. Http. request(options, callback) Initiates an HTTP request. The options parameter is the callback function of the request

    Host: domain name or IP address of the requested website 2. Port: port of the requested website (default: 80) 3. Method: request mode (default: GET) 4Copy the code

Callback: Passes an instance of http.ClientResponse, and http.request returns an instance of http.ClientRequest

Var HTTP = require(' HTTP ') var query = require(' queryString ') var params = Var options = {host: 'aps.juhe.cn', path: '/ IP /Example/query.php', method: 'POST', headers: { 'Content-Type': 'application/x-www.form-urlencoded; charset=UTF-8' } } var req = http.request( options, functioin( res ) { res.setEncoding('utf8') res.on('data', function(data) { }) }) req.write( params ) req.end()Copy the code

HTTP. Get (options, callback) The HTTP module also provides a quick GET request

var http = require('http') let options = { host:'', path: '', headers: {}, qs: Get (options, function(res) {res.setencoding ('utf8') res.on('data', function(data) {})})Copy the code

8. Module loading mechanism

Node.js modules can be divided into two categories: core module and file module

  1. Core modules are their own API modules, such as FS and HTTP, which can be obtained directly through require. If the file module name conflicts with the core module, the core module will always be loaded

  2. A file module is a separate file stored in js code, JSON, or C/C++. It can be loaded either by path or by searching the node_modules folder

    If require starts with a /, it looks for modules in an absolute path, Js /home/module.json /homt/module.node

    If require with./ or.. /, then look for modules in a relative path, usually modules that extend themselves

    ** If it doesn’t start with a relative path and an absolute path, and the module isn’t a core module, then the module is loaded via node_modules. Packages we fetch using NPM are usually loaded this way

The loading sequence of modules is summarized as follows

  • If the module is a core module, load it directly and end
  • If you start with /./.. /, load the module by path, end
  • Assuming that the current directory is dir, load dir/node_modules/module as the path. If the loading succeeds, end. If the loading fails, repeat the process to the root directory using dir as its parent directory