ssh2-sftp-client实现前端项目自动部署

121 阅读5分钟

ssh2-sftp-client实现前端项目自动部署

目录

[TOC]

自动部署完整代码

package.json

下载这三个包

  • shelljs :执行 shell命令
  • ssh2-sftp-client 与服务器建立链接(内部有ssh2)
  • chalk 打印彩色输出
  "devDependencies": {
    "shelljs": "^0.8.5",
    "ssh2-sftp-client": "^9.1.0",
    "chalk": "4.1.0"
  },

配置脚本命令  deploy 注意后边加上运行环境
执行deploy命令时内部执行了打包动作

  "scripts": {
    "dev": "vue-cli-service serve",
    "staging": "vue-cli-service serve --mode staging",
    "build:prod": "vue-cli-service build",
    "build:stage": "vue-cli-service build --mode staging",
    "preview": "node build/index.js --preview",
    "lint": "eslint --ext .js,.vue src",
    "deploy": "node deploy/index.js --prod"
  },

deploy /config   服务器信息

module.exports = [
  {
    id: 0,
    nodeEnv: "prod",
    name: "正式环境",
    domain: "",
    host: "ip",
    port: 端口,
    username: "用户名",
    password: "密码",
    path: "/data/www/paccount",//部署路径
    removepath: "/data/www/paccount", //删除路径
  },
];

deploy / index  部署命令入口文件

// 服务器配置文件
const config = require("./config.js");
// shell命令
const shell = require("shelljs");
// 输出颜色
const chalk = require("chalk");
// node fs 模块 读写文件
const fs = require("fs");
// node path模块 获取文件路径
const path = require("path");
// SSH2-SFTP-Client 是一个用于在Node.js中进行SSH SFTP操作的强大工具。它允许你建立SSH连接并进行文件传输,非常适用于自动化任务和远程文件管理。本文将引导你如何安装、配置和使用SSH2-SFTP-Client。
const Client = require("ssh2-sftp-client");
// 获取环境变量
const rawArgv = process.argv.slice(2);
// 日期插件
const dayjs = require("dayjs");
 
//判断环境
const filterStage = rawArgv.includes("--prod") ? "prod" : "stage";
console.log(chalk.blue("当前环境:", filterStage));
 
// 打包
const compileDist = async () => {
  // 根据环境执行打包命令
  if (shell.exec(`npm run build:${filterStage}`).code === 0) {
    console.log(chalk.green("打包成功"));
  }
};
// 部署
async function connectShell(params) {
  // 判断需要上传的服务器
  config
    .filter((item) => item.nodeEnv == filterStage)
    .map((item, index) => {
      const sftp = new Client();
      sftp
        .connect({
          host: item.host,
          port: item.port,
          username: item.username,
          password: item.password,
        })
        // 备份
        .then(() => {
          if (index > 0) {
            return "ok";
          }
          console.log(
            chalk.red(`${item.host}--`) + chalk.blue(`---执行下拉文件备份---`)
          );
          console.log(chalk.blue(`---创建备份文件夹中···---`));
          let newFile = `/${item.host}/${dayjs().format(
            "YYYY-MM-DD"
          )}/dist-${dayjs().format("HH_mm_ss")}`;
          // 创建本地文件夹
          fs.mkdir(
            path.resolve(__dirname, `../distbak${newFile}`),
            { recursive: true },
            (err) => {
              if (err) throw err;
              console.log(chalk.green("---创建备份文件夹成功---"));
            }
          );
          //执行服务器下拉操作
          return sftp.downloadDir(
            item.path, //服务器路径
            path.resolve(__dirname, `../distbak${newFile}`) //写入的本地路径地址
          );
        })
        // 删除
        .then(() => {
          if (index === 0) {
            console.log(
              chalk.red(`${item.host}--`) + chalk.blue(`---备份完成---`)
            );
          }
          console.log(
            chalk.yellow(`${item.host}--`) +
              chalk.red(`---执行删除文件中···---`)
          );
          // 删除路径 递归删除
          return sftp.rmdir(item.path, true);
        })
        // 上传
        .then(() => {
          console.log(
            chalk.red(`${item.host}--`) + chalk.green(`执行删除文件成功---`)
          );
          console.log(
            chalk.hex("#DEADED").bold(`---${item.host}执行上传文件中···---`)
          );
          return sftp.uploadDir(path.resolve(__dirname, "../dist"), item.path);
        })
        // 上传成功 关闭链接
        .then(() => {
          console.log(
            chalk.yellow(`${item.host}--`) + chalk.green(`上传完成,部署成功---`)
          );
          sftp.end();
        })
        // 上传失败
        .catch((err) => {
          console.error(
            err,
            chalk.red(`${item.host}--`) + chalk.red(`上传失败`)
          );
          sftp.end();
        });
    });
}
 
async function runStart() {
  await compileDist();
  await connectShell();
}
runStart();

如果需要在服务器执行命令

在部署完成后执行

SSH2是一个用于在网络上安全地访问远程计算机的协议,而上述代码段则使用Node.js的ssh2库来执行SSH连接和操作。这段代码中包含了两个事件处理器:

  1. .on("ready", function () { ... })
  • 这是ssh2库中的一个事件处理器,它在SSH连接准备就绪时触发。当与远程主机建立SSH连接后,会执行其中的代码块。通常,你可以在这个事件中执行需要在SSH连接建立后执行的操作。
  1. .connect({ ... })
  • 这是用于建立SSH连接的方法,其中包含了一个包含连接参数的对象,如主机地址、端口、用户名和密码等。在调用 .connect() 时,ssh2库将尝试连接到指定的远程主机。

在代码中,当SSH连接准备就绪("ready")时,它执行了一个命令,使用 conn.exec() 执行 chmod 命令,将目标目录的权限设置为755(允许读、写和执行)。如果设置权限成功,它会打印一条成功消息,并结束SSH连接。

总之,上述代码段通过ssh2库建立SSH连接,并在连接就绪后执行特定的命令来更改目标目录的权限。这通常用于在远程服务器上执行操作,例如修改文件权限。

const ClientOrg = require("ssh2").Client;
async function chmodDir(item) {
  if (!item) {
    throw "获取ip配置失败";
  }
 
  const conn = new ClientOrg();
  conn
    .on("ready", function () {
      conn.exec("chmod  755  /etc/nginx/html -R", function (err, stream) {
        if (err) throw err;
        console.log(
          chalk.red(`${item.host}--`) + chalk.green(`---添加目录权限成功---`),
        );
        conn.end();
      });
    })
    .connect({
      host: item.host,
      port: item.port,
      username: item.username,
      password: item.password,
    });
}

shelljs的使用说明

shelljs 模块重新包装了 child_process ,调用系统命令更加简单。
shelljsUnix ShellNode.js API 层的轻量级实现,可以支持 Windows、Linux、OS X 。你可以像在 Unix 命令行敲命令一样书写代码

shelljs 官网地址: www.npmjs.com/package/she…

shelljs的安装

shelljs 是第三方模块,需要安装后才能使用。

全局安装

$ npm install shelljs -g

本地安装

将当前工作目录切换为需要使用 shelljs 模块的目录(已经创建了 package.json 文件的目录)

$ npm install shelljs --save

shelljs的使用说明

对于熟悉 Unix Shell 脚本的开发者,简单扫一眼API就能愉快的开始写代码了。
先看个例子:

var shell = require('shelljs');
 
//判定git命令是否可用
if (!shell.which('git')) {
    //向命令行打印git命令不可用的提示信息
    shell.echo('Sorry, this script requires git');
    //退出当前进程
    shell.exit(1);
}
 
//先删除'out/Release'目录
shell.rm('-rf', 'out/Release');
//拷贝文件到'out/Release'目录
shell.cp('-R', 'stuff/', 'out/Release');
 
//切换当前工作目录到'lib'
shell.cd('lib');
//shell.ls('*.js')返回值是一个包含所有js文件路径的数组
shell.ls('*.js').forEach(function(file) {//遍历数组
    //sed命令用于文件内容的替换,这里是对每个文件都执行如下3步操作,更改版本信息
    shell.sed('-i', 'BUILD_VERSION', 'v0.1.2', file);
    shell.sed('-i', /^.*REMOVE_THIS_LINE.*$/, '', file);
    shell.sed('-i', /.*REPLACE_LINE_WITH_MACRO.*\n/, shell.cat('macro.js'), file);
});
//切换当前工作目录到上一层
shell.cd('..');
 
//同步执行git命令提交代码
if (shell.exec('git commit -am "Auto-commit"').code !== 0) {
    shell.echo('Error: Git commit failed');
    shell.exit(1);
}

上面的例子展示了一个可发布版本提交到 git 仓库的过程。

shelljs 的方法都遵循:
方法名 就是我们常用的执行命令,而方法参数就是命令行参数。只是有些方法对命令行参数做了变形和拓展。

重要方法介绍

exec()
  • exec(command [, options] [, callback])
    • command <String> :要在命令行执行的完整命令
    • options <Object> :可选参数,JSON对象
      • async: 异步执行.如果你提供了回调方法,这个值就一定为true,无论你怎么设置

      • silent:打印信息不输出到命令控制台

      • Node.js 的 child_process.exec() 方法的其他参数都可以用

    • callback:<Function> :当进程终止时调用,并带上输出。
      • error <Error>

      • stdout <String> | <Buffer>

      • stderr <String> | <Buffer>

    • 返回值: 同步模式下,将返回一个ShellString(shelljs v0.6.xf返回一个形如{ code:..., stdout:... , stderr:... }的对象);异步模式下,将返回一个child_process的对象

Note:
由于 exec() 现在同步方法的实现占用了大量 CPU ,所以,官方建议使用异步模式运行一个需要长时间保活的进程。

例子:

var version = exec('node --version', {silent:true}).stdout;
 
var child = exec('some_long_running_process', {async:true});
child.stdout.on('data', function(data) {
  /* ... do something with data ... */
});
 
exec('some_long_running_process', function(code, stdout, stderr) {
  console.log('Exit code:', code);
  console.log('Program output:', stdout);
  console.log('Program stderr:', stderr);
});
ls()
  • ls([options,] path_array)

  • options <String> :可选参数,可以多个参数叠加使用,比如-lA

    • -R : 递归处理,将指定目录下的所有文件及子目录一并处理

    • -A : 显示除影藏文件“.”和“..”以外的所有文件列表

    • -L : 如果遇到性质为符号链接的文件或目录,直接列出该链接所指向的原始文件或目录

    • -d : 仅显示目录名,而不显示目录下的内容列表。显示符号链接文件本身,而不显示其所指向的目录列表

    • -l : 以长格式显示目录下的内容列表。输出的信息从左到右依次包括文件名,文件类型、权限模式、硬连接数、所有者、组、文件大小和文件的最后修改时间等

  • path_array <Array> :可选参数,目标目录的组成的数组,ls命令依次处理各个目录

  • ls([options,] [path, ...])

  • options <String> :可选参数,与 ls([options,] path_array) 方法的参数一样

  • [path, ...] :可选参数,目标目录序列,以多参数的形式存在,
    比如:ls ( path1, path2 , ... , pathN);

ls方法返回一个包含给定的目标目录下的所有文件或目录路径集合的数组,如果没有给定路径,则默认为当前路径。如果设置了上面的提到的参数,则按照给定参数逐条将结果保存在数组中。

例子:

ls('projs/*.js');//
ls('-R', '/users/me', '/tmp');//递归遍历'/users/me'和'/tmp'
ls('-R', ['/users/me', '/tmp']); // 和上面一条一样
ls('-l', 'file.txt'); //[ { name: 'file.txt', mode: 33188, nlink: 1, ...} ]
ShellString()
  • ShellString(str)
    • str <String> :常规字符串

ShellString() 方法用于将常规字符串转换为 ShellString 。这样,就可以使用 ShellString 的方法 to()toEnd()

ShellString.prototype.to (file)

类似 Unix 命令中的 重定向操作> ,即把 ShellString 的内容覆盖写入参数指定的 file
例子:

//将input.txt的内容写入outpu.txt
cat('input.txt').to('output.txt');
ShellString.prototype.toEnd(file)

类似 Unix 命令中的 重定向并附加操作>> ,即把 ShellString 的内容写到指定文件的末尾。
例子:

//将input.txt的内容附加outpu.txt的末尾
cat('input.txt').to('output.txt');

SSH2-SFTP-Client 使用文档

SSH2-SFTP-Client 是一个用于在Node.js中进行SSH SFTP操作的强大工具。它允许你建立SSH连接并进行文件传输,非常适用于自动化任务和远程文件管理。本文将引导你如何安装、配置和使用SSH2-SFTP-Client。

安装

首先,确保你已经安装了Node.js。然后,可以使用npm来安装SSH2-SFTP-Client。

npm install ssh2-sftp-client

使用方法

接下来,让我们看一下如何使用SSH2-SFTP-Client执行常见的SFTP操作。

new SftpClient(name) ===> SFTP client object

构造函数来创建一个新的ssh2-sftp客户端对象。可以提供一个可选的名称字符串,该字符串将用于错误消息中,以帮助识别引发错误的客户端。

构造函数参数

name:字符串。错误消息中使用的可选名称字符串

示例使用

'use strict';
 
const Client = require('ssh2-sftp-client');
 
const config = {
  host: 'example.com',
  username: 'donald',
  password: 'my-secret'
};
 
const sftp = new Client('example-client');
 
sftp.connect(config)
  .then(() => {
    return sftp.cwd();
  })
  .then(p => {
    console.log(`Remote working directory is ${p}`);
    return sftp.end();
  })
  .catch(err => {
    console.log(`Error: ${err.message}`); // error message will include 'example-client'
  });

确保替换 'host''username''password' 为实际的SSH服务器信息。

connect(config) ===> SFTP object

连接到sftp服务器。此处提供了有关连接选项的完整文档

连接选项

该模块基于优秀的SSH2模块。该模块是一个通用的SSH2客户端和服务器库,提供的功能远不止SFTP连接。该模块提供的许多连接选项与SFTP连接不太相关。建议您将配置选项保持在所需的最小值,并坚持使用下面commonOpts中列出的选项。

retries、retry_factor和retry_minTimeout选项不属于SSH2模块。这些是重试包配置的一部分,用于启用sftp连接尝试的重试。有关这些值的解释,请参阅该软件包的文档。

// common options
 
let commonOpts {
  host: 'localhost', // string服务器的主机名或IP。
  port: 22, // 服务器的端口号。
  forceIPv4: false, // boolean (optional) 仅通过IPv4地址连接
  forceIPv6: false, // boolean (optional) 仅通过IPv6地址连接
  username: 'donald', //string身份验证用户名.
  password: 'borsch', // string基于密码的用户身份验证的密码
  agent: process.env.SSH_AGENT, // string-ssh代理的UNIX套接字的路径
  privateKey: fs.readFileSync('/path/to/key'), //包含的缓冲区或字符串
  passphrase: 'a pass phrase', // string-用于加密的私钥
  readyTimeout: 20000, // integer等待SSH握手的时间(以毫秒为单位)
  strictVendor: true, // boolean-执行严格的服务器供应商检查
  debug: myDebug,function-将其设置为接收单个,用于获取详细(本地)调试信息的字符串参数。
  retries: 2, // 整数重试连接的次数
  retry_factor: 2, //整数用于计算重试间隔时间的时间因子
  retry_minTimeout: 2000, // 整数尝试之间的最小超时
};
 
 
//很少使用的选项
 
let advancedOpts {
  localAddress,
  localPort,
  hostHash,
  hostVerifier,
  agentForward,
  localHostname,
  localUsername,
  tryKeyboard,
  authHandler,
  keepaliveInterval,
  keepaliveCountMax,
  sock,
  algorithms,
  compress
};

示例使用

sftp.connect({
  host: 'example.com',
  port: 22,
  username: 'donald',
  password: 'youarefired'
});
downloadDir(srcDir, dstDir, options) ==> string

将srcDir指定的远程目录下载到dstDir指定本地文件系统目录。如果需要,将创建dstDir目录。srcDir中的所有子目录也将被复制。本地路径中的任何现有文件都将被覆盖。本地路径中的任何文件都不会被删除。

该方法还发出下载事件,以提供监视下载进度的方法。下载事件侦听器是用一个参数调用的,该参数是一个具有两个属性(源和目标)的对象。source属性是已下载的远程文件的路径,destination是文件下载到的本地路径。您可以使用on()方法为此事件添加侦听器。

options参数是一个options对象,具有两个受支持的属性filter和useFastget。filter参数是一个谓词函数,对于要下载的每个潜在项,它将使用两个参数进行调用。第一个参数是项的完整路径

'use strict';
 
 
//使用uploadDir()方法上载目录的示例
//到远程SFTP服务器
 
 
const path = require('path');
const SftpClient = require('../src/index');
 
const dotenvPath = path.join(__dirname, '..', '.env');
require('dotenv').config({path: dotenvPath});
 
const config = {
  host: process.env.SFTP_SERVER,
  username: process.env.SFTP_USER,
  password: process.env.SFTP_PASSWORD,
  port: process.env.SFTP_PORT || 22
};
 
async function main() {
  const client = new SftpClient('upload-test');
  const src = path.join(__dirname, '..', 'test', 'testData', 'upload-src');
  const dst = '/home/tim/upload-test';
 
  try {
    await client.connect(config);
    client.on('upload', info => {
      console.log(`Listener: Uploaded ${info.source}`);
    });
    let rslt = await client.uploadDir(src, dst);
    return rslt;
  } catch (err) {
    console.error(err);
  } finally {
    client.end();
  }
}
 
main()
  .then(msg => {
    console.log(msg);
  })
  .catch(err => {
    console.log(`main error: ${err.message}`);
  });
rmdir(path, recursive) ==> string

删除目录。如果删除目录和递归标志设置为true,则指定的目录以及所有子目录和文件都将被删除。如果设置为false,并且目录包含子目录或文件,则操作将失败。

路径:字符串。远程目录的路径

递归:布尔值。如果为true,请删除目标目录中的所有文件和目录。默认为false

注意:至少有一份报告称,即使递归标志没有设置为true,一些SFTP服务器也会允许删除非空目录。虽然这不是标准行为,但如果计划依靠递归标志来防止删除非空目录,建议用户验证rmdir的行为。

例子

let remoteDir = '/path/to/remote/dir';
let client = new Client();
 
client.connect(config)
  .then(() => {
    return client.rmdir(remoteDir, true);
  })
  .then(() => {
    return client.end();
  })
  .catch(err => {
    console.error(err.message);
  });
uploadDir(srcDir, dstDir, options) ==> string

将srcDir指定的目录上载到dstDir所指定的远程目录。如有必要,将创建dstDir。srcDir中的任何子目录也将被上传。远程路径中的任何现有文件都将被覆盖。

上传过程还会发出“上传”事件。每个成功上传的文件都会触发这些事件。上载事件调用具有1个参数的侦听器,该参数是一个具有source和destination属性的对象。源属性是上载的文件的路径,目标属性是上载文件的路径。此事件的目的是为客户端代码提供某种方式来获得有关上载进度的反馈。您可以使用on()方法添加自己的侦听器。

第三个参数是一个选项对象,它有两个受支持的属性,filter和useFastput。

过滤器选项是一个函数,它将为每个要上传的项目调用。该函数将使用两个参数进行调用。第一个参数是完整路径

例子

'use strict';
 
// Example of using the uploadDir() method to upload a directory
// to a remote SFTP server
 
const path = require('path');
const SftpClient = require('../src/index');
 
const dotenvPath = path.join(__dirname, '..', '.env');
require('dotenv').config({path: dotenvPath});
 
const config = {
  host: process.env.SFTP_SERVER,
  username: process.env.SFTP_USER,
  password: process.env.SFTP_PASSWORD,
  port: process.env.SFTP_PORT || 22
};
 
async function main() {
  const client = new SftpClient('upload-test');
  const src = path.join(__dirname, '..', 'test', 'testData', 'upload-src');
  const dst = '/home/tim/upload-test';
 
  try {
    await client.connect(config);
    client.on('upload', info => {
      console.log(`Listener: Uploaded ${info.source}`);
    });
    let rslt = await client.uploadDir(src, dst);
    return rslt;
  } catch (err) {
    console.error(err);
  } finally {
    client.end();
  }
}
 
main()
  .then(msg => {
    console.log(msg);
  })
  .catch(err => {
    console.log(`main error: ${err.message}`);
  });

node js --- fs模块

fs全称为file system模块是Node.js中的核心模块之一,用于对文件系统进行操作。它提供了丰富的函数和方法,可以进行文件的读取、写入、复制、删除等操作,同时也支持目录的创建、遍历和修改等操作。使用fs模块,你可以在Node.js环境中轻松地与文件系统交互。

.mkdir 创建文件夹

在 Node.js 中,我们可以使用 mkdir 或 mkdirSync 来创建文件夹
语法:

fs.mkdir(path[, options], callback)
fs.mkdirSync(path[, options])

参数说明:

  • path 文件夹路径
  • options 选项配置( 可选 )
  • callback 操作后的回调

示例代码:

//异步创建文件夹
fs.mkdir('./page', err => {
	if(err) throw err;
	console.log('创建成功');
});
//递归异步创建
fs.mkdir('./1/2/3', {recursive: true}, err => {
	if(err) throw err;
	console.log('递归创建成功');
});
//递归同步创建文件夹
fs.mkdirSync('./x/y/z', {recursive: true});

__dirname

__dirnamerequire类似,都是 Node.js 环境中的’全局’变量
__dirname保存着当前文件所在目录的绝对路径,可以使用 __dirname 与文件名拼接成绝对路径

代码示例:

let data = fs.readFileSync(__dirname + '/data.txt');
console.log(data);

使用 fs 模块的时候,尽量使用 __dirname 将路径转化为绝对路径,这样可以避免相对路径产生的Bug

path.resolve()用法

path 模块是 Node.js 官方提供的、用来处理路径的模块。它提供了一系列的方法和属性,用来满足用户对路径的处理需求。

1、不带参数时
path.resolve()返回的是当前的文件的绝对路径/Users/xxxx/
2、带不是/开头的参数
path.resolve('a') 返回的是当前绝对路径拼接现在的参数/Users/xxxx/a
path.resolve('a','b') 返回的是当前绝对路径拼接现在的参数/Users/xxxx/a/b
3、带./开头的参数
path.resolve('./a') 返回的是当前绝对路径拼接现在的参数/Users/xxxx/a
path.resolve('./a','./b') 返回的是当前绝对路径拼接现在的参数/Users/xxxx/a/b
4、带/开头的参数 返回的是 /+‘最后一个前面加/的文件文件名’+‘剩下文件夹
path.resolve('/a') 返回的是当前绝对路径拼接现在的参数/a
path.resolve('/a','/b') 返回的是当前绝对路径拼接现在的参数/b
path.resolve('/a','/b', 'c') 返回的是当前绝对路径拼接现在的参数/b/c

1.console.log(path.resolve());  //E:\nodejs
2.console.log(path.resolve(''));  //E:\nodejs
3.console.log(path.resolve('.'));  //E:\nodejs
4.console.log(path.resolve(__dirname));  //E:\nodejs
5.console.log(path.resolve('js/common','test'));  //E:\nodejs\js\common\test
6.console.log(path.resolve('./js/common','test'));  //E:\nodejs\js\common\test
7.console.log(path.resolve('js/common','./test'));  //E:\nodejs\js\common\test
8.console.log(path.resolve('./js/common','./test'));  //E:\nodejs\js\common\test
9.console.log(path.resolve('/js/common','test'));  //E:\js\common\test
10.console.log(path.resolve('js/common','/test'));  //E:\test
11.console.log(path.resolve('/js/common','/test'));  //E:\test
12.console.log(path.resolve('/js/common','../test'));  //E:\js\test
13.console.log(path.resolve('js/common','../test'));  //E:\nodejs\js\test

process

当我们谈论Node.js的应用程序时,通常需要处理命令行参数和访问进程信息。Node.js提供了两个强大的工具,即 process.argvprocess 对象,用于实现这些功能。在本文中,我们将深入探讨它们的用途和如何使用它们。

1. 了解process.argv

process.argv 是Node.js中一个重要的全局对象,它包含了命令行参数的信息。当您在终端中执行Node.js应用程序时,您可以在命令行中传递参数,例如:

node myApp.js arg1 arg2 arg3

在这个例子中, arg1arg2arg3 就是命令行参数。 process.argv 用于捕获这些参数,并它是一个包含以下元素的数组:

  • process.argv[0] :Node.js的执行路径
  • process.argv[1] :当前执行的JavaScript文件的路径
  • process.argv[2] 以及之后的元素:命令行参数

以下是一个示例,展示如何使用 process.argv 来获取命令行参数:

// myApp.js
console.log(process.argv); // 打印完整的命令行参数数组
 
// 获取特定参数
const arg1 = process.argv[2];
const arg2 = process.argv[3];
 
console.log(`arg1: ${arg1}`);
console.log(`arg2: ${arg2}`);

2. process对象的用途

process 对象是Node.js中的另一个全局对象,它提供了关于当前Node.js进程的信息。它包含了各种属性和方法,让您可以监视和控制应用程序的执行。以下是一些常见的用途:

  • Exit事件监听 :通过 process.on('exit', callback) ,您可以在应用程序即将退出时执行自定义操作。

  • 信号处理 :您可以使用 process.on('SIGINT', callback) 等方法来处理操作系统发出的信号,如Ctrl+C。

  • 环境变量process.env 包含了所有的环境变量,您可以在其中查找应用程序所需的配置信息。

  • 标准输入/输出process.stdin 用于处理标准输入, process.stdoutprocess.stderr 用于处理标准输出和错误输出。

以下是一个示例,展示如何监听 exit 事件和处理信号:

process.on('exit', (code) => {
  console.log(`应用程序即将退出,退出码:${code}`);
});
 
process.on('SIGINT', () => {
  console.log('接收到 SIGINT 信号,应用程序即将退出。');
  process.exit(0);
});

3. 结论

process.argvprocess 对象是Node.js中不可或缺的工具,用于处理命令行参数和控制应用程序的行为。了解如何使用它们可以让您更好地管理和监控Node.js应用程序的执行过程。希望这篇文章能帮助您更好地理解它们的用途和功能。

chalk开源库

前言

前段时间看别人分析vuecli的基础配置时,看到了这个第三方库,感觉很好玩,正好自己也在学习node基础,于是自己赶紧玩一下。玩的路上凑巧碰到了它的两个小兄弟,顺路一起玩一下。

chalk作用与使用

这个chalk的源码可以去github上自己看,官网上还有示例,使用起来很简单。

作用:在浏览器控制台或终端中修改打印的字符串样式,如字体样式,字体颜色等
缺点:好像不支持渐变色,只有单色
安装: npm install chalk

在项目中引入使用如下所示,使用方式很多,可去官网查看示例。

console.log(chalk.blue('Hello world!'));  // 打印出的字体为蓝色
console.log(chalk.red('Hello') + ' World' + chalk.red('!')); // 还支持拼接
console.log(chalk.pink.bgRed.bold('Hello world!')); // 支持链式调用,字体变色、加粗、背景色

chalk在node中使用的版本坑

我是在node项目中与前端项目中都玩了下这个库,首先在node项目中直接npm install chalk后,使用require方法导入使用发现报错:

去官网查看发现从chalk从5.0+版本开始,只支持ESModule格式,chalk是使用export default导出的,chalk之前的版本支持CommomJs格式,chalk是使用module.exports导出的。我直接安装默认是5.0.1最新版,require引入所以报错。

于是我将chalk版本换为4.x版本,npm install chalk@4.x 发现可以正常使用,效果如下:

chalk在node中使用场景

可在终端输出不同值时使用不同颜色的字体,有一个醒目的效果,比如终端打印错误时使用红色字体等。自己也可以封装小函数,按情况返回不同颜色的字体。

const chalk = require('chalk');
const hint = (...info) => {
  console.log(chalk.blue(info));
}
const error = (...info) => {
  console.log(chalk.red(info));
}