大家好,我是herry菌,現在是我們的分享時間,今天要分享的是,使用nodejs開發一個文檔同步器,可以將本地的文件實時同步在git倉庫中。
初衷
之所以要做這個工具是為了讓自己能隨時用電腦時記錄日常工作或生活。一般只需要簡單記錄下就行了。這樣我在家里的和公司里的記錄都能同步看到。
要說這種應用市面上有很多,像堅果雲、有道雲筆記、騰訊文檔、語雀之類的都是。我為什么還是要自己實現一個呢。首先雲筆記要記錄時每次都要打開應用到指定頁面去,而我比較喜歡使用nodepad來做記事,notepad打開很快,打開就是之前的記錄位置,我可以快速把自己的想法記錄上去,如果等待時間長個幾秒,可能就會忘記一些東西。雖然堅果雲可以同步文件,但是我公司的電腦屏蔽了這個軟件聯網,因此就只能自己搞個了。
這樣后期整理的時候看到幾個關鍵詞就能想起來具體的事情,有的也可以為日后整理成文章做一個草稿,這樣寫文章才能有頭有尾,否則想到什么說什么是非常不利於寫出文章的。
一開始我使用手動同步的方式,但是發現很麻煩,之后就直接用了個批處理文件來一次性同步。
git pull git add . git commit -m '同步' git push git status @echo off pause
但是這樣還是有幾個缺點:
1.有時候會忘記執行同步,特別是下班的時候,直接關機的。
2.如果一開始忘記同步了,后面就會產生git沖突。體驗不是太好。
接下來就是開始開發了
開發前,我們電腦上需要默認安裝nodejs和git。
因為后來抽時間寫了個小程序。只要把程序運行在后台,每過一段時間就會自動將文檔同步起來。
本地改過內容會自動同步到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秒都會去檢查下是否是最新的。