search
HomeWeb Front-endJS TutorialUnderstanding the module system in Node.js

Understanding the module system in Node.js

Nov 24, 2020 pm 05:58 PM
node.jsModule system

Understanding the module system in Node.js

Related recommendations: "node js tutorial"

Node.js module

JavaScript as a A simple scripting language to add interactive functions to web pages came out. It did not include a module system at the beginning. As JavaScript solved more and more complex problems, writing all codes in one file and using function to distinguish functional units can no longer support the development of complex applications. Yes, ES6 brings classes and modules that are common in most high-level languages, making it easier for developers to organize code

import _ from 'lodash';

class Fun {}

export default Fun;

The above three lines of code show the two most important elements of a module system, import and export

  • export is used to specify the external interface of the module

  • import is used to import the functions provided by other modules

Before ES6, many module loading solutions appeared in the community, the most important ones were CommonJS and AMD. Node.js was born earlier than ES6, and the module system used something similar to CommonJS The implementation follows several principles

  • A file is a module, and the scope of variables in the file is within the module

  • Usemodule.exports Object export module external interface

  • Use require to introduce other modules

circle.js

const { PI } = Math;

module.exports = function area(r) {
  PI * r ** 2;
};

The above code implements a module of Node.js. The module does not depend on other modules and exports the methodarea to calculate the area of ​​a circle

test.js

const area = require('./circle.js');
console.log(`半径为 4 的圆的面积是 ${area(4)}`);

The module relies on circle.js and uses its exposed area method to calculate the area of ​​the circle

module.exports

The external exposed interface of the module uses module.exports. There are two common usages: adding attributes to it or assigning values ​​to new objects.
test.js

// 添加属性
module.exports.prop1 = xxx;
module.exports.funA = xxx;
module.exports.funB = xxx;

// 赋值到全新对象
module.exports = {
  prop1,
	funA,
  funB,
};

The two writing methods are equal to Price, there is no difference when using

const mod = require('./test.js');

console.log(mod.prop1);
console.log(mod.funA());

There is another way to directly use the exports object, but you can only add attributes to it and cannot assign it to a new object. The reason will be introduced later.

// 正确的写法:添加属性
exports.prop1 = xxx;
exports.funA = xxx;
exports.funB = xxx;

// 赋值到全新对象
module.exports = {
  prop1,
	funA,
  funB,
};

require('id')

Module type

require usage is relatively simple, id supports two types: module name and file path

Module name

const fs = require('fs');
const _ = require('lodash');

The fs and lodash in the example are both module names. fs is the built-in core module of Node.js, and lodash is a third-party module installed through npm under node_modules. If there are duplicate names , give priority to using the system’s built-in modules

Because a project may contain multiple node_modules folders (Node.js’ relatively failed design), the third-party module search process will follow the principle of proximity and go up layer by layer (you can find it in the program Print module.paths to view the specific search path) until the file system root directory is found according to the NODE_PATH environment variable. For the specific process, please refer to the official documentation

In addition, Node .js also searches the following global directory listing:

  • $HOME/.node_modules
  • $HOME/.node_libraries
  • $PREFIX/lib/node

$HOME is the user's home directory, $PREFIX is the node_prefix configured in Node.js. It is strongly recommended to place all dependencies in the local node_modules directory, which will load faster and be more reliable

File path

Modules can also be loaded using file paths. This is the project A common loading method for custom modules within the directory. The path extension can be omitted. Modules prefixed with

'/'
    will be tried in the order of .js, .json, and .node.
  • Is the absolute path of the file. Find the module according to the system path.
  • Modules prefixed with './' are relative to the file currently calling the require method, and are not affected by where subsequent modules are used. To affect

Single loading & circular dependency

The module will be cached to Module._cache after the first load, if it is called every time ## If #require('foo') is parsed to the same file, the same object will be returned. Calling require(foo) multiple times at the same time will not cause the module's code to be executed multiple times. Node.js caches modules based on their actual file names, so the same module is not loaded twice when referenced from different levels of directories.

The understood module single loading mechanism facilitates our understanding of the phenomenon of module circular dependencies


a.js

console.log('a 开始');
exports.done = false;
const b = require('./b.js');
console.log('在 a 中,b.done = %j', b.done);
exports.done = true;
console.log('a 结束');

b.js

console.log('b 开始');
exports.done = false;
const a = require('./a.js');
console.log('在 b 中,a.done = %j', a.done);
exports.done = true;
console.log('b 结束');

main.js:

console.log('main 开始');
const a = require('./a.js');
const b = require('./b.js');
console.log('在 main 中,a.done=%j,b.done=%j', a.done, b.done);
When main.js loads a.js, a.js loads b.js. At this time, b.js will Try to load a.js

In order to prevent an infinite loop, an

unfinished copy of the exports object of a.js will be returned to the b.js module, and then b.js will complete the loading. And provide the exports object to the a.js module

so the output of the example is

main 开始
a 开始
b 开始
在 b 中,a.done = false
b 结束
在 a 中,b.done = true
a 结束
在 main 中,a.done=true,b.done=true

看不懂上面的过程也没关系,日常工作根本用不到,即使看懂了也不要在项目中使用循环依赖!

工作原理

Node.js 每个文件都是一个模块,模块内的变量都是局部变量,不会污染全局变量,在执行模块代码之前,Node.js 会使用一个如下的函数封装器将模块封装

(function(exports, require, module, __filename, __dirname) {
	// 模块的代码实际上在这里
});
  • __filename:当前模块文件的绝对路径
  • __dirname:当前模块文件据所在目录的绝对路径
  • module:当前的模块实例
  • require:加载其它模块的方法,module.require 的快捷方式
  • exports:导出模块接口的对象,module.exports 的快捷方式

回头看看最开始的问题,为什么 exports 对象不支持赋值为其它对象?把上面函数添加一句 exports 对象来源就很简单了

const exports = module.exports;
(function(exports, require, module, __filename, __dirname) {
	// 模块的代码实际上在这里
});

其它模块 require 到的肯定是模块的 module.exports 对象,如果吧 exports 对象赋值给其它对象,就和 module.exports 对象断开了连接,自然就没用了

在 Node.js 中使用 ES Module

随着 ES6 使用越来越广泛,Node.js 也支持了 ES6 Module,有几种方法

babel 构建

使用 babel 构建是在 v12 之前版本最简单、通用的方式,具体配置参考 @babel/preset-env(https://babeljs.io/docs/en/babel-preset-env)

.babelrc

{
  "presets": [
    ["@babel/preset-env", {
      "targets": {
        "node": "8.9.0",
        "esmodules": true
      }      
    }]
  ]
}

原生支持

在 v12 后可以使用原生方式支持 ES Module

  • 开启 --experimental-modules

  • 模块名修改为 .mjs (强烈不推荐使用)或者 package.json 中设置 "type": module

这样 Node.js 会把 js 文件都当做 ES Module 来处理,更多详情参考官方文档(https://nodejs.org/dist/latest-v13.x/docs/api/esm.html)

更多编程相关知识,请访问:编程视频!!

The above is the detailed content of Understanding the module system in Node.js. For more information, please follow other related articles on the PHP Chinese website!

Statement
This article is reproduced at:博客园. If there is any infringement, please contact admin@php.cn delete
From Websites to Apps: The Diverse Applications of JavaScriptFrom Websites to Apps: The Diverse Applications of JavaScriptApr 22, 2025 am 12:02 AM

JavaScript is widely used in websites, mobile applications, desktop applications and server-side programming. 1) In website development, JavaScript operates DOM together with HTML and CSS to achieve dynamic effects and supports frameworks such as jQuery and React. 2) Through ReactNative and Ionic, JavaScript is used to develop cross-platform mobile applications. 3) The Electron framework enables JavaScript to build desktop applications. 4) Node.js allows JavaScript to run on the server side and supports high concurrent requests.

Python vs. JavaScript: Use Cases and Applications ComparedPython vs. JavaScript: Use Cases and Applications ComparedApr 21, 2025 am 12:01 AM

Python is more suitable for data science and automation, while JavaScript is more suitable for front-end and full-stack development. 1. Python performs well in data science and machine learning, using libraries such as NumPy and Pandas for data processing and modeling. 2. Python is concise and efficient in automation and scripting. 3. JavaScript is indispensable in front-end development and is used to build dynamic web pages and single-page applications. 4. JavaScript plays a role in back-end development through Node.js and supports full-stack development.

The Role of C/C   in JavaScript Interpreters and CompilersThe Role of C/C in JavaScript Interpreters and CompilersApr 20, 2025 am 12:01 AM

C and C play a vital role in the JavaScript engine, mainly used to implement interpreters and JIT compilers. 1) C is used to parse JavaScript source code and generate an abstract syntax tree. 2) C is responsible for generating and executing bytecode. 3) C implements the JIT compiler, optimizes and compiles hot-spot code at runtime, and significantly improves the execution efficiency of JavaScript.

JavaScript in Action: Real-World Examples and ProjectsJavaScript in Action: Real-World Examples and ProjectsApr 19, 2025 am 12:13 AM

JavaScript's application in the real world includes front-end and back-end development. 1) Display front-end applications by building a TODO list application, involving DOM operations and event processing. 2) Build RESTfulAPI through Node.js and Express to demonstrate back-end applications.

JavaScript and the Web: Core Functionality and Use CasesJavaScript and the Web: Core Functionality and Use CasesApr 18, 2025 am 12:19 AM

The main uses of JavaScript in web development include client interaction, form verification and asynchronous communication. 1) Dynamic content update and user interaction through DOM operations; 2) Client verification is carried out before the user submits data to improve the user experience; 3) Refreshless communication with the server is achieved through AJAX technology.

Understanding the JavaScript Engine: Implementation DetailsUnderstanding the JavaScript Engine: Implementation DetailsApr 17, 2025 am 12:05 AM

Understanding how JavaScript engine works internally is important to developers because it helps write more efficient code and understand performance bottlenecks and optimization strategies. 1) The engine's workflow includes three stages: parsing, compiling and execution; 2) During the execution process, the engine will perform dynamic optimization, such as inline cache and hidden classes; 3) Best practices include avoiding global variables, optimizing loops, using const and lets, and avoiding excessive use of closures.

Python vs. JavaScript: The Learning Curve and Ease of UsePython vs. JavaScript: The Learning Curve and Ease of UseApr 16, 2025 am 12:12 AM

Python is more suitable for beginners, with a smooth learning curve and concise syntax; JavaScript is suitable for front-end development, with a steep learning curve and flexible syntax. 1. Python syntax is intuitive and suitable for data science and back-end development. 2. JavaScript is flexible and widely used in front-end and server-side programming.

Python vs. JavaScript: Community, Libraries, and ResourcesPython vs. JavaScript: Community, Libraries, and ResourcesApr 15, 2025 am 12:16 AM

Python and JavaScript have their own advantages and disadvantages in terms of community, libraries and resources. 1) The Python community is friendly and suitable for beginners, but the front-end development resources are not as rich as JavaScript. 2) Python is powerful in data science and machine learning libraries, while JavaScript is better in front-end development libraries and frameworks. 3) Both have rich learning resources, but Python is suitable for starting with official documents, while JavaScript is better with MDNWebDocs. The choice should be based on project needs and personal interests.

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

MantisBT

MantisBT

Mantis is an easy-to-deploy web-based defect tracking tool designed to aid in product defect tracking. It requires PHP, MySQL and a web server. Check out our demo and hosting services.

Dreamweaver Mac version

Dreamweaver Mac version

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

PhpStorm Mac version

PhpStorm Mac version

The latest (2018.2.1) professional PHP integrated development tool

WebStorm Mac version

WebStorm Mac version

Useful JavaScript development tools