分享

使用 Dojo 和 node

 oskycar 2017-03-01

在 IBM Bluemix 云平台上开发并部署您的下一个应用。

开始您的试用

前言

作为一名 Web 前端工程师,我们的工作在大多数情况下,就是与各种浏览器打交道,开发以页面为主的 Web 应用程序。为此,非常的熟悉 HTML、CSS、JavaScript 以及各类主流的 JavaScript 工具库,比如 Dojo、jQuery、YUI 等。但是,浏览器的安全沙盒把我们限制在了一个小小的圈子里,我们不能用 JavaScript 访问操作系统的本地文件系统,不能发起一个 Socket 请求, 不能获取 CPU 和内存的使用情况, 也不能访问关系型数据库或者 NoSQL 数据库。

您是否一直在憧憬着,某一天,您使用着您最拿手的前端技能,来开发那些本来由 Java,、C++等语言所开发的桌面应用程序呢? 很幸运,答案是肯定的!Node-webkit 这个开源项目的出现,为 Web 前端开发人员提供了一个新的舞台;它更给我们带来了一个实际的价值,让我们现有的 Web 应用,可以更方便的移植到我们的桌面上来,加以本地功能的扩展,获取更大的用户体验度。

回页首

Node-webkit 架构概述

Node-webkit 是项目托管网站 Github 上一个非常热门的开源项目,它基于著名的浏览器开源项目 Chromium 和服务器端 JavaScript 实现 Node.js 的一个应用程序运行时环境。假如您对它还没有任何头绪,不妨可以这样来想象一下这个运行时环境:它是一个支持 HTML5 特性的全功能 Web 浏览器, 并且它没有安全沙盒的限制, 我们可以用 JavaScript 来操作 HTML DOM 对象,也可以来调用操作系统的本地资源。

图 1. Node-webkit 概览
Node-webkit 概览

我们来通过一段最简单的代码,窥探一下 Node-webkit 的样子:

清单 1. 简单示例代码<!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 代码运行结果
清单 1 代码运行结果

安装

有两种方式可以实现 Node-webkit 的安装:第一种是从其项目主页面, 下载源代码,然后自行编译安装;或者, 我们为了方便起见, 可以直接下载它提供的编译好的二进制可执行文件, 目前支持三个操作系统平台:Windows、Linux 以及 Mac。

我们的教程在后文中都将主要以 Windows 为例,其他平台请具体参考 Node-webkit 的项目文档。以下是安装的具体步骤:

  1. 将下载的二进制文件放到一个文件夹下,例如 C:\Program Files\node-webki
  2. 在 Windows 的环境变量 PATH 中,添加路径 C:\Program Files\node-webki

至此, Node-webkit 安装就算完成了。我们可以在命令行中运行 nw,如果您看到如下窗口出现, 则表示 Node-webkit 在您的计算机上已完全安装成功:

图 3. 成功运行 Node-Webkit 的界面
成功运行 Node-Webkit 的界面

创建第一个 Node-webkit 应用

复杂的应用从 Hello World 开始!让我们一步一步来建立我们第一个最简单易懂的 Node-webkit 应用程序。

首先,在您计算机上任意目录下,建立一个命名为 sample-app 的文件夹,它将被用来存放我们的示例应用程序代码和其他所有需要的资源文件;

然后在 sample-app 文件夹下,预建立一些空的子文件夹,用来合理的存放不同类型的文件;

最后,建立两个文件:index.html 和 package.json。至此,sample-app 文件夹中看起来应该是这样的一个结构:

图 4. sample-app 包含的文件和目录
sample-app 包含的文件和目录

对这样一个目录结构,是不是觉得非常熟悉?没错,它就是一个标准的 Web 工程的目录结构,因为 Node-webkit 的开发继承了 Web 前端开发的一切,所以您所掌握的 Web 开发经验将使您更快速的掌握它。

下一步,我们来看一下 index.html 和 package.json 这两个重要文件中的内容:

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

它将是我们这个应用程序的入口,现在它包含的仅仅是一段最简单的 HTML 文本,显示了一个"Hello World!"的问候,我们将在后文中一步步的充实它的内容。

清单 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 的应用描述文件,一个完整的 node-webkit 应用程序必须包含这样一个文件。它用于定义应用程序的基本信息以及运行相关的参数,比如名称、介绍、入口文件名称以及应用程序窗口的各项配置,如窗口的显示尺寸、显示位置、是否显示工具栏等等。您可以阅读 Node-webkit 描述文件格式来获取更多相关信息。

运行

以上这些文件构成了一个最简单基本的 node-webkit 程序。我们非常清楚如何让一个 HTML 文件在浏览器中运行起来,但是,在 node-webkit 环境下,如何让它运行起来呢?

打开您的命令行工具,进入 sample-app 所在的目录,然后执行命令:nw sample-app

成功运行中的窗口界面如下所示:

图 5. sample-app 运行结果
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 组件来创建和布局整个应用的界面。下面是一部分关键代码:

清单 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="本地功能调用示例">
      <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>

下面是实际的运行效果图:

图 6. 本地功能调用示例运行界面
本地功能调用示例运行界面

本地功能调用

上面示例程序的第一个选项卡,展示的是一个调用并展示计算机系统信息的功能。由于 Node-webkit 内置了 Node.js,所以调用计算机本地功能和资源的工作主要都是通过它的 API 来完成。我们的应用使用了 Node.js 的 OS 模块,用以读取计算机的基本信息:

清单 5. 读取本地系统信息
// 加载 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
    };
}

读写本地文件系统也是桌面应用程序经常会用到的功能,以下代码段展示如何完成此任务:

清单 6. 读写本地文件
  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 数据:

图 7. 远程数据访问示例运行界面
远程数据访问示例运行界面
清单 7. 读取远程 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 请求,与远程服务器进行数据交互。

清单 8. 使用 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"选项卡,出现的就是一个代码调试工具:

图 8. Node-webkit 调试工具界面
Node-webkit 调试工具界面

通过该调试工具,我们可以选择需要调试的代码文件,对代码行设置断点,设置要监视的变量等等,然后进行单步调试,并获取调试结果信息。

打包与发布

在一个应用程序开发完成后,将其打包成方便于发布的格式是我们必须做的事情。完成我们的 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.zip5KB

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多