• You don’t know Node
  • By Samer Buna
  • The Nuggets translation Project
  • Permanent link to this article: github.com/xitu/gold-m…
  • Translator: lampui
  • Proofreader: Smile, Yuuoniy

At this year’s Forward. Js conference (a JavaScript summit), I gave a talk titled “Node you Don’t Know” in which I asked the audience a series of questions about the Node.js runtime that most of the technical audience couldn’t answer.

I didn’t really do the math, and it wasn’t until the end of the talk that some brave people came up to me and said they couldn’t.

That’s the question that got me talking, and I don’t think we’re teaching Node the right way. Most of the Nodejs textbooks focus on things outside of the Node package and the Node runtime. Most of these packages encapsulate modules (such as HTTP or stream) at the Node runtime. The problem may be that they are hidden inside the runtime, but if you don’t understand the Node runtime, You’re in trouble.

The problem: Most Nodejs textbooks focus on things outside of the Node package and the Node runtime.

I have selected a few questions and organized some answers to write this article. The answers are below the questions. It is recommended to try to answer them yourself first.

If you find a wrong or misleading answer, please contact me.

Question #1: What is a call stack? Is it part of V8?

The call stack is 100% part of V8 and is the data structure V8 uses to track method calls. Every time we call a method, V8 places a reference to that method in the call stack, and V8 does the same for nested calls to every other method, including methods that recursively call themselves.

Screenshot captured from my Pluralsight course — Advanced Node.js

When the nested call to a method ends, V8 pops the method off the stack one by one, using the method’s return value in its place.

Why is this so critical to understanding Node? Because you only have one call stack per Node process. If you keep the call stack busy, your entire Node process will also be busy. Keep that in mind!

Question #2: What is an event loop? Is it part of V8?

Where do you think the cycle of events falls on this graph?

Screenshot captured from my Pluralsight course — Advanced Node.js

The answer is libuv. Event loops are not part of V8!

An event loop is an entity that manipulates external events and converts them into callbacks, a loop that pulls events from the event queue and pushes the event’s callback function onto the call stack. And the cycle is divided into several independent stages.

If this is the first time you’ve heard of event loops, these concepts probably won’t help you much. The event loop is part of a larger picture:

Screenshot captured from my Pluralsight course — Advanced Node.js

You need to understand the outline before you understand the event loop, you need to understand V8’s role in it, the Node APIs, and how events are queued and processed by V8.

Node APIs are methods like setTimeout or fs.readfile. They are not part of JavaScript itself, they are methods provided by Node.

The cycle of events in the middle of this image (a more sophisticated version, really) plays the role of an organizer. When the V8 call stack is empty, the event loop can determine what to execute next.

Question #3: What does Node do when both the call stack and the event loop queue are empty?

Node will exit directly.

When you execute a Node program, Node automatically starts the event loop and exits the process when there is no event handling and no other tasks.

To keep a Node process running, you need to put some tasks into an event queue. For example, when you create a timer or an HTTP server, you are basically telling the event loop to hold on and check that these tasks continue to execute.

Question #4: Besides V8 and Libuv, what external dependencies does Node have?

Here are all the external libraries a Node process can use:

  • http-parser
  • c-ares
  • OpenSSL
  • zlib

These libraries are external to Node itself. They have their own source code, licenses, and Node just uses them.

You want to remember them because you want to know where your program is going. If you’re doing some compression work, you’re probably having problems with zlib. Node is innocent.

Question #5: Is it possible to run a Node process without V8?

It may be a question of ingenuity. You certainly need a virtual machine to run the Node process, but V8 is not the only virtual machine. You can also use Chakra.

Check out this Github repository to track the progress of the Node-Chakra project:

  • nodejs/node-chakracore

    : node-chakracore – Node.js on ChakraCore

Question #6: What is the difference between Module. exports and exports?

You can use the module.exports API. You can also use exports, but there is one caveat:

module.exports.g = ...  // Ok

exports.g = ...         // Ok

module.exports = ...    // Ok

exports = ...           // Not OkCopy the code

Why is that?

Exports is just a reference or alias to module.exports. When you modify exports you are inadvertently trying to modify Module. exports, but this modification has no effect on the official API (module. You just get a local variable in the module scope.

Question #7: Why is the top-level variable not a global variable?

If you define a top-level variable g in module1:

// module1.js

var g = 42;Copy the code

And if you rely on module1 in module2 and try to access the variable g, you get the error G is not defined.

Why is that? If you perform the same operation in the browser, you can access top-level defined variables in all scripts.

Each Node file has its own IIFE behind it (call function expressions immediately), and all variables declared in a Node file are limited to this IIFE scope.

Related issue: There is only one line of code in a Node file. What does this output:

// script.js</pre>

console.log(arguments);Copy the code

You’ll see some parameters!

Why is that?

Because Node executes a function. Node wraps your code in a function that explicitly defines the five arguments you saw above.

Question # 8:exports,require, andmoduleThree objects are globally available in each file, but they differ in each file. Why?

When you need to use require objects, you just use them directly like global variables. However, if you compare require objects in 2 different files, you’ll find 2 different objects. What’s going on?

IIFE (call function expressions immediately) for the same reason:

As you can see, IIFF passes the following five arguments to your code: exports, require, module, __filename, and __dirname.

When you use these five variables in Node, it seems like you’re using global variables, but they’re just function arguments.

Question #9: What are loop dependencies in Node?

What happens if you have a module1 dependent on Module2, and module2 in turn dependent on Module1? A mistake?

// module1

require('./module2');

// module2

require('./module1');Copy the code

Rest assured, no errors will be reported, Node allows this.

Therefore, Module1 depends on Module2, but because Module2 depends on Module1, which is not ready at this point, module1 will only get an incomplete version of Module2.

The system has sent out a warning.

Question #10: When is it appropriate to use a file systemsynchronousMethods (like readFileSync)?

Each Node has a synchronous version of the FS method. Why would you use a synchronous method instead of an asynchronous one?

Sometimes it is good to use synchronous methods, for example, for any initialization while the server is still loading. Typically, after the initialization is complete, your next job is to proceed with the job based on the data obtained rather than introducing the callback level. Using synchronous methods is acceptable, as long as the method you use is one-off.

However, if you use a synchronous method in an on-request callback like an HTTP server, it’s 100% wrong! Don’t do that.

I hope you can answer some or all of these questions, but here’s my article that goes into node.js in a bit more detail:

  • Before you bury yourself in packages, learn the Node.js runtime itself
  • Requiring modules in Node.js: Everything you need to know
  • Understanding Node.js Event-Driven Architecture
  • Node.js Streams: Everything you need to know
  • Node.js Child Processes: Everything you need to know
  • Scaling Node.js Applications

The Nuggets Translation Project is a community that translates quality Internet technical articles from English sharing articles on nuggets. The content covers Android, iOS, React, front-end, back-end, product, design and other fields. If you want to see more high-quality translation, please continue to pay attention to the Project, official Weibo, Zhihu column.