暖男排狗后面 發表於 2021-12-23 22:27:00

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

<p>大家好,我是herry菌,现在是我们的分享时间,今天要分享的是,使用nodejs开发一个文档同步器,可以将本地的文件实时同步在git仓库中。&nbsp;</p>
<h3>初衷</h3>
<p>之所以要做这个工具是为了让自己能随时用电脑时记录日常工作或生活。一般只需要简单记录下就行了。这样我在家里的和公司里的记录都能同步看到。</p>
<p>要说这种应用市面上有很多,像<span style="background-color: rgba(255, 255, 0, 1)">坚果云、有道云笔记、腾讯文档、语雀</span>之类的都是。我为什么还是要自己实现一个呢。首先云笔记要记录时每次都要打开应用到指定页面去,而我比较喜欢使用nodepad来做记事,notepad打开很快,打开就是之前的记录位置,我可以快速把自己的想法记录上去,如果等待时间长个几秒,可能就会忘记一些东西。虽然坚果云可以同步文件,但是我公司的电脑屏蔽了这个软件联网,因此就只能自己搞个了。</p>
<p>这样后期整理的时候看到几个关键词就能想起来具体的事情,有的也可以为日后整理成文章做一个草稿,这样写文章才能有头有尾,否则想到什么说什么是非常不利于写出文章的。</p>
<p>一开始我使用手动同步的方式,但是发现很麻烦,之后就直接用了个批处理文件来一次性同步。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">git pull
git add .
git commit </span>-m <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">同步</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">
git push
git status
@echo off
pause</span></pre>
</div>
<p>但是这样还是有几个缺点:</p>
<p>1.有时候会忘记执行同步,特别是下班的时候,直接关机的。</p>
<p>2.如果一开始忘记同步了,后面就会产生git冲突。体验不是太好。</p>
<p>&nbsp;</p>
<h3>接下来就是开始开发了</h3>
<p>开发前,我们电脑上需要默认安装<span style="background-color: rgba(255, 204, 0, 1)">nodejs</span>和<span style="background-color: rgba(255, 204, 0, 1)">git</span>。</p>
<p>&nbsp;</p>
<p>因为后来抽时间写了个小程序。只要把程序运行在后台,每过一段时间就会自动将文档同步起来。</p>
<p>本地改过内容会自动同步到git仓库,git仓库内容被改后,又会自动拉取最新内容同步到本地,这样就能保证远程仓库和本地最新了,两台电脑直接的内容也就同步了。</p>
<p>&nbsp;</p>
<p>我们来看下使用nodejs如何实现:</p>
<p>首先我们必须要有个git仓库用来存储数据。</p>
<p>去<span style="color: rgba(255, 0, 255, 1); background-color: rgba(255, 204, 0, 1)">gitee或github</span>申请开个仓库就行。创建后得到远程仓库的地址,复制下来备用。</p>
<p><img src="https://img2020.cnblogs.com/blog/883015/202112/883015-20211223184706727-771603177.png" alt="" width="303" height="240" loading="lazy"></p>
<p>&nbsp;</p>
<p>本地创建一个文件夹用于同步文档数据。</p>
<p>文件加中执行&nbsp;<span style="background-color: rgba(255, 255, 0, 1)">npm init</span>&nbsp;创建package.json</p>
<div class="cnblogs_code">
<pre>npm init -y</pre>
</div>
<p>&nbsp;</p>
<p>之后是绑定远程仓库:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">git init#进行初始化仓库
git remote add origin [你的仓库地址]
git push origin
git push </span>--<span style="color: rgba(0, 0, 255, 1)">set</span>-upstream origin master#首次同步仓库</pre>
</div>
<p>这样之后就可以直接运行工具了。</p>
<p>&nbsp;</p>
<p>新增文件<span style="background-color: rgba(255, 204, 0, 1)">index.js</span></p>
<p>在文件夹中安装3个依赖包</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">yarn add child_process
yarn add iconv</span>-<span style="color: rgba(0, 0, 0, 1)">lite
yarn add moment</span></pre>
</div>
<p>&nbsp;</p>
<p><span style="background-color: rgba(255, 204, 0, 1)">index.js</span>中写入代码:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
* git文件同步器
* 需要先安装git工具
</span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">

const { exec } </span>= require("child_process"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> const process = require('process');</span>
const iconv = require("iconv-lite"<span style="color: rgba(0, 0, 0, 1)">);
const moment </span>= require("moment"<span style="color: rgba(0, 0, 0, 1)">);
const fs </span>= require("fs"<span style="color: rgba(0, 0, 0, 1)">);

const encoding </span>= "cp936"; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">输出编码 就是gb2312 中文</span>
const binaryEncoding = "binary"; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">文件编码为二进制</span>

<span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
* 执行一行cmd命令
</span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">
async </span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> cmd(text) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">new</span> Promise((resolve, reject) =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
    exec(
      text,
      { encoding: binaryEncoding },
      (err </span>= "", stdout = "", stderr) =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      </span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (err) {
          resolve(</span>"错误"<span style="color: rgba(0, 0, 0, 1)">);
          </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)">;
      }
      resolve(iconv.decode(Buffer.from(stdout, binaryEncoding), encoding));
      }
    );
});
}

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

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

init();

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> console.log(__dirname, __filename)</span></pre>
</div>
<p>&nbsp;</p>
<p>这样我们使用<span style="background-color: rgba(255, 255, 0, 1)">node index</span>就能做git同步了。&nbsp;</p>
<p>&nbsp;</p>
<p>但是这样还不行,这不是我们想要的结果,我们想要的是同步指定文件夹的文件,不是当前目录的文件。所以我们要将其打包成一个exe文件,放到需要同步的文件夹中,才能同步指定目录。</p>
<p>首先我们全局安装一个依赖:<span style="background-color: rgba(255, 204, 0, 1)">pkg</span></p>
<div class="cnblogs_code">
<pre>npm install -g pkg</pre>
</div>
<p>然后在工具的目录中执行:</p>
<div class="cnblogs_code">
<pre>pkg -t win index.js</pre>
</div>
<p>即可将该nodejs项目打包成独立的<span style="background-color: rgba(255, 204, 0, 1)">exe</span>程序,然后将这个exe程序放在需要git同步的目录中。</p>
<p>&nbsp;</p>
<p>另外,为了不把这个exe文件同步到仓库中,我们需要排除这个文件</p>
<p>所以要在同步的目录中放一个<span style="background-color: rgba(255, 204, 0, 1)">.gitignore</span>文件,里面加上一行用于去除该exe文件</p>
<p><img src="https://img2020.cnblogs.com/blog/883015/202112/883015-20211223222217816-1514680555.png" alt="" loading="lazy"></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>这个打包出来的文件:https://www.jianguoyun.com/p/DQGnvHQQ6KKRChjg8qIE</p>
<p>这个配置文件:https://www.jianguoyun.com/p/DbWJu0MQ6KKRChi486IE</p>
<p>&nbsp;</p>
<h3>为了能让电脑开机后能直接启动程序,我们将程序放入开机启动项</h3>
<p>打开文件夹,然后粘贴这个路径到文件夹,回车</p>
<div class="cnblogs_code">
<pre>%USERPROFILE%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup</pre>
</div>
<p>我们将这个文件的快捷方式放入到开机启动项中,这样开机就会执行同步了,实现一直同步。每30秒都会去检查下是否是最新的。</p>
<p><img src="https://img2020.cnblogs.com/blog/883015/202112/883015-20211223233324227-1781001452.png" alt="" width="667" height="164" loading="lazy"></p>
<p>&nbsp;</p>

</div>
<div id="MySignature" role="contentinfo">
    <blockquote>
<div style="text-align: center;">博客园作者:herry菌
</div>
<p style="text-align: center;">
    <span style="display: block; font-weight: bold;"> 朋友,看到这里,关注作者的公众号吧,不漏掉更新哦 </span>
</p>
<p style="text-align: center;">
    <img width="90%" style="max-width: 240px !important;"
      src="//img2020.cnblogs.com/blog/883015/202112/883015-20211228112018420-497925652.jpg" alt="">
</p>
</blockquote><br><br>
来源:https://www.cnblogs.com/wuhairui/p/15724818.html
頁: [1]
查看完整版本: nodejs制作一个文档同步工具,自动同步到gitee中