nodejs监听本地文件的修改,自动上传到github

1,320 阅读3分钟

代码地址:https://github.com/wukang0718/nodeServerUploadMarkdownFile

思路

  1. 监听本地文件的修改
  2. 上传到github
  3. 设置脚本开机自启动

实现

新创建一个项目,执行npm init一直回车

在项目中创建一个config.json文件,存放github相关配置信息

{
    "dirPath": "D:/dir/markdown文件",  // 要监听的本地文件目录
    "commitMessage": "使用nodejs自动提交的文件",   // 提交到github的message
    "repo": "<github.name>/<项目名称>", // github仓库地址
    "branch": "master", // 分支
    "remote": "origin" // 仓库
}

使用的模块

日志处理

​ 使用log4js模块

  • 安装
npm install log4js --save
  • 使用

在项目目录中创建log.js

const log4js = require('log4js');

log4js.configure({
    appenders: {
        file: {
            type: 'DateFile', // 文件以日期命名
            filename: 'logs/app', // 文件存放目录
            pattern: '-yyyy-MM-dd.log', // 文件名称格式
            alwaysIncludePattern: true
        }
    },
    categories: {
        default: {
            appenders: ['file'],
            level: 'debug'
        }
    }
})

module.exports = log4js.getLogger()

上传到github

​ 使用simple-git模块

  • 安装
npm install simple-git --save
  • 使用

在项目下创建git-cmd.js的文件 在这个文件定义同步和提交 git 的方法

提交到 git 之前,要先和 git 仓库做一次同步,如果是监听文件修改要上传到 github ,设置延迟3秒保存,防止快速保存,造成多次同步

const git = require('simple-git');
const { dirPath, branch, commitMessage, remote } = require("./config.json");
const logger = require('./log');

/**
 * 初始化git
 */
let gitEntity = git(dirPath)

/**
 * git提交,要先更新在提交
 */
function gitPush() {
    gitPull().then(() => {
        logger.info("开始提交到github");
        gitEntity
            .add('./*')
            .commit(commitMessage)
            .push([remote, branch])
            .then(() => {
                logger.info(`Push to ${branch} success`);
            })
            .catch(err => {
                logger.error(`Push to ${branch} error`);
                logger.error(err);
            })

    })
}

/**
 * git更新
 */
function gitPull() {
    logger.info("开始从github更新");
    return gitEntity
        .pull(remote, branch)
        .then(() => {
            logger.info(`Pull to ${branch} success`);
        })
        .catch(err => {
            logger.error(`Pull to ${branch} error`);
            logger.error(err);
        });
}

/**
 * 延时执行函数, 延迟3秒
 */
const delayMethod = function(type) {
    let timer;
    return function() {
        clearTimeout(timer);
        timer = setTimeout(function() {
            gitCmd[type]();
            clearTimeout(timer);
        }, 3000)
    }
};

const gitCmd = {
    push: gitPush,
    pull: gitPull,
    delayInvoke: {
        push: delayMethod("push"),
        pull: delayMethod("pull")
    }
}


module.exports = function(type, immediately) {
    if (immediately) {
        return gitCmd[type]();
    } else {
        gitCmd.delayInvoke[type]();
    }
}

监听文件

​ 使用chokidar模块

  • 安装
npm install chokidar --save
  • 使用

在项目下新建watchFile.js文件

const chokidar = require('chokidar');
const invokeGit = require("./git-cmd");

/**
 * 监听文件夹
 * @param {*} dir 
 */

module.exports = function(dirPath) {
    chokidar.watch(dirPath, {
        ignored: /(\.git)|(\.idea)|(\.vscode)/
    }).on("all", ((event, path) => {
        // 文件修改同步到github仓库
        invokeGit("push")
    }))
}

启动项目

再项目目录中创建app.js文件

项目启动后和 github 先做一次同步,然后监听文件状态,执行同步方法

const invokeGit = require("./git-cmd");
const logger = require("./log");
const watch = require("./watchFile");
const { dirPath } = require("./config.json");

logger.info('服务启动成功');

// 程序加载 ---- 更新文件
invokeGit("pull", true).then(() => {
    watch(dirPath);
    logger.info("监听文件");
});

设置开机自启动

使用node-windows模块

  • 安装
npm install node-windows --save
  • 使用

再项目中创建server.js文件

const logger = require("./log");
const path = require("path");
const Service = require("node-windows").Service;

const svc = new Service({
    name: "nodejsUploadMarkdownToGithub",
    description: "nodejs脚本自动上传文件到github",
    script: path.resolve(__dirname, "app.js"),
    wait: 1,
    grow: 0.25,
    maxRestarts: 40
});

svc.on("install", () => {
    logger.info("自启动程序安装成功");
    svc.start();
})

svc.on("uninstall", () => {
    logger.info("自启动程序卸载成功");
})

svc.on("alreadyinstalled ", () => {
    logger.warn("程序已经启动");
})

svc.on("error", (err) => {
    logger.error("自启动服务异常" + err);
})

svc.on("start", () => {
    logger.info("自启动脚本,启动服务");
})

const args = process.argv.slice(2);
if (args[0] === "uninstall") {
    svc.uninstall();
} else {
    svc.install();
}

再package.json中配置启动命令

{
    "scripts": {
        "start": "node server.js", // 启动服务
        "uninstall": "node server.js uninstall" // 卸载服务
     }
}

注意事项

  • 要修改repo的remote
git remote set-url remote-name https://<username>:<password>@github.com/<username>/<repo_name>.git
  • 为repo设置用户名和邮箱
git config  user.email "xxxx@xx.com"
git config  user.name "xxxx"

启动服务

npm start

遗留问题

  • 一定要设置repo的remote 和 为repo单独设置用户名和邮箱,不明白为什么?
  • 有时候会出现第一次安装没有运行启动脚本,卸载再安装就可以了,不明白为什么?