代码地址:https://github.com/wukang0718/nodeServerUploadMarkdownFile
思路
- 监听本地文件的修改
- 上传到github
- 设置脚本开机自启动
实现
新创建一个项目,执行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单独设置用户名和邮箱,不明白为什么?
- 有时候会出现第一次安装没有运行启动脚本,卸载再安装就可以了,不明白为什么?