zoukankan      html  css  js  c++  java
  • Node.js 常用知识点归纳

    一、模块

    http://nodejs.cn/api/modules.html

    1. 模块概念

    在 Node.js 模块系统中,每个文件都被视为一个独立的模块。 例如,假设有一个名为 foo.js 的文件:

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

    在第一行中, foo.js 加载了与 foo.js 在同一目录中的 circle.js 模块。

    以下是 circle.js 的内容:

    const { PI } = Math;
    
    exports.area = (r) => PI * r ** 2;
    
    exports.circumference = (r) => 2 * PI * r;

    circle.js 模块导出了 area() 和 circumference() 函数。通过在特殊的 exports 对象上指定额外的属性,可以将函数和对象添加到模块的根部。

    2. 模块加载

    • Node.js 的 require() 函数的语义被设计得足够通用化,可以支持许多合理的目录结构。
    • require() 总是会优先加载核心模块。 例如, require('http') 始终返回内置的 HTTP 模块,即使有同名文件。

    2.1. 文件模块加载

    如果按确切的文件名没有找到模块,则 Node.js 会尝试带上 .js、 .json等拓展名再加载。

    以 '/' 为前缀的模块是文件的绝对路径。 例如, require('/home/marco/foo.js') 会加载 /home/marco/foo.js 文件。

    以 './' 为前缀的模块是相对于调用 require() 函数所在文件的相对路径。 

    当没有以 '/'、 './' 或 '../' 开头来表示文件时,这个模块必须是一个核心模块或加载自 node_modules 目录。

    2.2. 目录模块加载

    可以把程序和库放到一个单独的目录,然后提供一个单一的入口来指向它。 

    把目录递给 require() 作为一个参数,有三种方式。

    第一种方式是在根目录下创建一个 package.json 文件,并指定一个 main 模块。 例子, package.json 文件类似:

    { 
      "name" : "some-library",
      "main" : "./lib/some-library.js" 
    }
    

    如果这是在 ./some-library 目录中,则 require('./some-library') 会试图加载 ./some-library/lib/some-library.js

    这就是 Node.js 处理 package.json 文件的方式。

    如果目录里没有 package.json 文件,则 Node.js 就会试图加载目录下的 index.js 或 index.node 文件。 例如,如果上面的例子中没有 package.json 文件,则 require('./some-library') 会试图加载:

    • ./some-library/index.js
    • ./some-library/index.node

    2.3. node_modules 目录加载

    如果传递给 require() 的模块标识符不是一个核心模块,也没有以 '/' 、 '../' 或 './' 开头,则 Node.js 会从当前模块的父目录开始,尝试从它的 /node_modules 目录里加载模块。 如果还是没有找到,则移动到再上一层父目录,直到文件系统的根目录。

    例子,如果在 '/home/ry/projects/foo.js' 文件里调用了 require('bar.js'),则 Node.js 会按以下顺序查找:

    • /home/ry/projects/node_modules/bar.js
    • /home/ry/node_modules/bar.js
    • /home/node_modules/bar.js
    • /node_modules/bar.js

    3. 模块作用域

    3.1. __dirname

    当前模块的目录名。 与 __filename 的 path.dirname() 相同。

    示例,从 /Users/mjr 运行 node example.js

    console.log(__dirname);
    // 打印: /Users/mjr
    console.log(path.dirname(__filename));
    // 打印: /Users/mjr

    3.2. __filename

    当前模块的文件名。 这是当前的模块文件的绝对路径。

    示例:从 /Users/mjr 运行 node example.js

    console.log(__filename);
    // 打印: /Users/mjr/example.js
    console.log(__dirname);
    // 打印: /Users/mjr
    

    3.3. exports

    这是一个对于 module.exports 的更简短的引用形式。

    3.4. module

    对当前模块的引用。 module.exports 用于指定一个模块所导出的内容,即可以通过 require() 访问的内容。

    3.5. require()

    用于引入模块、 JSON、或本地文件。 可以从 node_modules 引入模块。 可以使用相对路径(例如 ./、 ./foo、 ./bar/baz、 ../foo)引入本地模块或 JSON 文件,路径会根据 __dirname 定义的目录名或当前工作目录进行处理。

    // 引入本地模块:
    const myLocalModule = require('./path/myLocalModule');
    
    // 引入 JSON 文件:
    const jsonData = require('./path/filename.json');
    
    // 引入 node_modules 模块或 Node.js 内置模块:
    const crypto = require('crypto');

    3.6. require.resolve(request)

    • request: <string> 待解析的模块路径(相对路径)
    • returns: <string>   解析后的模块路径(绝对路径)

    使用内部的 require() 机制查询模块的位置(绝对路径), 此操作只返回解析后的文件名,不会加载该模块。

    示例:在 Node.js 中使用 fs 读取文件的时候,经常碰到要拼一个文件的绝对路径的问题 (fs 处理相对路径均以进程执行目录为准)。

    之前一直的方法都是,使用 path 模块以及 __dirname 变量 。

    fs.readFileSync(path.join(__dirname, './assets/file.txt'));

    使用 require.resolve 可以简化这一过程

    fs.readFileSync(require.resolve('./assets/file.txt'));

    此外, require.resolve 还会在拼接好路径之后检查该路径是否存在, 如果 resolve 的目标路径不存在, 就会抛出 Cannot find module './file.txt' 的异常, 省略了一道检查文件是否存在的工序 (fs.exists).

    4. module 对象

    4.1. module.exports

    module.exports 对象由 Module 系统创建。导出对象需要将对象赋值给 module.exports

    例如,假设正在创建一个名为 a.js 的模块:

    const EventEmitter = require('events');
    
    module.exports = new EventEmitter();
    
    // 处理一些工作,并在一段时间后从模块自身触发 'ready' 事件。
    setTimeout(() => {
      module.exports.emit('ready');
    }, 1000);
    

    然后,在另一个文件中可以这么做:

    const a = require('./a');
    a.on('ready', () => {
      console.log('模块 a 已准备好');
    });
    

    4.2. exports

    这是一个对于 module.exports 的更简短的引用形式。module.exports.f = ... 可以更简洁地写成 exports.f = ...

    二、path(路径)

    path 模块提供用于处理文件路径和目录路径的实用工具。 它可以使用以下方式访问:

    const path = require('path');

    2.1. path.dirname(path)

    path.dirname() 方法返回 path 的目录名。

    path.dirname('/foo/bar/baz/asdf/quux');
    // 返回: '/foo/bar/baz/asdf'
    

    2.2. path.join([...paths])

    path.join() 方法使用平台特定的分隔符将所有给定的 path 片段连接在一起。

    零长度的 path 片段会被忽略。 如果连接的路径字符串是零长度的字符串,则返回 '.',表示当前工作目录。

    path.join('/foo', 'bar', 'baz/asdf', 'quux', '..');
    // 返回: '/foo/bar/baz/asdf'
    
    path.join('foo', {}, 'bar');
    // 抛出 'TypeError: Path must be a string. Received {}'
    

    2.3. path.resolve([...paths])

    path.resolve() 方法将路径或路径片段的序列解析为绝对路径

    每个参数都类似在当前目录执行一个cd操作,从左到右执行,返回的是最后的当前目录(pwd)!

    1. 如果在处理完所有给定的 path 片段之后还未生成绝对路径,则再加上当前工作目录。
    2. 生成的路径需要删除尾部斜杠。
    3. 零长度的 path 片段会被忽略。
    4. 如果没有传入 path 片段,则 path.resolve() 将返回当前工作目录的绝对路径。
    path.resolve('/foo/bar', './baz');
    // 返回: '/foo/bar/baz'
    
    path.resolve('/foo/bar', '/tmp/file/');
    // 返回: '/tmp/file'
    
    path.resolve('wwwroot', 'static_files/png/', '../gif/image.gif');
    // 如果当前工作目录是 /home/myself/node,
    // 则返回 '/home/myself/node/wwwroot/static_files/gif/image.gif'
    

    参考:小tips:path的join和resolve的使用区别

    三、process(进程)

    process 对象是一个全局变量,它提供有关当前 Node.js 进程的信息并对其进行控制。 作为一个全局变量,它始终可供 Node.js 应用程序使用,无需使用 require()

    3.1. process.env

    process.env 属性返回包含用户环境的对象。

    process.env.foo = 'bar';
    console.log(process.env.foo);
    // => bar
  • 相关阅读:
    反汇编角度->C++ const
    反汇编->C++虚函数深度分析
    反汇编->C++内联
    反汇编->C++引用与指针
    数据库初步认识
    数据库系统的结构抽象与演变
    Android · PendingIntent学习
    Android · ContentProvider学习
    notepad++
    MapReduce使用JobControl管理实例
  • 原文地址:https://www.cnblogs.com/codestarer/p/13635521.html
Copyright © 2011-2022 走看看