用 NodeJS 開發(fā)在線流程圖網站
源碼:https://github.com/maqi1520/Clone-processon
背景
對于程序員來說,每天除了寫代碼,接觸較多的可能是各種圖表了,諸如流程圖、原型圖、拓撲圖、UML 圖以及思維導圖等等,我們較為熟悉的是 ProcessOn 了,可能你還在用 ProcessOn 免費版, 總共十張圖,畫完這張圖下載下來刪除再重新畫另一張。前些天,在群里看到有小伙伴在邀請新用戶注冊,可以獲得 3 個文件數(shù)。奈何大家都注冊了,沒注冊的只有少數(shù),作為前端程序員,我在想是否可以將它的 js 扒下來,在本地起一個服務器使用?
獲取前端靜態(tài)資源
說干就干,使用 chrome 右鍵另存為 ,可以直接將這個網站使用到的靜態(tài)文件保存下來,但是保存下來的靜態(tài)資源目錄都自動替換了本地,但我想要的是跟線上一樣的目錄結構。
難道右鍵一個一個 JS 另存為嗎?
并不是,可以使用一個chrome插件?Save All Resources?[1]?把整個網站的靜態(tài)資源 down 下來,
安裝之后在chrome devTools 會多出一欄
image.png點擊?save All Resources??就可以了,全部down下來了.
解壓之后,我們一起來看看目錄
image.png不光這個域名下的靜態(tài)資源,其他域下的靜態(tài)資源也都 down 下來了,其實這已經完成一半了。
將全部資源拷貝出來,然后將 html 文件重命名為?index.html?使用?http-server[2]?在當前目錄起一個服務,這樣就成功訪問了。能夠畫流程圖了,只不過數(shù)據(jù)不能保存。
那么該如何保存數(shù)據(jù)呢?
開發(fā)一個 chrome 插件
一開始我的想法是開發(fā)一個 chrome 插件,類似掘金的chrome插件[3]一樣, 點擊就可以打開,然后重寫 jquery 的$.ajax?的方法,使用?localStroage?存儲數(shù)據(jù),這樣可以更加方便我們使用,實現(xiàn)起來應該不難吧。
然后就去找如何開發(fā)一個 chrome extension。我在 github 找到了?chrome-extensions-samples[4]?然后對著里面的 demo,嘗試了下。但結果遂不人愿,因為 ProcessOn 中大量使用了eval方法。chrome-extensions 認為這個方法不安全。
又然后根據(jù)官網?Using eval in Chrome extensions[5],根據(jù)里面的介紹,將 html 放入一個?iframe?中, ?這樣可以就可以了。略微開心了一下,一起看下我們的 hello Word Chrome extensions。
Nov-10-2021 15-53-08.gif接下來準備保存數(shù)據(jù)。
iframe 內部想要跟父容器的通信可以使用 parent,又遇到了問題。
image.png因為 chrome extension iframe 是直接打開的,并不是在一個 http 服務下,然后我又試了?postMessage?等方法,還是不能通信。
既然不能做到純離線的,那只能就開發(fā)一個在線版本好了??
Nodejs 開發(fā)
技術棧
- 后端:?express.js[6]
- 數(shù)據(jù)庫:?postgres[7]
- ORM:?prisma[8]
- Authentication:?github OAuth[9]
- 前端:?Jquery[10]
這邊的技術棧我就直接選用了我博客[11]的相同的技術棧,畢竟注冊登錄這些代碼都能直接拿過來用。
感興趣的同學可以看下我之前的文章?用 NextJS 和 TailwindCSS 重構我的博客[12]
表結構
接下來就是根據(jù)接口,進行建表
image.png
image.png根據(jù)首次加載查看詳情的 get 請求 可以看到請求數(shù)據(jù),他是將 Json 作為字符串返回的,我估計他使用的是 MongoDB 數(shù)據(jù)庫,id 跟 MongoDB id 長度一致。
datasource?db?{
??provider?=?"postgresql"
??url??????=?env("DATABASE_URL")
}
generator?client?{
??provider?=?"prisma-client-js"
}
model?User?{
??id?????????????String????@id?@default(uuid())
??name???????????String?
??password???????String
??email??????????String????@unique
??avatar_url?????String?
??emailCheckCode?String??//郵箱驗證唯一code
??checked????????Boolean???@default(true)?//郵箱是否驗證
??posts??????????Post[]
??historys???????History[]
??charts?????????Chart[]
}
model?Comment?{
??id??????String??@id?@default(uuid())
??shapeId?String?
??name????String?
??replyId?String?
??time????Int
??content?String
??userId??String
??chartId?String
??chart???Chart???@relation(fields:?[chartId],?references:?[id])
}
model?Chart?{
??id?????????String????@id?@default(uuid())
??title??????String
??deleted????Boolean???@default(false)
??elements???Json
??page???????Json
??theme??????Json?
??ownerId????String
??owner??????User??????@relation(fields:?[ownerId],?references:?[id])
??historys???History[]
??comments???Comment[]
??createTime?DateTime??@default(now())[email protected]
??lastModify?DateTime??@default(now())[email protected]
}
model?History?{
??id?????????String???@id?@default(uuid())
??title??????String
??remark?????String
??elements???Json
??page???????Json
??theme??????Json?
??userId?????String
??user???????User?????@relation(fields:?[userId],?references:?[id])
??chartId????String
??chart??????Chart????@relation(fields:?[chartId],?references:?[id])
??createTime?DateTime?@default(now())[email protected]
}
然后是歷史表,一對多,一張圖對多張歷史,每次操作都更新當前數(shù)據(jù)后,然后插入歷史表。
總體來說,實現(xiàn)起來不是很難。
部署
想要部署的同學 可以移步?github[13],里面有寫部署步驟。
TODO
當然還有一些比較困難的還未實現(xiàn), 比如:
- websocket 多人同步編輯
- 文件上傳
- 生成縮略圖
- 分享頁面
總結
- ProcessOn 沒有做代碼混淆,對于前端來說可以格式化代碼后直接修改。
- 前端 js 基礎很重要,ProcessOn 沒有使用其他框架,就使用了?
jquery?和?div?實現(xiàn)了流程圖而且不卡,我之前用react 也寫個類似的拓撲圖,但論流暢性和用戶體驗遠不及它。 - 不差錢的同學,還是希望大家支持正版。
最后
本篇記錄了實現(xiàn)的主要步驟,但是對于一些細節(jié),還有一些特殊代碼操作沒有記錄,希望喜歡的同學點個小贊,加個小星?,后續(xù)可以出更多的文章
希望這篇文章對大家有所幫助,也可以參考我往期的文章或者在評論區(qū)交流你的想法和心得,歡迎一起探索前端。
參考資料
[1]Save All Resources :?https://chrome.google.com/webstore/detail/save-all-resources/abpdnfjocnmdomablahdcfnoggeeiedb
[2]http-server:?https://www.npmjs.com/package/http-server
[3]掘金的chrome插件:?https://chrome.google.com/webstore/detail/%E7%A8%80%E5%9C%9F%E6%8E%98%E9%87%91/lecdifefmmfjnjjinhaennhdlmcaeeeb
[4]chrome-extensions-samples:?https://github.com/GoogleChrome/chrome-extensions-samples
[5]Using eval in Chrome extensions:?https://developer.chrome.com/docs/extensions/mv3/sandboxingEval/
[6]express.js:?https://expressjs.com/
[7]postgres:?http://www.postgres.cn/docs/12/
[8]prisma:?https://prisma.io/
[9]github OAuth:?https://docs.github.com/en/developers/apps/building-oauth-apps/authorizing-oauth-apps
[10]Jquery:?https://jquery.com/
[11]博客:?https://maqib.cn/
[12]用 NextJS 和 TailwindCSS 重構我的博客:?https://juejin.cn/post/6984267680324780040
[13]github:?https://github.com/maqi1520/Clone-processon
