作為一名 Web 前端工程師,我們的工作在大多數情況下,就是與各種瀏覽器打交道,開發以頁面為主的 Web 應用程序。為此,非常的熟悉 HTML、CSS、JavaScript 以及各類主流的 JavaScript 工具庫,比如 Dojo、jQuery、YUI 等。但是,瀏覽器的安全沙盒把我們限制在了一個小小的圈子里,我們不能用 JavaScript 訪問操作系統的本地文件系統,不能發起一個 Socket 請求, 不能獲取 CPU 和內存的使用情況, 也不能訪問關系型數據庫或者 NoSQL 數據庫。
您是否一直在憧憬著,某一天,您使用著您最拿手的前端技能,來開發那些本來由 Java,、C++等語言所開發的桌面應用程序呢? 很幸運,答案是肯定的!Node-webkit 這個開源項目的出現,為 Web 前端開發人員提供了一個新的舞臺;它更給我們帶來了一個實際的價值,讓我們現有的 Web 應用,可以更方便的移植到我們的桌面上來,加以本地功能的擴展,獲取更大的用戶體驗度。
Node-webkit 是項目托管網站 Github 上一個非常熱門的開源項目,它基于著名的瀏覽器開源項目 Chromium 和服務器端 JavaScript 實現 Node.js 的一個應用程序運行時環境。假如您對它還沒有任何頭緒,不妨可以這樣來想象一下這個運行時環境:它是一個支持 HTML5 特性的全功能 Web 瀏覽器, 并且它沒有安全沙盒的限制, 我們可以用 JavaScript 來操作 HTML DOM 對象,也可以來調用操作系統的本地資源。
我們來通過一段最簡單的代碼,窺探一下 Node-webkit 的樣子:
<html> <head> <title>Sample App</title> </head> <body> <h1>Hello World!</h1> We are using node.js <script>document.write(process.version)</script>. </body></html>
安裝
有兩種方式可以實現 Node-webkit 的安裝:第一種是從其項目主頁面, 下載源代碼,然后自行編譯安裝;或者, 我們為了方便起見, 可以直接下載它提供的編譯好的二進制可執行文件, 目前支持三個操作系統平臺:Windows、Linux 以及 Mac。
我們的教程在后文中都將主要以 Windows 為例,其他平臺請具體參考 Node-webkit 的項目文檔。以下是安裝的具體步驟:
至此, Node-webkit 安裝就算完成了。我們可以在命令行中運行 nw,如果您看到如下窗口出現, 則表示 Node-webkit 在您的計算機上已完全安裝成功:
創建第一個 Node-webkit 應用
復雜的應用從 Hello World 開始!讓我們一步一步來建立我們第一個最簡單易懂的 Node-webkit 應用程序。
首先,在您計算機上任意目錄下,建立一個命名為 sample-app 的文件夾,它將被用來存放我們的示例應用程序代碼和其他所有需要的資源文件;
然后在 sample-app 文件夾下,預建立一些空的子文件夾,用來合理的存放不同類型的文件;
最后,建立兩個文件:index.html 和 package.json。至此,sample-app 文件夾中看起來應該是這樣的一個結構:
對這樣一個目錄結構,是不是覺得非常熟悉?沒錯,它就是一個標準的 Web 工程的目錄結構,因為 Node-webkit 的開發繼承了 Web 前端開發的一切,所以您所掌握的 Web 開發經驗將使您更快速的掌握它。
下一步,我們來看一下 index.html 和 package.json 這兩個重要文件中的內容:
<html> <head> <title>Sample App</title> </head> <body> <h1>Hello World!</h1> </body></html>
它將是我們這個應用程序的入口,現在它包含的僅僅是一段最簡單的 HTML 文本,顯示了一個"Hello World!"的問候,我們將在后文中一步步的充實它的內容。
{ "main": "index.html", "name": "sample-app", "description": "demo app of node-webkit", "version": "0.1.0", "window": { "toolbar": false, "resizable": false, "width": 800, "height": 500 }}
該文件是 node-webkit 的應用描述文件,一個完整的 node-webkit 應用程序必須包含這樣一個文件。它用于定義應用程序的基本信息以及運行相關的參數,比如名稱、介紹、入口文件名稱以及應用程序窗口的各項配置,如窗口的顯示尺寸、顯示位置、是否顯示工具欄等等。您可以閱讀 Node-webkit 描述文件格式來獲取更多相關信息。
運行
以上這些文件構成了一個最簡單基本的 node-webkit 程序。我們非常清楚如何讓一個 HTML 文件在瀏覽器中運行起來,但是,在 node-webkit 環境下,如何讓它運行起來呢?
打開您的命令行工具,進入 sample-app 所在的目錄,然后執行命令:nw sample-app
成功運行中的窗口界面如下所示:
基于 Dojo 來設計桌面應用
好了,我們接下來要在前文的基礎上,使用 Node-webkit 開發個稍微像樣一點的東西。
開發一個專業的應用程序,界面的開發永遠是一個重頭,將耗費相當多的時間和精力。我們現代 Web 頁面應用的開發中,通常會采用一些設計良好、功能強大、界面組件豐富的工具庫,它們可以極大的加速我們的開發,減少我們的工作量,并且提高代碼質量。例如 Dojo、jQuery 等就是一些我們經常采用的開源工具庫,它們成熟、功能強、兼容性好,并且有強大的開發維護社區的支持。而 Dojo 是我個人比較喜歡的一個,它包含了豐富的基礎 API 和界面組件(布局,表單,表格,圖表等等),面向對象,高度模塊化,可擴展性和可定制性非常強,所以非常適合開發各種不同規模的應用程序。在本教程中,我們將使用 Dojo 作為我們的開發輔助工具。
如今,基于 Web 技術的軟件應用朝著單頁化的方向發展,前端開發的復雜度已經遠遠超出我們的預期,如何讓我們的軟件設計層次清晰,又做到代碼實現簡單明了,即用最少的代碼實現更多的功能,是我們的迫切需求。Dojo 為我們提供了非常有用的工具包 dojox.mvc,它是 Dojo 的一個對目前非常流行的前端 MVC 的思想的實現,主要關注前端的 View 和 Model 之間的數據綁定,能實時同步表單控件和 Model 數據,無論哪一方發生變化,另一方都會進行實時更新。其能夠簡化本來在 JavaScript 中處理表單的繁雜重復的代碼。
我們下面要使用 Dojo 來構建我們整個應用程序的框架。這個應用程序將向您展示 2 個小示例,以此來闡明如何在 Node-webkit 環境下調用本地功能,以及如何訪問外部數據資源。
我們的 index.html 現在看起來已經充實了很多,使用了 Dojo 組件來創建和布局整個應用的界面。下面是一部分關鍵代碼:
<script type="dojo/require">at: "dojox/mvc/at"</script><span id="ctrl" data-dojo-type="dojox/mvc/EditModelRefController" data-dojo-props="sourceModel: models.sysinfo"></span><div id="appLayout" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design: 'headline'"> <div class="centerPanel" data-dojo-type="dijit/layout/TabContainer" data-dojo-props="region: 'center', tabPosition: 'bottom'"> <!-- tab 1 --> <div data-dojo-type="dijit/layout/ContentPane" title="本地功能調用示例"> <div style="border:1px solid #cccccc"> <table> <tr> <td>計算機名:</td> <td><span data-dojo-type="dojox/mvc/Output" data-dojo-props="value: at('widget:ctrl', 'hostname')"></span></td> </tr> <tr> <td>操作系統類型:</td> <td> <span data-dojo-type="dojox/mvc/Output" data-dojo-props="value: at('widget:ctrl', 'ostype')"></span> <span data-dojo-type="dojox/mvc/Output" data-dojo-props="value: at('widget:ctrl', 'platform')"></span> </td> </tr> <tr> <td>CPU 架構:</td> <td><span data-dojo-type="dojox/mvc/Output" data-dojo-props="value: at('widget:ctrl', 'arch')"></span></td> </tr> <tr> <td>CPU 核心數:</td> <td><span data-dojo-type="dojox/mvc/Output" data-dojo-props="value: at('widget:ctrl', 'cpus')"></span></td> </tr> </table> </div> <div style="margin-top:10px;padding: 8px;border:1px solid #cccccc"> <span>內存使用情況:</span> <div id="mem-pie-chart" style="width:550px;height:280px;"></div> </div> </div> <!-- tab 2 --> <div data-dojo-type="dijit/layout/ContentPane" title="遠程數據訪問示例"> <div id="feed-toolbar"></div> <div id="feed-list"></div> </div> </div></div>
下面是實際的運行效果圖:
本地功能調用
上面示例程序的第一個選項卡,展示的是一個調用并展示計算機系統信息的功能。由于 Node-webkit 內置了 Node.js,所以調用計算機本地功能和資源的工作主要都是通過它的 API 來完成。我們的應用使用了 Node.js 的 OS 模塊,用以讀取計算機的基本信息:
// 加載 nodejs OS 模塊var os = global.require('os');//通過調用 nodejs api,獲取本地計算機的內存使用信息var getMemoryData = function() { var fm = os.freemem(); var um = os.totalmem() - fm; return [ { x: "1", y: fm, text: "Free" }, { x: "1", y: um, text: "Used" } ];}//通過調用 nodejs api,獲取本地計算機的基本信息var getSystemInfo = function() { return { hostname: os.hostname(), ostype: os.type(), platform: os.platform(), arch: os.arch(), cpus: os.cpus().length };}
讀寫本地文件系統也是桌面應用程序經常會用到的功能,以下代碼段展示如何完成此任務:
var fs = global.require('fs'); fs.readFile('/your/file.txt', function(err, data) { if (err) throw err; console.log(data); }); fs.writeFile('/your/file.txt', 'Hello World', function(err) { if (err) throw err; console.log('Saved!'); });
注意:Dojo 和 Nodejs 都包含 require API,為了避免沖突,所以請使用 global.require()來限定作用域,以正確調用 Nodejs 的 require API。
遠程數據訪問
我們應用程序的第二個選項卡,展示如何訪問遠程數據。在 Web 開發中,Ajax,JSONP 等方式已經非常流行,這些技術在 Node-webkit 環境下仍然是可用的。在我們的程序中就使用了 Dojo 提供的 Ajax API 來獲取 IBM DeveloperWorks 網站的 RSS 數據:
request('http://www.ibm.com/developerworks/cn/views/global/rss/libraryview.jsp', { handleAs: 'xml'}).then(function(data){ var items = data.getElementsByTagName('item'); for (var i = 0; i < items.length; i++) { var item = items[i]; var children = item.children; var title = children[0].textContent; var description = children[1].textContent; var link = children[2].textContent; var pubdate = new Date(Date.parse(children[3].textContent)); var feed = domConstruct.toDom([ '<div class="feed">', '<h4><a href="', link, '" target="_blank">', title, '</a></h4>', '<p>內容概要: ', description, '</p>', '<div>發布時間: ', locale.format(pubdate), '</div>', '</div>' ].join('')); dom.byId('feed-list').appendChild(feed); }});
除了使用 Ajax,JSONP 等這些瀏覽器提供的遠程數據訪問方式,在 Node-webkit 中另外還可以使用 Nodejs 的 http,https 和 net 等模塊 API 來發起系統原生的 HTTP 和 Socket 請求,與遠程服務器進行數據交互。
var net = require('net');var client = net.connect({ port: 8088 }, function() { console.log('client connected'); client.write('hello world!\r\n'); //向服務器端發送 hello world!});client.on('data', function(data) { console.log(data.toString()); //接受到服務器端發送來的數據 client.end();});client.on('end', function() { console.log('client disconnected');});
調試
調試 Node-webkit 應用,我們一般借助它自帶的開發者工具。要使用這個工具,首先我們要在 package.json 中,將 window 設置項中的 toolbar 設置為 true,之后在運行程序的窗口上會出現頂部的工具欄,在工具欄內點擊右邊如下圖紅框中的按鈕,則會彈出開發者工具(Developer Tools),點擊"Sources"選項卡,出現的就是一個代碼調試工具:
通過該調試工具,我們可以選擇需要調試的代碼文件,對代碼行設置斷點,設置要監視的變量等等,然后進行單步調試,并獲取調試結果信息。
打包與發布
在一個應用程序開發完成后,將其打包成方便于發布的格式是我們必須做的事情。完成我們的 Node-webkit 應用程序的打包步驟如下:
步驟 1:將 sample-app 目錄下的所有文件添加到一個 zip 格式的壓縮文件 sample-app.zip 中,請確認 package.json 在這個 zip 文件中處于跟目錄的位置;
步驟 2:將 sample-app.zip 重命名成 sample-app.nw;
步驟 3:在命令行中運行 nw sample-app.nw,確認能正確運行;
.nw 文件就是 Node-webkit 最基本的發布格式。如果您有需求需要將應用程序打包成.exe 或.app 等可執行文件的格式,您可以參閱Node-webkit 打包指南了解更多打包相關的詳細內容,以達到您的目標。
結束語
隨著 HTML5 的日趨成熟和廣泛應用,基于 Web 技術的軟件開發已經不甘心局限于傳統概念的網頁開發,它們的觸角已經快速伸向了各個軟件開發領域,比如 PhoneGap 移動應用開發, Adobe Air 應用開發等等,讓 HTML,CSS,JavaScript 這些技術擁有了跟多新的表現力以及更強的生命力。深度挖掘我們已經掌握的知識和技能,讓我們的工作變得更有生產力和更有趣。
描述 | 名字 | 大小 |
---|---|---|
示例代碼 | sample-app.zip | 5KB |