nodejs制作一个文档同步工具,自动同步到gitee中


大家好,我是herry菌,现在是我们的分享时间,今天要分享的是,使用nodejs开发一个文档同步器,可以将本地的文件实时同步在git仓库中。 

初衷

之所以要做这个工具是为了让自己能随时用电脑时记录日常工作或生活。一般只需要简单记录下就行了。这样我在家里的和公司里的记录都能同步看到。

要说这种应用市面上有很多,像坚果云、有道云笔记、腾讯文档、语雀之类的都是。我为什么还是要自己实现一个呢。首先云笔记要记录时每次都要打开应用到指定页面去,而我比较喜欢使用nodepad来做记事,notepad打开很快,打开就是之前的记录位置,我可以快速把自己的想法记录上去,如果等待时间长个几秒,可能就会忘记一些东西。虽然坚果云可以同步文件,但是我公司的电脑屏蔽了这个软件联网,因此就只能自己搞个了。

这样后期整理的时候看到几个关键词就能想起来具体的事情,有的也可以为日后整理成文章做一个草稿,这样写文章才能有头有尾,否则想到什么说什么是非常不利于写出文章的。

一开始我使用手动同步的方式,但是发现很麻烦,之后就直接用了个批处理文件来一次性同步。

git pull
git add .
git commit -m '同步'
git push
git status
@echo off
pause

但是这样还是有几个缺点:

1.有时候会忘记执行同步,特别是下班的时候,直接关机的。

2.如果一开始忘记同步了,后面就会产生git冲突。体验不是太好。

接下来就是开始开发了

开发前,我们电脑上需要默认安装nodejsgit

因为后来抽时间写了个小程序。只要把程序运行在后台,每过一段时间就会自动将文档同步起来。

本地改过内容会自动同步到git仓库,git仓库内容被改后,又会自动拉取最新内容同步到本地,这样就能保证远程仓库和本地最新了,两台电脑直接的内容也就同步了。

我们来看下使用nodejs如何实现:

首先我们必须要有个git仓库用来存储数据。

gitee或github申请开个仓库就行。创建后得到远程仓库的地址,复制下来备用。

本地创建一个文件夹用于同步文档数据。

文件加中执行 npm init 创建package.json

npm init -y

之后是绑定远程仓库:

git init  #进行初始化仓库
git remote add origin [你的仓库地址] 
git push origin 
git push --set-upstream origin master  #首次同步仓库

这样之后就可以直接运行工具了。

新增文件index.js

在文件夹中安装3个依赖包

yarn add child_process
yarn add iconv-lite
yarn add moment

index.js中写入代码:

/**
 * git文件同步器
 * 需要先安装git工具
 */

const { exec } = require("child_process");
// const process = require('process');
const iconv = require("iconv-lite");
const moment = require("moment");
const fs = require("fs");

const encoding = "cp936"; //输出编码 就是gb2312 中文
const binaryEncoding = "binary"; //文件编码为二进制

/**
 * 执行一行cmd命令
 */
async function cmd(text) {
  return new Promise((resolve, reject) => {
    exec(
      text,
      { encoding: binaryEncoding },
      (err = "", stdout = "", stderr) => {
        if (err) {
          resolve("错误");
          return;
        }
        resolve(iconv.decode(Buffer.from(stdout, binaryEncoding), encoding));
      }
    );
  });
}

/**
 * 运行顺序 逻辑
 * git status 判断目录与仓库状态 not a git repository是未绑定远程仓库
 * 若已绑定仓库,可使用git pull进行拉取文件,将仓库文件同步到本地
 * 再使用git status判断本地是否有修改文件,如果修改了 可以使用git add 和 git commit 和 git push将本地文件同步到仓库
 */
async function run() {
  const time = moment().format("YYYY-MM-DD HH:mm:ss");
  let status = (await cmd(`git status`)) || "";
  if (
    status.includes(`not a git repository (or any of the parent directories)`)
  ) {
    //目录未绑定git地址
    console.log("目录未绑定git地址");
  } else {
    //已绑定git
    //拉取
    const pull = (await cmd(`git pull`)) || "";
    if (
      !pull.includes(`Already up to date`) &&
      !pull.includes(`Already up-to-date`)
    ) {
      //拉取下来了最新数据
      console.log(`拉取了最新数据。时间:${time}`);
    }
    //状态
    status = (await cmd(`git status`)) || "";
    if (status.includes(`(use "git add"`)) {
      //本地内容有改动 需要提交
      (await cmd(`git add .`)) || "";
      (await cmd(`git commit -m 同步`)) || "";
      (await cmd(`git push`)) || "";
      console.log(`同步成功。时间:${time}`);
    }
  }
}

/**
 * 初始化
 *
 * 判断.gitignore文件是否存在,若不存在则创建,若存在则看*.exe规则是否存在,若不存在则加入,若存在则什么都不做
 * 每15秒在后台运行一次检查和同步
 */
function init() {
  const ishave = fs.existsSync("./.gitignore");
  if (!ishave) {
    fs.writeFileSync("./.gitignore", "*.exe\n");
  } else {
    const content = fs.readFileSync("./.gitignore", "utf-8");
    const lines = content.split(/\r?\n/);
    if (!lines.includes("*.exe")) {
      fs.appendFileSync("./.gitignore", "\n*.exe\n");
    }
  }
  //运行同步 每15秒执行一次
  setInterval(() => {
    run();
  }, 1000 * 15);
  console.log("监听中,可切换至后台运行!");
  run();
}

init();

// console.log(__dirname, __filename)

这样我们使用node index就能做git同步了。 

但是这样还不行,这不是我们想要的结果,我们想要的是同步指定文件夹的文件,不是当前目录的文件。所以我们要将其打包成一个exe文件,放到需要同步的文件夹中,才能同步指定目录。

首先我们全局安装一个依赖:pkg

npm install -g pkg

然后在工具的目录中执行:

pkg -t win index.js

即可将该nodejs项目打包成独立的exe程序,然后将这个exe程序放在需要git同步的目录中。

另外,为了不把这个exe文件同步到仓库中,我们需要排除这个文件

所以要在同步的目录中放一个.gitignore文件,里面加上一行用于去除该exe文件

这个打包出来的文件:https://www.jianguoyun.com/p/DQGnvHQQ6KKRChjg8qIE

这个配置文件:https://www.jianguoyun.com/p/DbWJu0MQ6KKRChi486IE

为了能让电脑开机后能直接启动程序,我们将程序放入开机启动项

打开文件夹,然后粘贴这个路径到文件夹,回车

%USERPROFILE%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup

我们将这个文件的快捷方式放入到开机启动项中,这样开机就会执行同步了,实现一直同步。每30秒都会去检查下是否是最新的。