第0.1節 HTML5和桌面軟件開發的碰撞javascript
當咱們談論桌面軟件開發技術的時候,你會想到什麼?若是不對技術自己進行更爲深刻的探討,在個人世界裏,有這麼多技術概念能夠被羅列出來(請原諒我本質上是一個Windows程序員的事實)。html
操做系統 API。操做系統發展到今日,幾乎桌面應用的全部功能,都是基於系統API構建的。調用API和語言及技術無關,哪怕是使用匯編。例如(代碼來源於網絡,本地從新編譯):前端
;個人第一個win32彙編程序
;一個經典的hello world !程序
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386
.model flat,stdcall
option casemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;頭文件的定義
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;數據段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data
szCaption db '個人第一個win32程序',0
szText db 'hello world !',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;代碼段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
start:
invoke MessageBox,NULL,offset szText,offset szCaption,MB_OK
invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end starthtml5
代碼清單0-1 彙編MessageBoxjava
在代碼清單0-1中,經過彙編調用MessageBox Api來呈現一個簡單窗口程序。node
代碼清單0-1的運行結果以下:python
圖0-1 代碼清單0-1運行結果c++
一樣的,咱們使用c/c++來調用這樣一個win32 API,代碼多是以下這樣的:git
#include "windows.h"程序員
int main()
{
MessageBox(NULL, (LPCWSTR)L"Hello world!",
(LPCWSTR)L"個人第一個win32應用程序", MB_OK);
return 0;
}
代碼清單0-2 c/c++版MessageBox
代碼清單0-2運行結果以下圖:
圖0-2 代碼清單0-2運行結果
在系統API之上,通過抽象與封裝在各個操做系統上,造成了各自的所謂的庫和框架。好比windows的MFC和Delphi等,Linux的Gnome、GTK+、KDE等,Max OS X平臺的Cocoa開發庫。對於系統API的強依賴性,直接致使的問題是桌面應用的可移植性,開發人員不得不針對不一樣平臺的操做系統(即便同一平臺也不必定能良好兼容)編寫不一樣的代碼。另外即便你已經編寫了不一樣的代碼來適配不一樣的操做系統和平臺,仍然沒有辦法保證桌面應用的UI和交互是一致的,這一點上有的開發者認爲一致反而是障礙,由於不一樣平臺下的用戶的桌面應用的使用習慣是不同的。可是UI呢?我以爲保證UI一致是極其有必要的。
筆者接觸到的最先的跨平臺桌面UI庫是Qt。
Qt 是一個跨平臺的 C++ 圖形用戶界面庫,由挪威 TrollTech 公司出品,目前包括Qt,基於 Framebuffer 的 Qt Embedded,快速開發工具 Qt Designer,國際化工具 Qt Linguist 等部分 Qt 支持全部 Unix 系統,固然也包括 Linux,還支持 WinNT/Win2k,Win95/98 平臺。
圖0-3 Qt
上文中提到的Linux的KDE就是Qt的傑做。Qt作出了兩方面的努力,都很成功,一個是軟件UI,Qt在UI方面展示了獨特的效果,這種效果脫離了所依賴的操做系統的桌面風格,提現了桌面軟件在交互體驗方面的需求;另外一個方面是跨平臺性,它同時支持windows和Linux,在跨平臺的同時保證了自身UI和交互效果的獨立性。
值的一提的是,對於桌面軟件的UI和用戶體驗,Linux和Os X從一開始就作得很好,相反windows一直在快速開發上作文章,這一點一直到.NET 的Winform都沒有什麼大的改變。咱們不能說在windows上作不出炫酷的或者交互良好的桌面軟件,畢竟強大的系統API能讓咱們無所不能,可是這是開發者的追求,不是這個技術體系的給咱們的引導,結果是大多數windows桌面軟件都是灰色的,幾乎沒什麼好的交互效果(這可能有點偏激)。
如今咱們簡單總結下,桌面軟件開發有兩方面的問題成爲制約:
1) 跨平臺性
2) 低成本的UI和交互自定義
對於跨平臺性,上面咱們提到應用程序的底層是系統API,系統API具備自然的系統隔離性,對於開發人員處理這種兼容問題難度每每要大於實現應用程序自己。即便是Qt這樣的UI庫,也根本解決不了問題,UI庫能夠移植,單應用程序自己不能移植。隨着python和Java這樣的具備獨立運行時的框架出現以後,跨平臺的問題彷佛看到了曙光。在操做系統API和應用之間加了一個隔離層,解放了開發者。微軟的.NET也模仿了Java,可是隻是實現了在windows 各個不一樣的系統之間的可移植性(微軟如今也加入了開源大軍,.NET也能夠支持在Linux,OS X上運行了)。雖然運行時自己還具備系統的強依賴性,可是大多數開發者而言咱們能夠忽略這些,關注框架提供的基礎類庫而不是系統API。
跨平臺性彷佛暫時獲得了好的解決方案(雖然並不完美,可是從生產力的角度確實獲得了空前的提升,咱們暫且認爲問題獲得瞭解決),那麼UI和交互呢?順着剛纔的路線去想,在可跨平臺的語言基礎上,構建強大的UI庫是否是就解決了這個問題呢?確實有人在這樣作,可是卻沒有真正的成功者。問題出在哪裏了呢?
在語言和框架發展的過程當中,尤爲是互聯網的發展,專家們抽象和發展了應用程序的基礎功能,好比文件訪問、網絡請求、壓縮解壓縮、加密解密等等,這些內容都被集成到了可跨平臺的基礎類庫中,UI和交互一直作爲附屬品,在這些語言和框架中沒有獲得足夠的重視。可是是人們不重視UI和交互嗎?答案是否認的,隨着互聯網的發展,UI和交互愈加的獲得重視,並且空前發展,UI和交互有了單獨的語言來處理和定義——HTML和CSS。但是遺憾的是這兩門語言並無運用到桌面應用裏來,在編程領域出現了前端和後端的劃分,出現了C/S和B/S的劃分,出現了專門的前端程序員和後端程序員,卻沒有桌面程序員。這是歷史的發展,咱們無可厚非,並且要快樂的接受。HTML和CSS是全新的語言,和c/c++、Java/C#、Python都有本質的區別,首先它面向UI和交互,能夠近乎精準的還原設計;其次它們是聲明性語言,不是命令性語言。聲明性語言爲設計而生,你只需告訴它我要個黑色背景就能夠了,這是語言層級的支持,而不像命令式語言想的是如何實現一個黑色背景。除了HTML和CSS以外,和它們綁定到一塊兒的還有Javascript,一門很長一段時間只能運行在瀏覽器中同DOM進行交互的語言。
如今咱們再回頭看桌面軟件開發,在UI和交互方面沒有辦法和網頁端應用相比,這是從誕生開始就註定的宿命。在網頁端應用飛速發展這些年裏,尤爲是HTML5出現以後,人們彷彿以爲桌面應用已經日落西山了,遲早有一天會消亡。雖然桌面應用的開發者數量在減小,構建在純桌面環境的的應用也愈來愈少,可是桌面環境並無要消失的跡象,即便是瀏覽器自己也仍然是一個桌面應用,它也只能完成桌面應用的一小部分功能,只要你要使用桌面,就會有桌面應用的需求。
桌面應用開發技術也沒有止步,並和瀏覽器技術一步步融合。
融入互聯網,融入web是人類生活的需求,同時也是桌面軟件開發技術的需求,在軟件內部嵌入和控制網頁成爲最初的訴求。因而瀏覽器的功能被精簡,成爲組件被引入桌面軟件中,微軟憑藉自家瀏覽器技術的強項在.NET 中引入了WebBrowser控件,這一舉措方便了開發者,同時由於WebBrowser控件強依賴系統安裝的瀏覽器,微軟的瀏覽器又和系統依賴過強,致使控件在不一樣的客戶系統上的展示行爲也會有差異。固然離跨平臺又遠了一步。
圖0-4 WebBrower控件示例
同時咱們也應該看到控件的方式雖然精簡了瀏覽器功能,可是也擴展了Web應用的能力,控件是能夠和調用者進行通訊的,也就意味着控件是能夠經過「後端代碼」訪問本地資源的。可是在這一方面並無長足的發展。同時Google開源了Chromium項目,基於C++的CEF項目,將Chromium進行改造使之成爲一個控件,相對於微軟的WebBrowser控件,這一舉措意義很大。Chromium是開源的,能夠更好的和調用代碼進行交互,甚至能夠擴展javascript接口,使之能夠調用操做系統資源。
隨着web應用的發展,瀏覽器因爲自己的定位和安全特性的限制,不少須要和客戶端交互的功能沒法完成,因而出現了瀏覽器擴展的概念,可是擴展也不是無限制的。這方面微軟對瀏覽器的擴展最爲粗暴,它直接支持Activex控件,幾乎能夠無限制訪問本地資源,可是同時也打破了瀏覽器安全特性,這也是一直到如今不少銀行的網銀只支持IE瀏覽器的緣由。其餘瀏覽器也在這一方面作出了妥協,瀏覽器的Js或者本地擴展功能都被支持起來,不過僅僅是妥協而已,由於瀏覽器的使命不是開發桌面應用。
在這期間,微軟作了很大的嘗試,首先是基於.NET框架的WPF,微軟推出了XAML語言,全新的聲明性語言,想讓開發者像寫HTML同樣編寫軟件的界面和交互,這不正是廣大開發者的心聲嗎?能夠說WPF是很成功的產品,使用WPF咱們已經能夠可以開發出炫酷的桌面軟件了。可是從跨平臺性角度講,受.NET自己的制約,另外並無斬掉開發者和設計師之間的鴻溝。它仍然是傳統桌面軟件的延伸,面向的是仍然是後端開發人員,前端開發、交互設計師、UI設計師並無被引入進來。
圖0-5 WPF
微軟在這個方向上並無止步,隨着windows8操做系統的推出,Windows Runtime浮出水面。微軟運行使用HTML5和Javascript開發WinRT的應用,看起來很是美好的一件事情,可是在微軟手裏卻多出了不少遺憾。雖然咱們可使用HTML5和Javascript開發應用,甚至在移動端,可是這些應用只能運行於Windows Runtime環境,連Windows8的傳統桌面環境都不能夠,更不要談什麼跨平臺了。緣由是微軟直接擴展了Javascript類庫,映射到Windows Runtime的底層API上。
圖0-6 Windows Runtime
這期間不少人也在嘗試直接把B/S開發模型轉移到桌面開發中,簡單理解就是在本地啓動一個WebServer 負責訪問本地文件系統,UI端經過擴展將請求發送到Server再回調回來。這種方式看起來簡單,實則實現起來很複雜,涉及到通訊機制的改造。豆瓣曾經發布OneRing項目,使用相似的機制,後端使用Python來處理業務。
不論在兩個方向上如何融合,前與後的本質區別並無被打破。由於經過修改瀏覽器代碼去一點點擴展Javascript使之成爲超級瀏覽器,也不是不可取,只不過這期間的工程量仍是很大的,騰訊的Webtop項目就是基於這個想法進行的,不過已經夭折了。本質上仍是因爲HTML的發展制約,瀏覽器廠商不去讓瀏覽器足夠強大,第三方很難作到。所幸HTML5和Node.js出現了,並被承認和發展壯大起來。
關於Html5的新特性,這裏我不展開論述,讀者自行搜索,總之一句話,Html5帶來了翻天覆地的變化,使web應用在功能上能夠更像桌面應用了。而Node.js的誕生,直接打破了Javascript只能寄宿於瀏覽器端的限制,直接走到了大後方,在Node運行時上,Javascript能夠和其餘後端語言同樣訪問本地資源,「隨心所欲」(目前Node Js的基礎類庫尚未辦法和其餘後端語言相比,可是語言的功能本質發生了變化,在一個方向上了)。
圖0-7 Html5新特性
圖0-8 Node js
這裏要再次提到Google開源,它開源了瀏覽器引擎及Javascript引擎V8,開源使得不少有夢想的程序員能夠插上翅膀。因而乎這樣的想法——打破瀏覽器的安全沙箱,讓瀏覽器支持Node Js,先後端通吃——也就正常了。
由於Node Js使用的也是V8引擎,因此改造瀏覽器去兼容Node Js,同時再根據桌面窗口的特性去擴展些API出來,從技術上講小團隊也是能夠實現的。前端開發者也很容易加入到桌面軟件開發的大潮中。一樣一款應用,web端和桌面端能夠共享一套設計和交互,甚至是一樣的HTML和CSS以及負責交互的Javascript代碼。基於Node Js去實現後端業務邏輯,能夠和前端代碼無縫整合,這是目前理想狀態下的桌面軟件開發環境。咱們能夠寫相似這樣的代碼:
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<script>
var process = require('./addon')
console.log(process.getProcessList());
</script>
</body>
</html>
代碼清單0-3 在html頁面中調用nodejs
在瀏覽器中直接集成Node Js,是咱們目前看起來技術實現上難度不高,同時能夠爲桌面軟件開發帶來新但願的方式。下面咱們來看看開源界都作了什麼。
hex。官方網站http://hex.youdao.com/。heX 提供了一種全新的構建桌面應用的方式,可使用 web 技術快速構建跨平臺的桌面應用。heX 基於 CEF 而且融合了 Chromium 與 Node.js,因此咱們能夠在 web 頁面中使用各類 Node.js 原生模塊及第三方擴展,同時在這些模塊及擴展中還能夠訪問到 HTML 中的 DOM 元素。此外,heX 甚至能夠以一種 web 容器的方式嵌入到桌面應用的工程中。
項目目前處於停滯狀態。
圖0-9 hex
appjs。官方網站http://appjs.com/。實現了Html+nodejs開發桌面軟件的功能,項目目前處於停滯狀態。
nw.js。官方網站http://nwjs.io/。引用做者話說「經過Node.js和WebKit技術的融合,開發者能夠用HTML5技術編寫UI,同時又能利用Node.js平臺上衆多library訪問本地OS的能力,最終達到用Web技術就能夠編寫桌面應用的目的。實現上是基於Chromium項目的Content Layer構建(Chromium Browser也一樣基於Content Layer);實現上的特色是把Node.js的消息循環(libuv)和Chromium Renderer進程的消息循環合併到一塊兒,由於這樣才能從DOM(HTML)中直接調用Node.js提供的函數;把Node.js使用的V8引擎和Chromium的V8引擎合併,使得Node.js的Javascript和DOM裏面的Javascript能夠互相訪問;另外由於是支持本地應用,因此安全模型和Web程序有很大不一樣:nw.js程序能夠作web應用不容許作的不少事情,除了經過node.js訪問本地OS之外,還能夠進行跨域訪問等操做。」
圖0-10 nw.js
nw.js目前是該方向上受關注度最高的項目,並且一直在持續更新。
electron.js。官方網站http://electron.atom.io/。electron.js 和nw.js有着千絲萬縷的關係,其前身是github大名鼎鼎的atom shell。是目前最活躍的使用web技術開發桌面軟件的開源項目。包括github的atom和微軟的Visual Studio Code都基於electron.js開發。
圖0-11 electron.js
目前爲止,我以爲值得和你們介紹的項目就這麼多(固然可能有更好的),這些項目爲桌面軟件開發打開了新天地,讓web開發技術和桌面軟件開發技術完美的融合在一塊兒。你們能夠到相關的網站去了解項目的詳細信息。今後桌面軟件開發有了新的技術體系,html5+node.js。固然探索尚未止步,好比edge.js(https://github.com/tjanczuk/edge),打通 了node js 和.NET運行時,能夠實現互調,那麼咱們也是能夠node js 爲橋樑把複雜的業務邏輯封裝到.NET中。微軟的開源項目.NET Core,也讓不少人產生了新的想法,是否能夠將.NET Core 運行時直接打包到瀏覽器中,將.NET 類庫直接生成Javascript 接口供網頁中的js調用呢?
圖0-12 .NET Core 5
在將近兩年的HTML5桌面軟件開發過程當中,雖然總體過程是愉快的,可是不可避免的遇到不少問題甚至是沒法克服只能繞過的「坑」。兩年裏我主要使用的框架是nw.js(那時還叫node-webkit),也在博客上零星的寫了一些nw.js入門的教程,雖然不成體系,文章數量也很少,可是仍然是國內最全的教程了。nw.js 也在不斷的迭代更新,因而我產生了從新動手,寫一本完整的書來記錄兩年來的開發經驗,這裏面重要的不是nw.js如何使用,重要的是使用Html5和node.js開發桌面應用咱們應該怎麼作,會遇到什麼問題,如何去解決。
在下一節,會給你們闡述下nw.js的基本實現原理。
nw.js,electron交流羣 313717550