Classification of modules (core modules, file modules, third-party modules)
In Node.js, modules are the fundamental units of code organization and reuse. Depending on their source and usage, Node.js modules can be categorized into core modules, file modules, and third-party modules. Each type has distinct loading mechanisms and application scenarios, and understanding their differences is crucial for developing efficient and maintainable applications.
Core Modules
Core modules are built-in modules provided by Node.js and installed with the runtime. These modules typically offer foundational functionalities such as file system operations, network communication, and path handling. Core modules load the fastest because they are compiled into binary files when the Node.js process starts.
Examples of Common Core Modules
-
fs
: File system operationsconst fs = require('fs'); fs.readFile('/path/to/file', 'utf8', (err, data) => { if (err) throw err; console.log(data); });
-
http
: Creating an HTTP serverconst http = require('http'); http.createServer((req, res) => { res.end('Hello World'); }).listen(3000);
-
path
: Path handlingconst path = require('path'); const fullPath = path.join(__dirname, 'files', 'test.txt');
Characteristics of Core Modules
- No separate installation required; loaded directly via
require
- No need to specify a path when loading (e.g.,
require('fs')
) - Optimal performance; prioritize using core modules for functionality
File Modules
File modules are custom modules created by developers, typically stored in project directories. These modules can be a single JavaScript file or a directory containing an index.js
file. File modules are loaded via relative or absolute paths.
Creating and Using File Modules
1. Single File Module
// calculator.js
function add(a, b) {
return a + b;
}
module.exports = { add };
// app.js
const calc = require('./calculator');
console.log(calc.add(2, 3)); // Outputs 5
2. Directory Module
/my-module
├── index.js
├── utils.js
└── package.json
// my-module/index.js
const { helper } = require('./utils');
module.exports = {
main: () => helper()
};
// app.js
const myModule = require('./my-module');
File Module Loading Rules
- Exact filename matching:
require('./module')
attempts the following in order:module.js
module.json
module.node
- Directory loading: When the
require
path is a directory, it looks for:- The file specified in the
main
field of the directory'spackage.json
index.js
in the directoryindex.json
in the directoryindex.node
in the directory
- The file specified in the
Third-Party Modules
Third-party modules are community or organization-provided modules installed via npm (Node Package Manager). These modules are typically stored in the project's node_modules
directory and solve domain-specific problems or provide advanced functionality.
Using Third-Party Modules
- Install the module
npm install lodash
- Reference in code
const _ = require('lodash');
const users = [
{ 'user': 'barney', 'age': 36 },
{ 'user': 'fred', 'age': 40 }
];
const names = _.map(users, 'user'); // ['barney', 'fred']
Examples of Common Third-Party Modules
-
express
: Web application frameworkconst express = require('express'); const app = express(); app.get('/', (req, res) => res.send('Hello World')); app.listen(3000);
-
mongoose
: MongoDB object modelingconst mongoose = require('mongoose'); mongoose.connect('mongodb://localhost/test'); const Cat = mongoose.model('Cat', { name: String }); const kitty = new Cat({ name: 'Zildjian' }); kitty.save().then(() => console.log('meow'));
-
axios
: HTTP clientconst axios = require('axios'); axios.get('https://api.example.com/data') .then(response => console.log(response.data));
Characteristics of Third-Party Modules
- Must be installed via npm or yarn
- Loaded using only the module name, without a path (e.g.,
require('lodash')
) - Version management is handled via
package.json
- Can include their own dependencies
Module Loading Mechanism
Node.js's module system follows the CommonJS specification, with specific loading logic:
- First checks if it's a core module
- If not a core module, searches in the current directory's
node_modules
- If not found, searches in parent directories'
node_modules
up to the root directory - If a path is specified (e.g.,
./module
), treats it as a file module
Module Caching Mechanism
Node.js caches loaded modules, returning cached results for subsequent require
calls. The cache can be inspected via require.cache
.
console.log(require.cache);
// Output similar to:
// {
// '/path/to/module.js': {
// id: '/path/to/module.js',
// exports: {},
// ...
// }
// }
Module Scope
Each module has its own scope, exposing interfaces via module.exports
or exports
. Variables and functions inside a module are private by default.
// module.js
const privateVar = 'secret';
function privateFunc() {
console.log(privateVar);
}
module.exports = {
publicFunc: () => privateFunc()
};
// app.js
const mod = require('./module');
mod.publicFunc(); // Outputs "secret"
console.log(mod.privateVar); // undefined
ES Modules vs. CommonJS
Node.js has stable support for ES modules since v12, allowing both systems to coexist:
CommonJS Module
// cjs-module.js
module.exports = { name: 'CJS' };
// app.js
const cjs = require('./cjs-module');
ES Module
// esm-module.mjs
export const name = 'ESM';
// app.mjs
import { name } from './esm-module.mjs';
console.log(name);
Interoperability
-
ES modules can import CommonJS modules
// esm-app.mjs import cjs from './cjs-module.js'; console.log(cjs.name);
-
CommonJS modules cannot directly import ES modules; dynamic imports must be used
// cjs-app.js (async () => { const esm = await import('./esm-module.mjs'); console.log(esm.name); })();
Circular Dependencies
Node.js can handle circular dependencies between modules, but the state of exported values should be noted:
// a.js
console.log('a starting');
exports.done = false;
const b = require('./b');
console.log('in a, b.done =', b.done);
exports.done = true;
console.log('a done');
// b.js
console.log('b starting');
exports.done = false;
const a = require('./a');
console.log('in b, a.done =', a.done);
exports.done = true;
console.log('b done');
// main.js
console.log('main starting');
const a = require('./a');
const b = require('./b');
console.log('in main, a.done=', a.done, 'b.done=', b.done);
Running node main.js
outputs:
main starting
a starting
b starting
in b, a.done = false
b done
in a, b.done = true
a done
in main, a.done= true b.done= true
Module Debugging Tips
-
View module search paths
console.log(module.paths);
-
Get current module information
console.log(module);
-
Delete module cache (for hot reloading during development)
delete require.cache[require.resolve('./module')]; const freshModule = require('./module');
-
Check module type
const fs = require('fs'); console.log(require.resolve.paths('fs')); // null indicates a core module console.log(require.resolve.paths('lodash')); // array indicates a third-party module
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:Node.js的REPL环境
下一篇:require机制与模块加载过程