[笔记] 写了一个自己的自动部署cli

1,260 阅读3分钟

前面写了一个nodejs自动部署本地静态文件

贴一个传送门
使用node编写自动部署静态文件脚本

后面发现每创建一个项目都在cv过来有点low
于是就把他发布成了一个npm工具 可以直接在项目里安装使用

传送门 ( npm ) zy-auto-deploy
传送门 ( github ) zy-auto-deploy

在这里记录一下过程

创建一个项目

先创建一个文件夹 我的是zy-auto-deploy 已下都是在该目录下进行操作

    // 初始化你的项目 生成package.json
    npm init
    
    // 安装依赖 依赖的作用上篇说过就不在多嘴
    npm i chalk inquirer node-ssh ora shelljs zip-local -S
    
    // 创建src目录(为了规范)  里面添加index.js

注意

当你安装的依赖 使用 -S 也就是 --save 保存为项目的依赖的时候
别人在安装你的npm包时候才会自动安装你项目的依赖 不然是不会安装的

修改package.json文件

    "main": "./src/index.js", // 项目入口文件路径
    "bin": {
        "zy-dpl": "./src/index.js" // 可执行文件路径 用于注册你的脚本的命令 
    },

关键一步 标记可执行文件

现在在index.js第一行写入

    #!/usr/bin/env node // 说明此文件为node的可执行脚本文件

本地调试

在根目录执行 npm link
将会在你系统中注册你的bin字段设置的zy-dpl命令为全局命令 vue create-react-app 就是这么来的

测试

在index.js中 随便写点什么

console.log('执行了zy-dpl')

然后打开命令行工具 直接运行 zy-dpl

不出意外 就可以在命令行看到打印的执行了zy-dpl

现在对以前的代码进行一些调整

其他改动不大 就是一些多了一些参数获取和默认参数配置 和打包判定
下面是完整代码

#!/usr/bin/env node
const fs = require("fs");
const path = require("path");
const ora = require("ora");
const zipper = require("zip-local");
const shell = require("shelljs");
const chalk = require("chalk");
const CONFIG = require(path.resolve(process.cwd(), "./deploy.config.js"));
const inquirer = require("inquirer");
const NodeSSH = require("node-ssh").NodeSSH;
let SSH = new NodeSSH();
const errorLog = (error) => console.log(chalk.red(`---------------> ${error}`));
const defaultLog = (log) => console.log(chalk.blue(`---------------> ${log}`));
const successLog = (log) => console.log(chalk.green(`---------------> ${log}`));
// 文件夹位置
const distDir = path.resolve(process.cwd(), CONFIG.DIST||'./dist');
const distZipPath = path.resolve(process.cwd(), "./dist.zip");

// 打包 npm run build
const compileDist = async () => {
  // 进入本地文件夹
  shell.cd(path.resolve(process.cwd(), "./"));
  shell.exec(CONFIG.SCRIPT||'npm run build');
  successLog("编译完成");
};

// ********* 压缩dist 文件夹 *********
const zipDist = async () => {
  try {
    if (fs.existsSync(distZipPath)) {
      defaultLog("dist.zip已经存在, 即将删除压缩包");
      fs.unlinkSync(distZipPath);
    } else {
      defaultLog("即将开始压缩zip文件");
    }
    await zipper.sync.zip(distDir).compress().save(distZipPath);
    successLog("文件夹压缩成功");
  } catch (error) {
    errorLog(error);
    errorLog("压缩dist文件夹失败");
  }
};

// ********* 执行清空线上文件夹指令 *********
const runCommond = async (commond) => {
  const result = await SSH.exec(commond, [], { cwd: CONFIG.PATH });

  console.log(chalk.yellow(result));
};
const COMMONDS = CONFIG.COMMONDS || [];
// ********* 执行清空线上文件夹指令 *********
const runBeforeCommand = async () => {
  defaultLog("执行前置命令");
  for (let i = 0; i < COMMONDS.length; i++) {
    await runCommond(COMMONDS[i]);
  }
};

// ********* 通过ssh 上传文件到服务器 *********
const uploadZipBySSH = async () => {
  // 上传文件
  let spinner = ora("准备上传文件").start();
  try {
    await SSH.putFile(distZipPath, CONFIG.PATH + "/dist.zip");
    successLog("完成上传");
    spinner.text = "完成上传, 开始解压";
    await runCommond("unzip -o ./dist.zip");
    spinner.stop();
    successLog("部署完成");
    process.exit(0);
  } catch (error) {
    errorLog(error);
    errorLog("上传失败");
  }
  spinner.stop();
};

// ********* 连接ssh *********
const connectSSh = async () => {
  defaultLog(`尝试连接服务: ${CONFIG.SERVER_PATH}`);
  let spinner = ora("正在连接");
  spinner.start();
  try {
    spinner.stop();
    SSH.connect({
      host: CONFIG.SERVER_PATH,
      username: CONFIG.SSH_USER,
      password: CONFIG.SSH_KEY,
      port: CONFIG.PORT || 22,
    }).then(async () => {
      await runBeforeCommand();
      await uploadZipBySSH();
    });
    successLog("SSH 连接成功");
  } catch (error) {
    errorLog(error);
    errorLog("SSH 连接失败");
  }
};

async function runTask(hasBuild) {
  if (hasBuild) {
    await compileDist();
  }
  await zipDist();
  await connectSSh();
}

console.log(CONFIG);

// defaultLog('服务器配置检查')
inquirer
  .prompt([
    {
      type: "confirm",
      name: "hasBuild",
      message: "是否需要打包",
    },
  ])
  .then((answers) => {
    let hasBuild = answers.hasBuild
      ? true //需要打包直接打包
      : fs.existsSync(distZipPath) // 不需要打包 判断是否有dist.zip 没有的话重新打包
        ? false
        : true
    runTask(hasBuild);
  });

登陆npm 发布

登陆npm需要先注册
记得把镜像源切回npm 不然会出问题 可以使用nrm管理npm镜像源

// 登陆npm
npm login

// 根据提示输入账号密码

// 发布
npm publish

更新版本

更新版本只需修改package.json里面的版本号 重新npm publish就可以了

删除指定版本

执行 npm unpublish zy-auto-deploy@1.0.5 即可

删除包

执行npm unpublish --force //强制删除

解除本地测试生成的全局命令

执行npm unlink即可