电竞比分网-中国电竞赛事及体育赛事平台

分享

使用 Dojo 和 node

 oskycar 2017-03-01

在 IBM Bluemix 云平臺(tái)上開(kāi)發(fā)并部署您的下一個(gè)應(yīng)用。

開(kāi)始您的試用

前言

作為一名 Web 前端工程師,我們的工作在大多數(shù)情況下,就是與各種瀏覽器打交道,開(kāi)發(fā)以頁(yè)面為主的 Web 應(yīng)用程序。為此,非常的熟悉 HTML、CSS、JavaScript 以及各類主流的 JavaScript 工具庫(kù),比如 Dojo、jQuery、YUI 等。但是,瀏覽器的安全沙盒把我們限制在了一個(gè)小小的圈子里,我們不能用 JavaScript 訪問(wèn)操作系統(tǒng)的本地文件系統(tǒng),不能發(fā)起一個(gè) Socket 請(qǐng)求, 不能獲取 CPU 和內(nèi)存的使用情況, 也不能訪問(wèn)關(guān)系型數(shù)據(jù)庫(kù)或者 NoSQL 數(shù)據(jù)庫(kù)。

您是否一直在憧憬著,某一天,您使用著您最拿手的前端技能,來(lái)開(kāi)發(fā)那些本來(lái)由 Java,、C++等語(yǔ)言所開(kāi)發(fā)的桌面應(yīng)用程序呢? 很幸運(yùn),答案是肯定的!Node-webkit 這個(gè)開(kāi)源項(xiàng)目的出現(xiàn),為 Web 前端開(kāi)發(fā)人員提供了一個(gè)新的舞臺(tái);它更給我們帶來(lái)了一個(gè)實(shí)際的價(jià)值,讓我們現(xiàn)有的 Web 應(yīng)用,可以更方便的移植到我們的桌面上來(lái),加以本地功能的擴(kuò)展,獲取更大的用戶體驗(yàn)度。

回頁(yè)首

Node-webkit 架構(gòu)概述

Node-webkit 是項(xiàng)目托管網(wǎng)站 Github 上一個(gè)非常熱門(mén)的開(kāi)源項(xiàng)目,它基于著名的瀏覽器開(kāi)源項(xiàng)目 Chromium 和服務(wù)器端 JavaScript 實(shí)現(xiàn) Node.js 的一個(gè)應(yīng)用程序運(yùn)行時(shí)環(huán)境。假如您對(duì)它還沒(méi)有任何頭緒,不妨可以這樣來(lái)想象一下這個(gè)運(yùn)行時(shí)環(huán)境:它是一個(gè)支持 HTML5 特性的全功能 Web 瀏覽器, 并且它沒(méi)有安全沙盒的限制, 我們可以用 JavaScript 來(lái)操作 HTML DOM 對(duì)象,也可以來(lái)調(diào)用操作系統(tǒng)的本地資源。

圖 1. Node-webkit 概覽
Node-webkit 概覽

我們來(lái)通過(guò)一段最簡(jiǎn)單的代碼,窺探一下 Node-webkit 的樣子:

清單 1. 簡(jiǎn)單示例代碼<!DOCTYPE html>
<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>
圖 2. 清單 1 代碼運(yùn)行結(jié)果
清單 1 代碼運(yùn)行結(jié)果

安裝

有兩種方式可以實(shí)現(xiàn) Node-webkit 的安裝:第一種是從其項(xiàng)目主頁(yè)面, 下載源代碼,然后自行編譯安裝;或者, 我們?yōu)榱朔奖闫鹨?jiàn), 可以直接下載它提供的編譯好的二進(jìn)制可執(zhí)行文件, 目前支持三個(gè)操作系統(tǒng)平臺(tái):Windows、Linux 以及 Mac。

我們的教程在后文中都將主要以 Windows 為例,其他平臺(tái)請(qǐng)具體參考 Node-webkit 的項(xiàng)目文檔。以下是安裝的具體步驟:

  1. 將下載的二進(jìn)制文件放到一個(gè)文件夾下,例如 C:\Program Files\node-webki
  2. 在 Windows 的環(huán)境變量 PATH 中,添加路徑 C:\Program Files\node-webki

至此, Node-webkit 安裝就算完成了。我們可以在命令行中運(yùn)行 nw,如果您看到如下窗口出現(xiàn), 則表示 Node-webkit 在您的計(jì)算機(jī)上已完全安裝成功:

圖 3. 成功運(yùn)行 Node-Webkit 的界面
成功運(yùn)行 Node-Webkit 的界面

創(chuàng)建第一個(gè) Node-webkit 應(yīng)用

復(fù)雜的應(yīng)用從 Hello World 開(kāi)始!讓我們一步一步來(lái)建立我們第一個(gè)最簡(jiǎn)單易懂的 Node-webkit 應(yīng)用程序。

首先,在您計(jì)算機(jī)上任意目錄下,建立一個(gè)命名為 sample-app 的文件夾,它將被用來(lái)存放我們的示例應(yīng)用程序代碼和其他所有需要的資源文件;

然后在 sample-app 文件夾下,預(yù)建立一些空的子文件夾,用來(lái)合理的存放不同類型的文件;

最后,建立兩個(gè)文件:index.html 和 package.json。至此,sample-app 文件夾中看起來(lái)應(yīng)該是這樣的一個(gè)結(jié)構(gòu):

圖 4. sample-app 包含的文件和目錄
sample-app 包含的文件和目錄

對(duì)這樣一個(gè)目錄結(jié)構(gòu),是不是覺(jué)得非常熟悉?沒(méi)錯(cuò),它就是一個(gè)標(biāo)準(zhǔn)的 Web 工程的目錄結(jié)構(gòu),因?yàn)?Node-webkit 的開(kāi)發(fā)繼承了 Web 前端開(kāi)發(fā)的一切,所以您所掌握的 Web 開(kāi)發(fā)經(jīng)驗(yàn)將使您更快速的掌握它。

下一步,我們來(lái)看一下 index.html 和 package.json 這兩個(gè)重要文件中的內(nèi)容:

清單 2. index.html<!DOCTYPE html>
<html>
  <head>
    <title>Sample App</title>
  </head>
  <body>
    <h1>Hello World!</h1>
  </body>
</html>

它將是我們這個(gè)應(yīng)用程序的入口,現(xiàn)在它包含的僅僅是一段最簡(jiǎn)單的 HTML 文本,顯示了一個(gè)"Hello World!"的問(wèn)候,我們將在后文中一步步的充實(shí)它的內(nèi)容。

清單 3. package.json
{
    "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 的應(yīng)用描述文件,一個(gè)完整的 node-webkit 應(yīng)用程序必須包含這樣一個(gè)文件。它用于定義應(yīng)用程序的基本信息以及運(yùn)行相關(guān)的參數(shù),比如名稱、介紹、入口文件名稱以及應(yīng)用程序窗口的各項(xiàng)配置,如窗口的顯示尺寸、顯示位置、是否顯示工具欄等等。您可以閱讀 Node-webkit 描述文件格式來(lái)獲取更多相關(guān)信息。

運(yùn)行

以上這些文件構(gòu)成了一個(gè)最簡(jiǎn)單基本的 node-webkit 程序。我們非常清楚如何讓一個(gè) HTML 文件在瀏覽器中運(yùn)行起來(lái),但是,在 node-webkit 環(huán)境下,如何讓它運(yùn)行起來(lái)呢?

打開(kāi)您的命令行工具,進(jìn)入 sample-app 所在的目錄,然后執(zhí)行命令:nw sample-app

成功運(yùn)行中的窗口界面如下所示:

圖 5. sample-app 運(yùn)行結(jié)果
sample-app 運(yùn)行結(jié)果

基于 Dojo 來(lái)設(shè)計(jì)桌面應(yīng)用

好了,我們接下來(lái)要在前文的基礎(chǔ)上,使用 Node-webkit 開(kāi)發(fā)個(gè)稍微像樣一點(diǎn)的東西。

開(kāi)發(fā)一個(gè)專業(yè)的應(yīng)用程序,界面的開(kāi)發(fā)永遠(yuǎn)是一個(gè)重頭,將耗費(fèi)相當(dāng)多的時(shí)間和精力。我們現(xiàn)代 Web 頁(yè)面應(yīng)用的開(kāi)發(fā)中,通常會(huì)采用一些設(shè)計(jì)良好、功能強(qiáng)大、界面組件豐富的工具庫(kù),它們可以極大的加速我們的開(kāi)發(fā),減少我們的工作量,并且提高代碼質(zhì)量。例如 Dojo、jQuery 等就是一些我們經(jīng)常采用的開(kāi)源工具庫(kù),它們成熟、功能強(qiáng)、兼容性好,并且有強(qiáng)大的開(kāi)發(fā)維護(hù)社區(qū)的支持。而 Dojo 是我個(gè)人比較喜歡的一個(gè),它包含了豐富的基礎(chǔ) API 和界面組件(布局,表單,表格,圖表等等),面向?qū)ο?,高度模塊化,可擴(kuò)展性和可定制性非常強(qiáng),所以非常適合開(kāi)發(fā)各種不同規(guī)模的應(yīng)用程序。在本教程中,我們將使用 Dojo 作為我們的開(kāi)發(fā)輔助工具。

如今,基于 Web 技術(shù)的軟件應(yīng)用朝著單頁(yè)化的方向發(fā)展,前端開(kāi)發(fā)的復(fù)雜度已經(jīng)遠(yuǎn)遠(yuǎn)超出我們的預(yù)期,如何讓我們的軟件設(shè)計(jì)層次清晰,又做到代碼實(shí)現(xiàn)簡(jiǎn)單明了,即用最少的代碼實(shí)現(xiàn)更多的功能,是我們的迫切需求。Dojo 為我們提供了非常有用的工具包 dojox.mvc,它是 Dojo 的一個(gè)對(duì)目前非常流行的前端 MVC 的思想的實(shí)現(xiàn),主要關(guān)注前端的 View 和 Model 之間的數(shù)據(jù)綁定,能實(shí)時(shí)同步表單控件和 Model 數(shù)據(jù),無(wú)論哪一方發(fā)生變化,另一方都會(huì)進(jìn)行實(shí)時(shí)更新。其能夠簡(jiǎn)化本來(lái)在 JavaScript 中處理表單的繁雜重復(fù)的代碼。

我們下面要使用 Dojo 來(lái)構(gòu)建我們整個(gè)應(yīng)用程序的框架。這個(gè)應(yīng)用程序?qū)⑾蚰故?2 個(gè)小示例,以此來(lái)闡明如何在 Node-webkit 環(huán)境下調(diào)用本地功能,以及如何訪問(wèn)外部數(shù)據(jù)資源。

我們的 index.html 現(xiàn)在看起來(lái)已經(jīng)充實(shí)了很多,使用了 Dojo 組件來(lái)創(chuàng)建和布局整個(gè)應(yīng)用的界面。下面是一部分關(guān)鍵代碼:

清單 4. index.html
<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="本地功能調(diào)用示例">
      <div style="border:1px solid #cccccc">
        <table>
          <tr>
            <td>計(jì)算機(jī)名:</td>
            <td><span data-dojo-type="dojox/mvc/Output" 
                data-dojo-props="value: at('widget:ctrl', 'hostname')"></span></td>
          </tr>
          <tr>
            <td>操作系統(tǒng)類型:</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 架構(gòu):</td>
            <td><span data-dojo-type="dojox/mvc/Output" 
                data-dojo-props="value: at('widget:ctrl', 'arch')"></span></td>
          </tr>
          <tr>
            <td>CPU 核心數(shù):</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>內(nèi)存使用情況:</span>
        <div id="mem-pie-chart" style="width:550px;height:280px;"></div>
      </div>
    </div>

    <!-- tab 2 -->
    <div data-dojo-type="dijit/layout/ContentPane" title="遠(yuǎn)程數(shù)據(jù)訪問(wèn)示例">
      <div id="feed-toolbar"></div>
      <div id="feed-list"></div>
    </div>
  </div>
</div>

下面是實(shí)際的運(yùn)行效果圖:

圖 6. 本地功能調(diào)用示例運(yùn)行界面
本地功能調(diào)用示例運(yùn)行界面

本地功能調(diào)用

上面示例程序的第一個(gè)選項(xiàng)卡,展示的是一個(gè)調(diào)用并展示計(jì)算機(jī)系統(tǒng)信息的功能。由于 Node-webkit 內(nèi)置了 Node.js,所以調(diào)用計(jì)算機(jī)本地功能和資源的工作主要都是通過(guò)它的 API 來(lái)完成。我們的應(yīng)用使用了 Node.js 的 OS 模塊,用以讀取計(jì)算機(jī)的基本信息:

清單 5. 讀取本地系統(tǒng)信息
// 加載 nodejs OS 模塊
var os = global.require('os');

//通過(guò)調(diào)用 nodejs api,獲取本地計(jì)算機(jī)的內(nèi)存使用信息
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" }
    ];
}

//通過(guò)調(diào)用 nodejs api,獲取本地計(jì)算機(jī)的基本信息
var getSystemInfo = function() {
    return {
        hostname: os.hostname(),
        ostype: os.type(),
        platform: os.platform(),
        arch: os.arch(),
        cpus: os.cpus().length
    };
}

讀寫(xiě)本地文件系統(tǒng)也是桌面應(yīng)用程序經(jīng)常會(huì)用到的功能,以下代碼段展示如何完成此任務(wù):

清單 6. 讀寫(xiě)本地文件
  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,為了避免沖突,所以請(qǐng)使用 global.require()來(lái)限定作用域,以正確調(diào)用 Nodejs 的 require API。

遠(yuǎn)程數(shù)據(jù)訪問(wèn)

我們應(yīng)用程序的第二個(gè)選項(xiàng)卡,展示如何訪問(wèn)遠(yuǎn)程數(shù)據(jù)。在 Web 開(kāi)發(fā)中,Ajax,JSONP 等方式已經(jīng)非常流行,這些技術(shù)在 Node-webkit 環(huán)境下仍然是可用的。在我們的程序中就使用了 Dojo 提供的 Ajax API 來(lái)獲取 IBM DeveloperWorks 網(wǎng)站的 RSS 數(shù)據(jù):

圖 7. 遠(yuǎn)程數(shù)據(jù)訪問(wèn)示例運(yùn)行界面
遠(yuǎn)程數(shù)據(jù)訪問(wèn)示例運(yùn)行界面
清單 7. 讀取遠(yuǎn)程 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>內(nèi)容概要: ', description, '</p>',
                '<div>發(fā)布時(shí)間: ', locale.format(pubdate), '</div>',
            '</div>'
        ].join(''));

        dom.byId('feed-list').appendChild(feed);
    }
});

除了使用 Ajax,JSONP 等這些瀏覽器提供的遠(yuǎn)程數(shù)據(jù)訪問(wèn)方式,在 Node-webkit 中另外還可以使用 Nodejs 的 http,https 和 net 等模塊 API 來(lái)發(fā)起系統(tǒng)原生的 HTTP 和 Socket 請(qǐng)求,與遠(yuǎn)程服務(wù)器進(jìn)行數(shù)據(jù)交互。

清單 8. 使用 Socket 與服務(wù)器交互
var net = require('net');

var client = net.connect({ port: 8088 }, function() {
  console.log('client connected');
  client.write('hello world!\r\n'); //向服務(wù)器端發(fā)送 hello world!
});

client.on('data', function(data) {
  console.log(data.toString());   //接受到服務(wù)器端發(fā)送來(lái)的數(shù)據(jù)
  client.end();
});

client.on('end', function() {
  console.log('client disconnected');
});

調(diào)試

調(diào)試 Node-webkit 應(yīng)用,我們一般借助它自帶的開(kāi)發(fā)者工具。要使用這個(gè)工具,首先我們要在 package.json 中,將 window 設(shè)置項(xiàng)中的 toolbar 設(shè)置為 true,之后在運(yùn)行程序的窗口上會(huì)出現(xiàn)頂部的工具欄,在工具欄內(nèi)點(diǎn)擊右邊如下圖紅框中的按鈕,則會(huì)彈出開(kāi)發(fā)者工具(Developer Tools),點(diǎn)擊"Sources"選項(xiàng)卡,出現(xiàn)的就是一個(gè)代碼調(diào)試工具:

圖 8. Node-webkit 調(diào)試工具界面
Node-webkit 調(diào)試工具界面

通過(guò)該調(diào)試工具,我們可以選擇需要調(diào)試的代碼文件,對(duì)代碼行設(shè)置斷點(diǎn),設(shè)置要監(jiān)視的變量等等,然后進(jìn)行單步調(diào)試,并獲取調(diào)試結(jié)果信息。

打包與發(fā)布

在一個(gè)應(yīng)用程序開(kāi)發(fā)完成后,將其打包成方便于發(fā)布的格式是我們必須做的事情。完成我們的 Node-webkit 應(yīng)用程序的打包步驟如下:

步驟 1:將 sample-app 目錄下的所有文件添加到一個(gè) zip 格式的壓縮文件 sample-app.zip 中,請(qǐng)確認(rèn) package.json 在這個(gè) zip 文件中處于跟目錄的位置;

步驟 2:將 sample-app.zip 重命名成 sample-app.nw;

步驟 3:在命令行中運(yùn)行 nw sample-app.nw,確認(rèn)能正確運(yùn)行;

.nw 文件就是 Node-webkit 最基本的發(fā)布格式。如果您有需求需要將應(yīng)用程序打包成.exe 或.app 等可執(zhí)行文件的格式,您可以參閱Node-webkit 打包指南了解更多打包相關(guān)的詳細(xì)內(nèi)容,以達(dá)到您的目標(biāo)。

結(jié)束語(yǔ)

隨著 HTML5 的日趨成熟和廣泛應(yīng)用,基于 Web 技術(shù)的軟件開(kāi)發(fā)已經(jīng)不甘心局限于傳統(tǒng)概念的網(wǎng)頁(yè)開(kāi)發(fā),它們的觸角已經(jīng)快速伸向了各個(gè)軟件開(kāi)發(fā)領(lǐng)域,比如 PhoneGap 移動(dòng)應(yīng)用開(kāi)發(fā), Adobe Air 應(yīng)用開(kāi)發(fā)等等,讓 HTML,CSS,JavaScript 這些技術(shù)擁有了跟多新的表現(xiàn)力以及更強(qiáng)的生命力。深度挖掘我們已經(jīng)掌握的知識(shí)和技能,讓我們的工作變得更有生產(chǎn)力和更有趣。

回頁(yè)首

下載

描述名字大小
示例代碼sample-app.zip5KB

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多