NodeJS -- 基础与模块机制

本文介绍了Node.js的基础知识,包括其特点、异步I/O机制、事件与回调函数、单线程特性、跨平台优势及使用场景。同时深入探讨了CommonJS模块机制,详细解释了如何在Node.js中引入和定义模块。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Node基础知识

Node的特点

  • 异步I/O
  • 事件与回调函数
  • 单线程
  • 跨平台

使用Node的场景

  • 前后端编程语言环境统一
  • 高性能I/O用于实时应用
  • 并行I/O可以更高效利用分布式环境,提升Web渲染能力
  • 构建前端工具类的应用

模块机制

CommonJS模块机制

1.模块引用

  • 使用require()方法,接受模块标识,以此引入一个模块的API到当前上下文中
var math = require('math');
复制代码

2.模块定义

  • exports对象用于到处当前模块的方法或变量
  • 在模块中,一个module对象就代表模块自身
// math.js
exports.add = function() {
    var sum = 0, i = 0, args = arguments, l = args.length;
    while(i < l) {
        sum += args[i++];
    }
    return sum;
};
复制代码

3.模块标识

  • 模块表示就是传递给require()方法的参数,必须符合小驼峰命名的字符串

Node的模块实现

1.Node中引入模块的3个步骤

  • 路径分析
  • 文件定位
  • 编译执行 注:Node对引入过的模块会进行缓存,以减少二次引入时的开销。require方法对于相同模块的二次加载,均采用缓存优先的方式,而较文件模块而言,Node会优先执行核心模块的缓存检查。与前端浏览器缓存静态脚本不同的是,浏览器仅仅缓存文件,而Node缓存的是编译和执行之后的对象

2.模块标识符

  • 核心模块(Node提供的),如:http、fs、path等
  • 以.或..开始的相对路径文件模块
  • 以/开始的绝对路径文件模块
  • 非路径形式的文件模块,如自定义的connect模块

3.模块路径

  • 是Node在定位文件模块的具体文件时指定的查找策略,具体表现为一个路径组成的数组
  • 这个数组包含 1)当前文件目录下的node_modules目录 2)父目录下的node_modules目录 3)父目录的父目录下的node_modules目录 4)沿路径向上逐级递归,直到根目录下的Node_modules目录

4.文件定位

  • 若require()的标识符若不出现文件扩展名,Node将按照.js, .json, .node的顺序依次补足扩展名进行尝试

5.模块编译

  • 每个文件模块都是一个对象
  • 每个编译成功的模块都会将其文件路径所谓索引缓存在Module._cache对象
  • .js文件通过fs模块同步读取文件后编译执行
  • .node文件通过dlopen()方法加载最后编译生成的文件
  • .json文件通过fs模块同步读取文件后,用JSON.parse()解析后返回结果
console.log(require.extendsions);
{'.js': [Function], '.json': [Function], '.node': [Function]}
复制代码
  1. JavaScript模块的编译
  • 在编译的过程中,Node对获取到的JavaScript文件内容进行了头尾包装,从而避免了污染全局环境
  • 每个模块文件之间都进行了作用域的隔离
(function(exports, require, module, __filename, __dirname) {
    var math = require('math');
    exports.area = function(radius) {
        return Math.PI * radius * radius;
    }
}
复制代码

前后端共用模块

1.AMD

define(id?, dependencies?, factory);
复制代码
  • AMD的模块id和依赖是可选的,但是必须在声明时指定;
  • 通过define来明确定义一个模块可以进行作用域隔离

2.CMD

define(['dep1', 'dep2'], function(dep1, deps){
    return function(){};
});
复制代码
  • CMD支持动态引入依赖,无需再声明模块时就指定
  1. 兼容多种模块规范
var multipleModules = function(name, definition){
    var hasDefine = typeof define === 'function';
    var hasExports = typeof module !== 'undefined' && module.exports;
    
    if(hasDefine) {
        // AMD or CMD
        define(definition);
    } else if(hasExports) {
        // Node模块
        module.exports = definition();
    } else {
        // 将模块执行结果挂在window变量中
        this[name]= definition();
    }
}
复制代码

转载于:https://juejin.im/post/5b27ab63e51d45589678a58d

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值