阿里云主机折上折
  • 微信号
Current Site:Index > Classification of modules (core modules, file modules, third-party modules)

Classification of modules (core modules, file modules, third-party modules)

Author:Chuan Chen 阅读数:26021人阅读 分类: Node.js

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 operations

    const fs = require('fs');
    fs.readFile('/path/to/file', 'utf8', (err, data) => {
      if (err) throw err;
      console.log(data);
    });
    
  • http: Creating an HTTP server

    const http = require('http');
    http.createServer((req, res) => {
      res.end('Hello World');
    }).listen(3000);
    
  • path: Path handling

    const path = require('path');
    const fullPath = path.join(__dirname, 'files', 'test.txt');
    

Characteristics of Core Modules

  1. No separate installation required; loaded directly via require
  2. No need to specify a path when loading (e.g., require('fs'))
  3. 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

  1. Exact filename matching: require('./module') attempts the following in order:
    • module.js
    • module.json
    • module.node
  2. Directory loading: When the require path is a directory, it looks for:
    • The file specified in the main field of the directory's package.json
    • index.js in the directory
    • index.json in the directory
    • index.node in the directory

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

  1. Install the module
npm install lodash
  1. 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 framework

    const express = require('express');
    const app = express();
    app.get('/', (req, res) => res.send('Hello World'));
    app.listen(3000);
    
  • mongoose: MongoDB object modeling

    const 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 client

    const axios = require('axios');
    axios.get('https://api.example.com/data')
      .then(response => console.log(response.data));
    

Characteristics of Third-Party Modules

  1. Must be installed via npm or yarn
  2. Loaded using only the module name, without a path (e.g., require('lodash'))
  3. Version management is handled via package.json
  4. Can include their own dependencies

Module Loading Mechanism

Node.js's module system follows the CommonJS specification, with specific loading logic:

  1. First checks if it's a core module
  2. If not a core module, searches in the current directory's node_modules
  3. If not found, searches in parent directories' node_modules up to the root directory
  4. 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

  1. ES modules can import CommonJS modules

    // esm-app.mjs
    import cjs from './cjs-module.js';
    console.log(cjs.name);
    
  2. 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

  1. View module search paths

    console.log(module.paths);
    
  2. Get current module information

    console.log(module);
    
  3. Delete module cache (for hot reloading during development)

    delete require.cache[require.resolve('./module')];
    const freshModule = require('./module');
    
  4. 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

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.