模块

模块

  • 允许代码分离,将其组织为可维护的单元,提升代码的可复用性和可读性;
  • CommonJS(CJS)、ECMAScript Modules(ESM)

CJS模块系统

  1. 导出模块 只需要使用module.exports或exports将模块中的内容导出即可
  • module.exports,

// 指定属性导出

module.exports.byebye = function (name) {
  console.log(`byebye, ${name}!`)
}
module.exports.userInfo = {
  name: 'dd',
  age: 18
}

// 统一的对象导出

// 在模块中定义一个byebye函数
function byebye(name) {
  console.log(`byebye, ${name}!`)
}

// 定义了一个名为 userInfo 的对象,包含姓名和年龄两个属性
const userInfo = {
  name: 'dd',
  age: 18
}

// 将函数和对象统一导出到模块的外部
module.exports = {
  byebye,
  userInfo
}
  • exports
//  定义一个模块,使用 exports 导出模块中的内容。
// 定义了一个名为 byebye 的函数,用于输出告别语
// 定义了一个名为 userInfo 的对象,包含姓名和年龄两个属性

exports.byebye = function (name) {
  console.log(`byebye, ${name}!`)
}
exports.userInfo = {
  name: 'dd',
  age: 18
}
  • module.exports vs exports
    module.exports 和 exports 都可用于导出 Node.js 模块中的代码的对象;
    exports实际上是module.exports的一个引用,当使用exports导出模块代码时,实际上是在向module.exports添加属性
// 导出一个名为 "hello" 的函数到 "exports" 对象中
// 函数中会将 "Hello World!" 的信息输出到控制台中
exports.hello = function() {
  console.log("Hello World!");
};


// 导出一个名为 "hello" 的函数到 "exports" 对象中
// 函数中会将 "Hello World!" 的信息输出到控制台中
module.exports.hello = function() {
  console.log("Hello World!");
};

// 建议在写 Node.js 模块时,只使用 module.exports 导出模块代码,而不要使用 exports。如果你需要向外部导出多个函数或对象,可以将它们作为 module.exports 的属性导出;
// 外部就可以通过 require 方法导入该模块,并访问其中的 hello 和 bye 方法了。
module.exports = {
  hello: function() {
    console.log("Hello World!");
  },
  bye: function() {
    console.log("Goodbye World!");
  }
};
  1. 引入模块

(1)完整引入

// 导入模块 "./exports" 并将其赋值给变量 context
const context = require('./exports')

// 调用 context 模块中的 hello 函数,并传入 context.userInfo.name 参数
context.hello(context.userInfo.name)

(2)解构引入

// 当导出内容是一个对象时,可以使用解构引入。

// 导入模块 "./exports" 中的 hello, userInfo 和 byebye,并赋值给相应的变量
const { hello, userInfo, byebye } = require('./exports')
// 调用 hello 函数,并传入 userInfo.name 参数
hello(userInfo.name)

ES Modules模块系统(ESM)

  • import/export
  • 默认情况下,.js文件识别为CJS模块;如果需要识别为ES模块,有2种方式:1. 使用.mjs命名;2. package.json种的type字段设置为module;
// package.json
{
  "type":"module"
}
  1. 默认导入导出,使用export default (export default,import xx from 'module');
// 文件 export_default.js
// 导出默认对象
export default {
  // 定义 byebye 方法,输出道别信息
  byebye(name) {
    console.log(`byebye, ${name}!`)
  },
  // 定义 userInfo 对象,存储用户信息
  userInfo: {
    name: 'dd', // 用户名
    age: 18 // 用户年龄
  }
}


// 文件 import_default.js

// 引入 export_default.js 中默认导出的模块
import defaultModule from './export_default.js'

// 调用 defaultModule 中定义的 byebye() 方法,输出道别信息并传入用户姓名
defaultModule.byebye(defaultModule.userInfo.name)

  1. 具名导入导出,使用export (export xx,import { xx } from 'module');
// 文件 export.js

// 定义 byebye 方法,输出道别信息
export function byebye(name) {
  console.log(`byebye, ${name}!`)
}

// 定义 userInfo 对象,存储用户信息
export const userInfo = {
  name: 'dd', // 用户名
  age: 18 // 用户年龄
}


// 文件 import.js

// 引入 export_named.js 中具名导出的模块,使用 as 关键字还可以修改导入内容的名称
import { byebye, hello, userInfo as user } from './export_named.js'

// 调用 byebye() 方法,输出道别信息并传入用户姓名
byebye(user.name)

  1. 导入导出所有对象,可以将另一个模块的内容直接全部导出,导出同时也可以设置默认导出; (export *,import * as xx from 'module');
// 文件 export_all.js

// 从 export.js 中导出所有的模块成员
export * from './export.js'

// 导出一个默认模块,对象包含 goal 属性,初始值为 'learn'
export default {
  goal: 'learn'
}


// 文件 import_all.js

// 导入 export_all.js 中所有被导出的模块成员,并作为 allValues 对象的属性
import * as allValues from './export_all.js'

// 在控制台输出 allValues 对象
console.log(allValues)

// 从 allValues 对象中解构出 hello、byebye、default 和 userInfo 模块成员
const { byebye, default: data, userInfo } = allValues

// 调用 byebye() 方法,输出道别信息并传入用户姓名
byebye(userInfo.name)

// 输出 data 对象的 goal 属性
console.log(data.goal)
  1. 重新导出 (export { xx } from 'module',export * from 'module')
// lib.js
export function hello(name) {
  console.log(`Hello, ${name}!`)
}

export default {
  filename: 'lib.js',
  des: 'lib.js的一些默认导出'
}


// util.js
export function byebye(name) {
  console.log(`ByeBye, ${name}!`)
}

export default {
  filename: 'util.js',
  des: 'util.js的一些默认导出'
}



// index.js
// 从 './lib.js' 中导出 hello 和默认导出并重命名为 libData
export { hello, default as libData } from './lib.js'

// 从 './util.js' 中导出所有命名导出
export * from './util.js'

// 从 './util.js' 中默认导出并重命名为 utilData
export { default as utilData } from './util.js'


// 使用的时候,就统一通过 index.js 引入即可。
// usage.js
import { hello, byebye, libData, utilData } from './index.js'

hello(libData.filename)
byebye(utilData.filename)

CJS vs ESM

  1. 模块加载时机
    CJS支持动态加载模块,require语句可以出现在任意位置;CJS 需要等到代码运行时才能确定依赖关系和加载模块;
    ESM会在所有模块都加载完毕后才执行代码,在使用导入的内容之前导入;ESM 可以在代码执行前进行静态分析和优化,从而提高性能;

  2. 导出内容的区别
    ESM 中,当我们导入一个变量时,实际上是导入了该变量的引用。这意味着,如果导出的变量在导入模块中发生了改变,导入的变量也会随之改变。
    CommonJS 中,导入的是导出模块的值的拷贝,而不是引用。这意味着,即使导出模块中的值发生了改变,导入模块中导入的变量不会受到影响。

ESM 导入的是值的引用,而 CJS 导入的是值的拷贝。

  1. 文件命名
    模块一般都以 .js 结尾,通过 package.json 中 "type":"module" 区分模块类型;

还可通过文件命名来区分 .cjs 表明是 CJS 规范的模块,.mjs 表明是 ESM 规范的模块。

常用的内置模块

  • global 全局对象,挂载了一些常用方法和属性
  • path 提供与文件路径相关的实用工具方法
  • fs 文件系统模块,用于操作文件和目录
  • util 提供一些实用工具函数
  • http 用于创建 HTTP 服务器,也可用于向已有服务发起请求并获取响应
  • child_process 用于创建操作子进程

全局变量

  • js中存在一个特殊的全局对象,可以在任意位置被房屋,通常用globalThis指代。 浏览器中,指向window,node.js中指向global。
  • 直接使用一些无需定义的方法时,都是global上的属性,如console,setTimeout。
  • 特殊全局变量:__filename,表示当前正在执行的脚本文件的绝对路径;__dirname ,表示当前执行脚本所在目录的绝对路径;(这两个变量只在CJS下存在)
  • 常用global属性:process(提供了与当前 Node.js 进程相关的信息和控制方法),Buffer( 用于处理二进制数据)
// process.argv 返回一个数组,包含启动 Node.js 进程时传递的命令行参数。
// process.cwd() 获取当前工作目录的绝对路径。
// process.version 获取当前 Node 版本。
// process.env 获取当前执行环境的环境变量 (对象形式)。
// process.pid:返回进程的 PID (进程 ID);
// process.platform:返回运行 Node.js 的操作系统平台;
// process.arch:获取 CPU 架构信息


// process.stdout:标准输出流,常用 process.stdout.write 进行数据写入。
process.stdout.write('hello')


// process.stdin:用于从标准输入流 (stdin) 读取数据。
// 监听用户输入数据
process.stdin.on('data', (data) => {
  console.log(`User input: ${data}`);
});

// 创建Buffer对象
const buf = Buffer.alloc(10); // 创建一个大小为 10 的 Buffer 对象,默认会用 0 填充
const buf2 = Buffer.from('Hello, world!'); // 创建一个包含字符串 'Hello, world!' 的 Buffer 对象
const buf3 = Buffer.from([0x68, 0x65, 0x6c, 0x6c, 0x6f]); // 内容为hello构成的16进制数组 Buffer 对象 


// 转换内容格式
const buf = Buffer.from('Hello, world!');
// 转为字符串输出
console.log(buf.toString()); // 输出 'Hello, world!'

// 转为16进制字符串输出
console.log(buf.toString('hex')); // 输出 '48656c6c6f2c20776f726c6421'(对应的是 'Hello, world!' 的 ASCII 码)

// 转为数组输出
console.log(Array.from(buf)); 

// 转为base64格式输出
console.log(buf.toString('base64')); // 输出 'SGVsbG8sIHdvcmxkIQ=='


// 写入内容
// 创建一个长度为 10 的 Buffer 实例并将它填充为 0
const buf = Buffer.alloc(10);

// 将字符串 'Hello' 写入 Buffer 实例的前 5 个字节
buf.write('Hello');

// 将字符串 'world' 写入 Buffer 实例的第 6 个字节开始的位置,由于 'world' 的长度为 5,所以不会覆盖掉之前写入的 'Hello'
buf.write('world', 5); 

// 将 Buffer 实例转换为字符串并输出 'Hello world'
console.log(buf.toString()); 



// 合并多个Buffer对象
const buf1 = Buffer.from('Hello');
const buf2 = Buffer.from('World');
const buf3 = Buffer.concat([buf1, buf2]);
console.log(buf3.toString()); // 输出 'HelloWorld'


// 截取Buffer对象
const buf = Buffer.from('Hello, world!');
const buf2 = buf.slice(0, 5);
console.log(buf2.toString()); // 输出 'Hello'

path路径处理

// path.join 将多个路径拼接成一个相对路径 (或绝对路径,取决于第一个路径是否为根路径)。
import path from 'path'

console.log(path.join('a', 'b', 'c'))
console.log(path.join(process.cwd(), '/hello', 'world'))


// path.resolve 将多个路径拼接成一个绝对路径,返回一个解析后的绝对路径。即如果传入相对路径,会以当前工作目录为基准,计算出绝对路径,如果传入了绝对路径,则以传入的绝对路径为基准。
import path from 'path';

console.log('=== path.resolve ===')
console.log(path.resolve('a', 'b', 'c'))
console.log(path.resolve('/hello', 'world', './a', 'b'))


// path.dirname  返回路径中的目录名
console.log('=== path.dirname ===')
console.log(path.dirname(process.cwd()))
console.log(path.dirname('/a/b/c'))


// path.basename 返回路径中的文件名,并可选地去除给定的文件扩展名。
console.log('=== path.basename ===')
console.log(path.basename('a/b/c.js'))
console.log(path.basename('a/b/c.js', '.js'))
console.log(path.basename('a/b/c.js', 'js'))
console.log(path.basename('a/b/c.js', 's'))


// path.extname 获取路径中的文件扩展名。
console.log('=== path.extname ===')
console.log(path.extname('a/b/c.js'))
console.log(path.extname('a/b/c'))
console.log(path.extname('a/b/c.d.ts'))
console.log(path.extname('a/b/.npmrc'))


// path.normalize  主要用于规范化路径,将路径中的不规范部分调整为标准格式
console.log('=== path.normalize ===')
console.log(path.normalize('a//b//c/d/e/..'))


// path.parse 用于解析文件路径,将其拆分为一个对象。
console.log('=== path.parse ===')
console.log(path.parse('/home/user/dir/file.txt'))


// path.sep  返回当前系统文件路径使用的分隔符。避免因为不同操作系统使用不同的文件路径分隔符而导致的错误。更推荐使用 path.join 方法来拼接文件路径:
console.log('=== path.sep ===')
console.log('foo/bar/baz'.split(path.sep))
const dir = 'users'
const file = 'index.html'
console.log(dir + path.sep + file)



fs文件系统

  • 用于操作文件和目录;支持同步 (sync) 或者异步 (async/callback) 调用,其中同步调用会阻塞主线程,异步调用不会阻塞。
import fs from "fs";

// 同步读取
const syncData = fs.readFileSync('./test.txt', 'utf-8');
console.log('syncData: ', syncData);



// 回调形式,异步读取
fs.readFile('./test.txt', 'utf-8', (err, callbackData) => {
  if (!err) {
    console.log('callbackData: ', callbackData);

  }
})



// promise形式 异步读取
fs.promises.readFile('./test.txt', 'utf-8').then((promiseData) => {
  console.log('promiseData: ', promiseData);
})


  1. 文件操作
// 读取文件
import fs from 'fs'
const txtContent = fs.readFileSync('./test.txt', 'utf-8')


// 以二进制形式读取,操作。
const buf = fs.readFileSync('./test.txt')

// 打印Buffer大小
console.log(buf.length)
// 修改前2个字符
buf.write('gg')

// 输出修改后的内容
console.log(buf.toString())


// 写入文件
fs.writeFileSync('./newTest.txt', 'hello world')


// 写入二进制文件
// 读取一个图片
const imgBuf = fs.readFileSync('./logo.png')
console.log('isBuffer', Buffer.isBuffer(imgBuf), 'bufferSize', imgBuf.length)

// 写入到新文件
fs.writeFileSync('newLogo.png', imgBuf, 'binary')



// 获取文件或目录的基本信息
import fs from 'fs'

console.log(fs.statSync('./test.txt'))
console.log(fs.statSync('./test-dir'))

// 返回的对象上还包含可直接调用的方案,用于判断文件类型。
const fileInfo = fs.statSync('./test.txt')
// 判断是文件还是目录
console.log(fileInfo.isFile(), fileInfo.isDirectory())

const dirInfo = fs.statSync('./test-dir')
// 判断是文件还是目录
console.log(dirInfo.isFile(), dirInfo.isDirectory())

try {
  // 查询一个不存在的文件/目录信息(会抛出异常,需要自行捕获)
  fs.statSync('not_exist.txt')
} catch (e) {
  console.log('文件不存在')
}


// 追加输出,fs.appendFileSync向文件末尾追加写入内容
import fs from "fs";
fs.appendFileSync("test.txt", "hello");



// 移动或重命名文件 fs.renameSync
import fs from "fs";
fs.renameSync('test.txt', 'test2.txt');
fs.renameSync("test2.txt", "test-dir/test2.txt");



// 删除文件 fs.unlinkSync  fs.rmSync都可用于单文件删除,fs.rmSync还支持删除目录,递归删除子文件或目录
fs.rmSync('test-dir', {recursive: true});

  1. 目录操作
// 读取目录所有文件fs.readdirSync
import fs from "fs";
const files = fs.readdirSync('test-dir');
const files2 = fs.readdirSync('test-dir', {withFileTypes: true});
console.log(files, files2);


// 创建目录fs.mkdirSync  recursive:true递归创建
fs.mkdirSync('test-dir/a/b/c', {recursive: true});


// 删除目录 fs.rmdirSync recursive:true表明删除包含其子目录
fs.rmdirSync('test-dir/a', {recursive: true});
fs.rmSync('test-dir/a', { recursive: true })



// 监听目录变更fs.watch
// 监听当前目录下所有的文件和子目录中的文件
fs.watch('./', {recursive: true}, (eventType, filename) => {
  console.log(`File '${filename}' has changed: ${eventType}`)
})


util工具

// 对象转字符串:util.inspect(object, [options]),常与 console.log 搭配使用,可以友好的将对象转为字符串,打印更加友好。
// 复杂对象
const testObj = {
  a: 1,
  b: {
    c: 2,
    d: [3, 4, 5],
    e: () => {
      console.log(6)
    }
  },
  f: '7',
  g: [{ 8: [{ 9: 10 }] }],
  h() {
    console.log(11)
  }
}

console.log(testObj); // 普通打印,可以看到嵌套的数组和函数没有办法打印出来
console.log(JSON.stringify(testObj, null, 2)); // 函数没有了
console.log(util.inspect(testObj, { depth: Math.Infinity })); // 深层的数组和对象被展开了,嵌套函数看不到
// npm i javascript-stringify
import { stringify } from 'javascript-stringify'
console.log(stringify(testObj, null, 2)); // 能保持和传入的结果基本一致。



// 格式化字符串 util.format
import util from 'util'
console.log(util.format('%s:%s', 'foo', 'bar')) // 'foo:bar'
console.log(util.format('%d + %d = %d', 1, 2, 3)) // '1 + 2 = 3'

console.log(
  util.format('My name is %j', { firstName: 'John', lastName: 'Doe' })
)


// 判断数据类型
import util from 'util'

// 判断数据类型
console.log(util.isArray([])) // true
console.log(util.isRegExp(/some regexp/)) // true
console.log(util.isDate(new Date())) // true
console.log(util.isPrimitive(null)) // true
console.log(util.isPrimitive(1)) // true


// 回调转promise util.promisify(original) 用于将常规带有回调函数的方法转为返回Promise对象的方法
import util from "util";
import fs from "fs";
// 将fs.readFile方法转为返回Promise的函数
const fsRead = util.promisify(fs.readFile);
// 使用Promise的方式读取文件内容并输出
fsRead('./package.json').then((data) => {
  console.log(data.toString());
})


--

http/https

  • 用于创建HTTP服务器,也可用于向已有的服务发起请求并获取响应
// http.get 发起请求
import https from "https";
https.get('https://api-url',
 (res) => {
  // 响应内容
  let content = "";
  res.on('data', (chunk) => {
    content += chunk;
  });

  // 读完对我暴露内容和状态码
  res.on('end', () => {
    console.log(content);
  });

  res.on('error', (er) => {
    console.log(err);
  })
 }
)


// 传参
const req = https.get(
  'https://api-url',
  {
    headers: {
      'Content-Type': 'application/json'
    }
  }
)

req.on('response', (res) => {
  // 响应内容拼接
  let content = ''
  res.on('data', (chunk) => {
    content += chunk
  })

  res.on('end', () => {
    console.log(content)
  })

  res.on('error', (err) => {
    console.log(err)
  })
})

// http.request
import https from 'https'

const url = new URL(
  'https://api-url'
)

const req = https.request(
  {
    // 设置请求方法
    method: 'GET',
    // http 80 https 443
    port: 443,
    hostname: url.hostname,
    path: url.pathname + url.search
  },
  (res) => {
    let content = ''
    res.on('data', (chunk) => {
      content += chunk
    })
    res.on('end', () => {
      console.log('statusCode', res.statusCode)
      console.log(content)
    })
  }
)
// 发送请求
req.end()

// fetch
fetch(
  'https://api-url'
)
  .then((res) => res.json())
  .then((data) => {
    console.log(data)
  })
  .catch((err) => {
    console.error(err)
  })

  // axios
  // npm i axios
  axios
  .get(
    'https://api-url'
  )
  .then((res) => {
    console.log(res.data)
  })
  .catch((err) => {
    console.error(err)
  })

// server.mjs http.createServer创建Web服务
import http from 'http'

const server = http.createServer((req, res) => {
  // 获取请求的路径和方法
  const { url, method } = req

  res.statusCode = 200
  res.setHeader('Content-Type', 'text/html')
  res.end('<h1>Hello, World!</h1>')
})
server.listen(4275, () => {
  console.log('Server running at http://127.0.0.1:4275/')
})

// node server.mjs
// 启动后可以通过fetch调用 
fetch('http://127.0.0.1:4275?hello=world', {
  method: 'POST'
})

// request内容

//  query 参数解析
// /a/b/c?name=123&age18

fetch('http://127.0.0.1:4275?hello=world', {
  method: 'POST'
})

const { url, method } = req
const query = Object.fromEntries(
  new URL(url, 'http://localhost').searchParams
)

// body 参数解析
fetch('http://127.0.0.1:4275?hello=world', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    name: 'xm',
    age: 18
  })
})
// 通过监听data和end事件获取
let body = []
req
  .on('data', (chunk) => {
    body.push(chunk)
  })
  .on('end', () => {
    body = Buffer.concat(body).toString()
    body = JSON.parse(body)
    console.log('body', body)
  })

// headers 参数解析
console.log('headers', req.headers)



// response内容
// 设置响应状态码为 200
res.statusCode = 200;
// 设置响应头,指定响应内容类型为 text/html
res.setHeader('Content-Type', 'text/html');
// 发送响应内容到客户端,结束响应
res.end('<h1>Hello, World!</h1>');

res.setHeader('Content-Type', 'application/json')


chiild_process 用于创建子进程

  • js单线程,但通过创建子进程也能实现多任务并行处理,也可以通过其调用系统的功能指令完成复杂的任务
  • 提供了4个方法:spawn、exec、execFile、fork

pwd 获取当前目录的路径,ls 获取当前目录下的文件

// spawn异步 spawnSync同步  启动一个子进程来执行指定的命令,并且可以通过流式数据通信与子进程进行交互
import ChildProcess from 'child_process'

const { spawn, spawnSync } = ChildProcess

const pwd = spawnSync('pwd')
console.log(pwd.stdout.toString())
const ls = spawnSync('ls', ['-lh'])
console.log(ls.stdout.toString())


// exec,execSync 启动一个 shell,并在 shell 中执行指定命令,执行完毕后插入 stdout/stderr 中,适用于一些命令行工具;
import { exec, execSync } from 'child_process'

const pwd = execSync('pwd')
console.log(pwd.toString())
const ls = execSync('ls -lh')
console.log(ls.toString())

const file = './../fs/index.mjs'
const execProcess = exec(`git log -1 --pretty="%ci" ${file}`)
execProcess.stdout.on('data', (data) => {
  console.log(`stdout: ${data}`)
  console.log(new Date(data))
})


// execFile 方法  执行某个可执行文件,支持同步和异步两种方式, 可以直接执行某个文件,而无需通过 shell 执行
// hello.js
#!/usr/bin/env node
const hello = 'hello world'
console.log(hello)
console.log(process.env)

// test.js
import { execFile, execFileSync } from 'child_process'

const file = './hello'
const execData = execFileSync(file)
console.log(execData.toString())

execFile(file, (error, stdout, stderr) => {
  if (error) {
    throw error
  }
  console.log(stdout)
  console.log(stderr)
})



//  fork() 方法创建一个子进程,并与子进程进行通信  专门用于在 Node.js 中衍生新的进程来执行 JavaScript 文件,并且建立一个与子进程的 IPC 通信管道。
// child.mjs
process.on('message', (msg) => {
  // 监听来自父进程的消息
  console.log(`Message from parent: ${msg}`)
  process.send('Hello from child!') // 向父进程发送消息
})


// form.mjs
import { fork } from 'child_process'

const child = fork('child.mjs') // 使用 fork() 方法创建子进程

child.on('message', (msg) => {
  // 监听来自子进程的消息
  console.log(`Message from child: ${msg}`)
})

child.send('Hello from parent!') // 向子进程发送消息

url模块

// url.parse 解析 URL 字符串,返回一个解析后的对象。
import url from 'url'

const testUrl = 'https://www.baidu.com?search=juejin'
console.log(url.parse(testUrl))


// url.URL 和全局的 URL 一样,创建一个 URL 实例,提供许多开箱即用的操作。
import url from 'url'

const testUrl = 'https://www.baidu.com?search=juejin'
console.log('url.URL === URL', url.URL === URL)
console.log(new URL(testUrl))

Timers

  • 定时器相关方法

setImmediate(() => console.log('setImmediate'))
setTimeout(() => console.log('setTimeout'), 0)
process.nextTick(() => console.log('nextTick'))
setInterval(() => console.log('setInterval'), 1000)

Readline模块

  • readline 模块提供了一个接口,用于从可读流 (例如 process.stdin) 读取数据,并支持逐行读取数据。
// 使用 question() 方法向用户询问姓名并显示
import readline from "readline";
const rl = readline.createInterface({
  input: process.stdin,
  outut: process.stdout,
});

rl.question('what is your name?', (name) => {
  console.log(`hello, ${name}`);
  rl.close();
})


// 使用 write() 方法向标准输出发送数据。
import readline from "readline";
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

rl.write('hello');
rl.close();



//  prompt  实现一个可多轮对话的命令行
const rl = readline.createInterface({
  input: process.stdin, // 从标准输入流中读取数据
  output: process.stdout // 输出数据到标准输出流中
})

rl.setPrompt('node> ') // 设置提示符
rl.prompt() // 显示提示符

rl.on('line', (line) => {
  // 监听行事件
  switch (
    line.trim() // 去除收尾空白字符,进行简单的命令选择判断
  ) {
    case 'hello':
      console.log('world') // 输出 'world'
      break
    case 'exit':
      rl.close() // 关闭 readline 接口
      break
    default:
      console.log(`Say what? I might have heard '${line.trim()}'`) // 输出收到的指令
      break
  }
  rl.prompt() // 显示提示符
})

rl.on('close', () => {
  // 监听关闭事件
  console.log('Goodbye!') // 输出 'Goodbye!'
  process.exit(0) // 退出 Node.js 进程
})

crypto模块

  • 主要用于加密和解密数据,内置了一些常用的算法, 哈希值生成,加解密,随机数生成。
// 生成具有给定大小的随机数据 (Buffer 类型)。
console.log(crypto.randomBytes(32).toString('hex'))
console.log(crypto.randomBytes(8).toString('hex'))


参考&感谢各路大神

node

posted @ 2024-07-16 22:47  安静的嘶吼  阅读(2)  评论(0编辑  收藏  举报