Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

Preface:

As a beginner, learning Node is very important. Here’s a summary of what we learned about Node a while ago.

Node. Js and Chrome V8

When it comes to Node, the V8 engine has to be mentioned. Chrome is also a V8 engine, and they are both event-driven and asynchronous architectures. The difference is that browsers interact through event-driven service interfaces; Node is event-driven service I/O;

Four features of Node

  1. Asynchronous I/O; The file read time depends on the slowest file read time.
  2. Events and callback functions (event-driven);
  3. Single thread;
  4. Cross-platform;

Module mechanism

First let’s take a look at the evolution of JavaScript: Toolclass library (browser compatible)—-> Component library (functional modules)—-> Front-end framework (functional module organization)—-> Front-end application (business module organization) We find that JavaScript is inherently lacking modules. So that leads to the CommonJS specification (which wants Javascript to run anywhere)

CommonJS module specification

It is divided into module reference, module definition and module identification.

1. Module reference

The require() method: accepts the module identity, thus introducing the module’s API into the current context

var math = require('math')
Copy the code

2. Module definition

The exports object is used to export methods or variables of the current module.

The Module object represents the module itself

exports.add= function(){
//............
}
Copy the code

3. Module identifier

The argument passed to the require() method must conform to the small hump named string, and the path begins with. Or.. The relative or absolute path of the.

Module implementation of Node

Node introduces the three steps of a module

1. Path analysis; Locate files. 3. Compile and execute files

Nodes are divided into two types of modules:

Core modules: modules provided by Node.

During the compilation of node source code, it is compiled into binary files. When the Node process is started, the core module is directly loaded into the memory, without the need for file location and compilation execution, in the path analysis priority judgment, so the loading speed is the fastest.

File module: user-written module.

Dynamic loading at run time requires complete path analysis, file location, and compilation execution. Slower than core modules.

Detailed module loading process

1. Load from cache preferentially

Just as front-end browsers cache static scripts, Node caches imported modules.

Different: browsers cache files, Node caches objects after compilation and execution

The core module cache takes precedence over the file module cache.

2. Analyze paths and locate files

2.1 Module identifier analysis

Module identifier classification

  • Core modules: such as HTTP \ FS \path\
  • . /.. Start the relative path file module
  • An absolute path file module starting with /
  • Non-path file modules, such as the custom CONNECT module. Node_modules, which takes the most time to find.

2.2 File Location

  • File name extension analysis

  • Directory analysis and packages

    Node finds package.json(a package description file defined by the CommonJS package specification) in the current directory —–> parse the package description object by json.pase () —–> extract the file name specified by the main property to locate it.

    If the main property specifies the wrong file name or there is no package.json file, Node will use index as the default file name and look for index.js, index.node, and index.json in sequence

2.3 Module Compilation

Different file extensions, loading methods are also different.

  • The.js file —–fs module is synchronously read and compiled for execution
  • The.node file ——— is an extension written in C/C++ that loads the file generated by the final compilation through the dlopen() method
  • Josn file —– After the fs module synchronously reads the file, it uses json.parse () to parse the returned result
  • The remaining extensions are loaded as JS files

Note: Each compiled Module will cache its file path as an index on the module. _cache object to improve secondary import performance

1. Compilation of Javascript modules

If you put the procedure of the defined module directly in the browser, you can pollute global variables.

In fact, Node wraps the JavaScript files it gets.

(function (exports,require,module,__filename,__dirname){
  //....
})
Copy the code

Each module file is scoped out.

It is wrapped and executed through the VM native module runInThisContext() method, returning a concrete function object. Finally, exports,require,module,__filename,__dirname are passed to function as arguments

Why does module.exports exist when exports exist?

Exports objects are passed in as parameters, and assigning parameters directly changes what parameters are introduced.

If require imports the effect of a class, copy it to the module.exports object

2. C/C++ module compilation

Node calls the process.dlopen() method to load and execute. The.node file is compiled after writing the C/C++ module. It does not need to be compiled, just loaded and executed. So the execution is efficient, but the writing barrier is higher than JavaScript.

3. Compilation of JSON files

1. The fs module reading JSON files – > 2. Call JSON. The parse () get the object — — — — — – > 3. The export assigned to the module object is available for external calls

The above three types of file module compilation, that is, user-written modules.

3. Core modules

It is divided into TWO parts: C/C++ (stored in Node SRC directory) and JavaScript (stored in Node lib directory).

3.1 Compilation process of JavaScript core modules

  1. Dump to C/C++ code

    V8 js2c.py tool, built-in js code —-> convert to C++ array —– to generate node_natives. H file

  2. Compile JavaScript core modules

    The source code is loaded from memory

3.2 C/C++ core module compilation process

Parts written in pure C/C++ are called built-in modules and are not directly called by users. For example: the Node in the buffer, crypto, evals, fs, OS modules are partly by C/C + +.

Advantages of built-in modules:

  1. Written in C/C++, the performance is better than scripting language.
  2. When the file is compiled, the built-in module compiles into the binary. Node execution is directly loaded into memory, and can be executed without doing identifiers, file location, or compilation.

Dependency hierarchy:

Built-in modules (C/C++)—–> Core modules (JavaScript)——> file modules

Note: The file module calls the core module. Core modules basically encapsulate built-in modules

Scripting languages are usually faster to develop than static languages, but less powerful, so Node strikes a balance by adopting this composite pattern.

Conclusion:

Above is my initial understanding of Node and knowledge about modules. This is just a small part of Node, and we need to continue to learn, summarize, and grow.