首先我們分享的第一塊叫端的延展。不知道大家對這張圖熟不熟悉,前段時間的新聞大家應該都聽到過,硅谷鋼鐵俠艾隆馬斯克發布了第一款商業化的載人龍飛船,這張圖片中就是龍飛船的控制臺,知乎上有人對這張圖的評價叫 JS 上天了。為什么說叫 JS 上天了呢?因為有傳言說它是基于 開發的,不過這個消息并沒有得到證實。但是可以證實的一點是航天飛船的觸控界面 UI ,確實是基于 + 這樣的架構來實現的。這也從某種程度上說明了這種架構的一個可用性和穩定性的能力。
下面我們一起來回顧一下前端在整個端領域的發展歷程。在早期,前端工程師的定義可能是基于瀏覽器運行環境的 Web 開發,但是隨著 09 年 Node.js 的出現,讓前端工程師有了脫離瀏覽器運行環境的開發能力。我們擁有了可以面向服務端開發的能力,前端的能力延展到了服務端。
隨著 HTML5 標準的制定,以及移動端設備技術的發展,前端工程師也可以更多的擁抱面向移動端場景的開發。也出現了像今天上午兩位講師所講到的移動端領域 React 這樣的跨平臺技術方案。隨著移動 APP 成為一個主流,基于這些智能化的設備以及芯片的計算能力,前端也普及到了物聯網設備方向,前端可以擁有了面向 Iot 的開發能力,也誕生了像 Thing.js 這樣的面向物聯網設備開發的 Js 框架。
CLI -> GUI
今天所要講的主題是桌面端,隨著 這樣的跨終端 JS 框架的出現,整個前端工程師的能力也是延展到了桌面端。當我們擁有了這樣的一個桌面端的開發能力之后,它能帶給我們的價值是什么呢?首先看一下桌面端給我們帶來哪些不一樣的體驗。大家看到左邊這張圖,是早期電腦的 DOS 系統的運行的截圖,右邊則是 1983 年蘋果電腦發布的第一款 Apple Lisa 個人電腦,它是全球第一款搭載圖形用戶界面(也就是我們所說的 GUI)的一臺個人電腦,正是因為這款電腦的問世,讓后期個人電腦大眾化的普及得以實現。為什么它會帶動個人電腦的普及化,是因為圖形界面對于用戶來說,在視覺上更容易接受,學習的成本也是大幅的下降。相信用過 MAC 系統的同學都會對蘋果優秀的界面設計以及整體的交互體驗,有比較深刻的感受。
那么,這樣的桌面端 GUI 的技術,能給我的前端開發工作帶來什么不一樣呢?
左邊這個流程相信大家不陌生,在我們開始新項目開發的時候,可能需要做哪些事情?首先第一步可能是需要去創建一個 Git 倉庫,創建完成之后將倉庫克隆到本地,然后通過團隊內部的 CLI 工具的安裝之后,去執行例如xxx-cli 這樣的命令去創建一個項目。創建項目完成之后,如果想進行開發,我們需要去運行npm ,安裝所需的依賴包,最終將整個項目提交到 Git 倉庫上去。這是我們新項目的創建,基于 CLI 方式的一個操作流程。
如果說基于客戶端的能力的,我們可以做哪些改變呢?我們可以看到,右邊的圖是我們團隊前端工程化平臺敦煌的系統截圖。如果是創建一個新項目,只需要選擇自己的創建方式,然后輸入一些必要的創建參數,比如說選擇你需要創建的 Git 倉庫 Group、項目名稱、腳手架類型,點擊創建項目之后,它會自動幫你將左邊的這一系列的流程全部執行完畢。就是說將左邊 6 個步驟簡化到了 2 個步驟,大大的簡化了操作的鏈路。
GUI 賦予的價值
GUI 賦予了我們哪些價值呢?首先它可以將分散的任務點進行一個串聯整合,提供了一個更簡化的操作鏈路,同時它還可以抹平不同同學使用時一些流程間的差異,以及流程所依賴的一些環境的差異,并且基于 GUI 的一個整合能力,我們還可以將其他能力進行一個橫向的串通,并且通過 GUI 來設計插件化的機制,還可以創造一個可共建的生態。同時基于 GUI 的圖形界面操作低學習成本,以及它對整個流程的托管,也是可以大大的降低團隊同學的研發復雜度。
業務場景應用
下面是基于 開發的一些重點應用的落地場景。這是我所負責的政采云電子招投標客戶端的業務。它主要的功能是幫助用戶由傳統的線下招投標,紙質的標書,轉變為電子標書,我們提供這樣的客戶端可以幫助用戶串聯整個制作標書的流程。同時基于 所提供的 Node.js 的能力,用戶本地標書文件的讀寫,以及本地文件的加解密操作,都可以在客戶端里面完成。
基建場景應用
這邊是 在我們的工程化平臺上的實踐,這就是我們前面所提到的前端工程化平臺-敦煌。它主要做的內容是對整個前端研發流程的托管,像我們剛才所提到的項目創建就是其中的一個環節。下面我們還會詳細的介紹一些這方面的應用。
開發模式
上面我們大概介紹了一下 的一些價值。如果說我們想基于 開發一個跨平臺的桌面端應用,應該如何來做?下面一起來看一下,第二部分:開發模式。 的開發模式跟我們平時的 Web 開發有哪些不一樣的地方?
架構
首先這是 的一個整體的架構,它是由 開發了一個開源框架,允許我們使用來 HTML + CSS + 來構建開發桌面應用,大大降低了桌面應用的開發的復雜度。整體架構的核心組成是由 + Node.js + APIs 組成的。其中 提供了 UI 的能力,Node.js 讓 有了底層操作的能力, APIs 則解決了跨平臺的一些問題,比如說 系統、MAC OS 系統及 Linux 系統之前一些差異的屏蔽,并且它還提供了一個比較統一體驗的原生能力。
能力點
我們來介紹一下它的一些核心的能力點。
其他桌面端選型對比
提供這些能力點大大的降低了桌面端開發的成本,以及上手的門檻。當然開發桌面端的話,除了 外,還會有一些其他的選型,我們看一下它跟其他的選型相比較的話有哪些差異點。
所以基于上面的比較,開發桌面客戶端,對前端工程師來說, 是一個非常好的選擇。
簡單 應用的結構
下面來看一下,如果想開發一個桌面客戶端,應該怎么做呢?這邊是一個最簡單的 桌面應用的結構,我們只需要有三個文件,首先我們通過 .json 中的main字段,通過main字段來定義應用的一個啟動入口。我們將入口文件定義為main.js,在mian.js里我們做了哪些事情呢?首先 app 代表著整個應用,監聽 app 的狀態,當整個應用達到一個 ready 的狀態之后,通過 提供的,去新創建一個瀏覽器窗口。創建瀏覽器窗口之后,去加載index.html文件,這樣的話我們就完成了一個最基礎版桌面端應用的實現。基于 開發桌面端應用,和平時的開發 web 端應用有哪些不一樣的,我們需要了解的兩個核心概念就是:主進程和渲染進程,以及兩個進程間的通信如何實現。在剛才的示例中,其中main.js是運行在主進程中,index.html則是運行在渲染進程之中。下面我們通過一個簡單的 Demo,來看一下如何實現兩個進程之間的通信,并且如何通過主進程來進行一些 Node.js 能力調用的。
進程間的通信
我們想要實現這樣的效果,頁面上有一個按鈕桌面應用程序主要開發技術應用場景,當點擊按鈕之后,向主進程發送了一個say-hello的消息,當主進程接收到消息之后桌面應用程序主要開發技術應用場景,它會在系統桌面上創建一個文件叫hello.txt。并寫入內容Hello Mac!。具體的我們是怎么做的?
首先在渲染進程里面,我們應該在頁面上會進行一個按鈕操作事件,當事件觸發之后,我們通過 提供的 向主進程發送一個叫say-hello這樣的一個消息。當我們的主進程接收到這樣一個消息之后,則可以在主進程中直接調用 Node.js 的 fs 模塊,一個文件讀寫的模塊。首先先創建一個文件,并且對這個文件寫入我們所傳輸的內容。當文件寫入成功之后,對渲染進程進行回復,通過調用 提供的模塊,顯示系統通知去告知用戶,這是一個簡單的 Demo 的實現,其核心的點就是需要關注主進程和渲染進程的概念,以及兩個進程之間是如何通過 IPC 機制進行通信的,這邊是一個簡單的實現。還有一些更多的應用的場景,這塊就不再對 API 進行過多的介紹。
下面我們會根據一個實際的應用,來介紹一下 開發的實踐。
工程化發展 CLI -> GUI
以我們的前端工程化平臺敦煌為例,介紹一下我們是如何通過 將工程化能力由 CLI 式 變為 GUI 式的使用。首先大家先看一個視頻,這個視頻就是我們在最開始所提到的項目創建的整個流程的運行的演示。大家可以看到我們整個流程完成了 Git 倉庫的創建、項目模板的創建、項目模板到倉庫的推送,并且對 Git 項目進行本地克隆,克隆完成之后,會進行依賴的安裝,并且在客戶端進行重新載入和管理這樣一個流程。將之前分散的單點命令操作,通過 GUI 的方式進行一個串聯。這個流程只是工程化平臺中的一塊,我們在整個工程化平臺中,實現了很多的單點命令到工作流的串聯。
I2P( To )
這邊是我們整個前端應用管理平臺的系統架構,大概看一下。核心流程就是上面所寫到的一個 I2P 的概念,就是 to 。它完成了組件、模板和項目這三個級別,從創建到發布的全流程托管。
在上面的整個 I2P 的流程中,我們沉淀出一些項目數據,包括流程數據,可能還有一些類似于組件管理的數據。以數據為連接點,可以將整個的研發流程與其他的一些技術建設能力進行一個串聯打通,包括用戶行為分析、頁面級、項目級的性能分析報告,還有錯誤監控的機制,都可以接入到整個工程化平臺上。支撐我們整個工程化平臺就是一些基礎能力以及 所提供的桌面端能力。基礎能力,包括一些常規的 GIt 操作、NPM 操作、一些命令執行和一些本地的 服務。 提供了桌面端包括更新、窗口管理、通信,以及些原生能力。
由點到線單點命令 -> 任務流
下面我們就具體來看一下如何實現由一個單點命令到任務流這樣的一個串聯。將單點命令的操作變為任務流的串聯模式,我們要從以下 4 個切入點來實現。
? 首先我們要將常規的一些命令調用變為函數式的調用。
? 基于這些函數式的調用,進行一個任務流的編排和組裝,根據實際的開發場景,去定制一個任務流。
? 第三塊我們所需要的是整個任務流的任務進度反饋機制,如何將任務執行,通過 GUI 的能力,讓用戶可以直觀感受到整個任務的執行鏈路和進度。
? 最后,在整個任務流中,很重要的一塊就是對整個流程的數據收集。
流程的設計
下面是我們剛才所演示的項目創建流程的架構設計。當我們在調用項目創建模塊的時候,首先會通過 接口,去創建 Git 項目。先對整個用戶的權限做一層校驗,校驗通過之后,通過調用 API,進行一個倉庫的創建,之后,根據所選用的模板信息拉取統一維護的項目模板,根據用戶所輸的項目名稱、項目描述等信息,來生成真正的項目文件,調用 API 將整個項目文件推送到創建好的倉庫。關于 API 的使用這一塊,在掘金上有進行過文章的分享,大家感興趣的話可以去了解一下,這邊就不再進行詳細的闡述。在我們整個服務端完成了一系列的 Git 創建操作之后,會將創建成功的倉庫 url,給到我們的桌面端,桌面端接收到這樣創建成功的任務結果之后,開始執行一些本地操作的任務流程。將 Git 倉庫克隆到本地的工作區內,同時完成整個項目的依賴安裝。在依賴安裝之后,我們會借助桌面端的通知能力,包括釘釘的接口去完成通知和反饋。其中克隆、依賴的安裝以及通知反饋是在我們桌面端的主進程內完成的。在我們整個任務流中,它有實時與渲染進程的消息反饋。我們會將整個任務的進度,包括命令執行的日志輸出、命令執行結果,通過 IPC 的方式實時的與渲染進行通信,最終在界面上給到用戶反饋。在整個流程中,也會對項目數據和流程數據進行存儲。
實現這樣的整個流程,在實踐上有哪些是需要說的呢,下面我們來看一下具體的代碼。
npm 變為 npm.()
首先在進行命令調用的時候,要將npm 這樣一個命令行的調用方式變成變為一個函數式的調用,會變為npm.()這樣一個調用方式。
git init 變為 git.init()
類似 Git 的命令,也會變成函數式調用
將命令式執行 化
下面我們看一下,具體場景,如何將命令式調用變成函數式調用。首先是將命令執行 化。例如git init這樣的操作,在執行整個命令的時候,我們更多關心的是整個命令執行的結果,可能不太會關心命令執行過程中的一些輸出的內容。這樣的話我們就可以通過 Node.js 中的spawn,啟動子進程來執行命令。通過監聽子進程輸出來判斷我們整個命令的執行狀態,然后對整個命令進行 封裝,我們就完成了git init這樣一個命令行調用變為git.init()這樣一個異步的函數調用。
實時輸出命令執行日志
在另外一個場景,比如說npm ,依賴安裝,或者說啟動本地開發服務,整個命令的執行過程可能會比較長,我們更關注的是過程中實時的日志輸出。我們怎么來做呢?首先我們這邊是先創建一個實例,作為我們的日志的分發管理,同樣的我們也是通過spwan來啟動一個子進程來執行命令,并且實時的監聽子進程的輸出,將輸出的日志通過實例將它分發出去。當我們在主進程中拿到這樣的實時日志輸出之后,可以通過 主進程跟渲染進程間的 IPC 的通信,將日志實時的輸出到渲染進程當中。
將命令式調用變為函數式調用,有了這樣的能力之后,就可以通過對這些函數的調用,進行任務流的編排。例如剛才我們所提到的項目創建,這可能是一個比較通用的流程,還有組件管理、模板管理和以及項目發布等。大家可以根據自己實際的業務需要,來去編排自己一個任務流。