BT

您是否属于早期采用者或者创新人士?InfoQ正在努力为您设计更多新功能。了解更多

使用node-webkit构建桌面应用程序(一)

| 作者 邱俊涛 关注 0 他的粉丝 发布于 2015年5月14日. 估计阅读时间: 18 分钟 | ArchSummit社交架构图谱:Facebook、Snapchat、Tumblr等背后的核心技术

Web前端的现状

目前Web前端的现状较之5~6年前,简直不能同日而语:从所使用的技术、工具、框架到开发一个产品所需要付出的工作量,从前端开发从业人员的数量到Web应用的数量,从企业对于Web前端的重要程度的认识到Web实际上为企业带来的回报,一切都有了翻天覆地的变化。

借助HTML5+CSS3的普及,加上一些开箱即用的CSS框架(如bootstrap,foundation等)支持,人们已经可以非常容易地从零开始搭建一个Web应用的前端。一个在UI方面非常业余的程序员也可以很快做出一个像模像样的用户界面。而另一方面,基于操作系统原生API,要想设计并实现一个桌面应用,需要的付出则远远超过同水平的Web界面。

Webkit浏览器内核

Webkit作为最受欢迎的浏览器内核,自然有非常多的port。比如GTK+对它的port – WebkitGTK,以及构建在WebkitGTK之上的Python的bind(即Python对WebkitGTK的本地动态库的一个包装,可以使用Python的语法来编写代码,但是底层仍然使用WebkitGTK自身的动态库)。使用WebkitGTK的Python版本,开发人员可以用HTML+CSS来开发应用,然后写一点Python脚本,最后将其运行在桌面上。

这里有个早期的例子来教你如何写一个所见即所得的编辑器。桌面应用开发中,用户界面的复杂性一直是一个难题,而这种方式可以降低很多用户界面开发的复杂性,将界面开发交给更加灵活、更加容易编写和调试的方式——HTML+CSS。

这种模式下基本的开发流程是编写一个HTML页面(作为程序入口),然后在这个页面上引入额外的CSS(界面风格)和JavaScript(动作),然后将这些资源交给工业级浏览器内核Webkit来渲染 。 这个过程和在浏览器中访问该文件并无二致,但是有两个额外的好处。

  • 页面运行在一个“桌面应用程序”中。

    没有地址栏,状态栏,菜单栏等,看起来更像是一个桌面应用。

  • 用户界面开发的复杂性被“外包”给一个更简单的环境。

    这就是传说中的混合(hybrid)开发模式,比如现在移动开发中的cordova就是采用这种模式,使得本来被视为天堑的原生的用户界面开发变为坦途。

node-webkit简介

node-webkit是一个基于chromium和node.js的应用程序开发工具。它不但支持使用传统的HTML5+CSS3+JS方式来开发应用程序,还支持无缝地与Node.js集成,也就是说,所有的Node支持的与操作系统交互的功能,如网络连接,文件系统,操作系统资源访问等,以及Node之上的第三方库都可以在node-webkit中进行使用。

更好的是,node-webkit是一个跨平台的工具,你可以使用它构建出运行在Mac OS,Linux以及Windows下的应用程序。应用程序通过Node.js来进行与系统相关的访问,而用HTML5+CSS3进行用户界面部分的设计。

node-webkit未必是未来桌面应用的唯一方式,但是却是一个非常好的选择,特别对于已经熟知Web前端开发技术栈的众多开发者来说,无需学习一门新的语言,一切都在很大程度上得到了简化。

第一个node-webkit应用程序

开发node-webkit应用程序非常简单。在这里下载系统对应的版本。并确保对应的二进制文件(nwnw.exe)在系统的PATH之中。

创建一个新的目录,然后在该目录中创建一个package.json文件和一个index.html文件:

$ mkdir -p hello-node-webkit
$ cd hello-node-webkit
$ touch package.json index.html

package.json文件的内容如下:

{
    "name": "hello-node-webkit",
    "version": "0.1.0",
    "main": "index.html"
}

index.html文件的内容如下:

<html>
<head>
    <title>Hello node-webkit</title>
</head>
<body>
<div>
    <h1>Hello node-webkit</h1>
</div>
</body>
</html>

然后将这两个文件打在一个zip格式压缩包中:

$ zip -r hello-node-webkit.zip *

然后将这个文件重命名为hello-node-webkit.nw,最后使用node-webkit来启动这个应用程序。

$  ~/Tools/node-webkit.app/Contents/MacOS/node-webkit hello-node-webkit.nw

添加外部JS/CSS

接下来我们为这个页面添加一些外部的引用:CSS/JavaScript文件。首先创建两个目录style和script,然后分别创建文件如下:

 ├── index.html
 ├── package.json
 ├── script
 │   ├── app.js
 │   └── jquery.min.js
 └── style
     └── style.css

其中,style.css定义了h1的简单样式:

 h1 {
     font-size: 20px;
     color: #999999;
 }

而app.js则注册了一个简单的事件处理器:

 $(function() {
     $("h1").on("click", function() {
         alert("Heading 1 is clicked");
     });
 });

此时的index.html修改如下:

 <html>
 <head>
     <title>Hello node-webkit</title>
     <link rel="stylesheet" type="text/css" href="style/style.css">
 </head>
 <body>
 <div>
     <h1>Hello node-webkit</h1>
 </div>
 <script type="text/javascript" src="script/jquery.min.js"></script>
 <script type="text/javascript" src="script/app.js"></script>
 </body>
 </html>

还是按照上一小节的命令完成打包,改名,启动之后。点击h1元素时,会弹出对话框如下:

在这个例子中,我们使用了外部的css文件来添加样式,还引入了jQuery作为访问DOM元素的工具,最后还使用了一段调用jQuery的JavaScript代码。

构建脚本

你可能已经注意到了,使用node-webkit开发非常方便。但是这一系列的动作(修改HTML+CSS,压缩打包,改名,启动)等有一部分重复工作,我们可以将其自动化。

好在已经有了一个很好用的grunt的插件:grunt-node-webkit-builder,这个插件可以帮助我们自动执行压缩打包这些动作。

$ npm install grunt-node-webkit-builder

然后定义一个Gruntfile.js,这个文件中指定源文件(所有的HTML,JavaScript代码,CSS文件)所在目录,目标文件所在目录,需要构建的应用程序指定的操作系统平台等:

module.exports = function(grunt) {
     grunt.initConfig({
         pkg: grunt.file.readJSON('package.json'),
         nodewebkit: {
             options: {
                 platforms: ['osx'],
                 buildDir: 'builds',
             },
             src: ['app/**/*']
         }
     });
 
     grunt.loadNpmTasks('grunt-node-webkit-builder');
     grunt.registerTask('default', ['nodewebkit']);
 };

这样,我们修改之后,就可以直接执行:

$ grunt

进行打包了。比如在Mac下,构建出来的应用位于builds/<app-name>/osx目录下,要启动该应用只需要在命令行输入下列命令:

$ open builds/hello-node-webkit/osx/hello-node-webkit.app

或者在Finder中双击打开即可。

可以看到上例中的应用程序还有浓重的浏览器痕迹,比如地址栏,刷新按钮,甚至还有一个DevTools的按钮。

我们可以通过修改package.json来指定:

{
     "name": "hello-node-webkit",
     "version": "0.1.0",
     "main": "index.html",
     "window": {
     "toolbar": false,
         "width": 800,
         "height": 600
     }
 }

这样的界面就更像是一个桌面应用了:

到目前为止,这个小的应用程序并没有什么有趣的特性,用户界面也毫无美感,但是有了这些基本知识和工具之后,我们就可以开始更进一步的开发了。除了使用既有的CSS框架来完成用户界面的美化,我们还会使用node.js访问系统资源来构建真实的应用程序。

一个实际的小例子

gist是一个非常好用的代码片段管理工具,Github的用户可以将自己的代码片段保存为一个gist,每个gist中可以包含若干个文件,每个gist可以通过一个唯一的URL指定,比如:https://gist.github.com/abruzzi/44550f2b4cb812b19701

我们这里将开发一个具体的小例子:通过Node.js请求到一个gist,并将其中的所有文件名都列出来,最终的结果看起来是这样的:

首先我们需要安装一个npm的包:gisty,这个包提供的API可以方便地获取gist。安装命令如下:

 $ cd app/
 $ npm install gisty

注意此处的app目录为我们的应用目录,其中包含了HTML文件,CSS,及JavaScript等,在这个目录中执行npm install会创建一个node_modules目录,gisty会安装在这个目录中。

然后我们修改scripts/app.js,内容如下:

 var Gisty = require('gisty');
 
 $(function() {
     var gist = new Gisty({
         username: 'abruzzi'
     });
 
     gist.fetch('44550f2b4cb812b19701', function(error, gist) {
         if (error) {
             throw new Error(error);
         }
         buildGistItem(gist);
     });
 
     function buildGistItem(gist) {
         var gists = $("#gists");
 
         for (filename in gist.files) {
             var gistItem = $("<li></li>");
             gistItem.text(filename);
             gistItem.appendTo(gists);
         }
     }
 });

注意此处的require语句,这正是使用node-webkit的强大之处:可以在“前端”代码中使用“后端”代码。gisty需要指定用户名来创建一个Gisty对象, 然后在这个对象上调用fetch方法,并将gist的ID传入来获取gist对象。gist对象上有files属性,其中保存该gist对应的文件名和文件内容。

使用gisty的API获取到gist列表之后,将其插入在页面元素上。HTML页面上声明了一个ID为gists的ul,然后在app.js中动态的创建li来添加到该ul上。

<html>
 <head>
     <title>Hello node-webkit</title>
     <link rel="stylesheet" type="text/css" href="style/style.css">
 </head>
 <body>
 <div>
     <h1>Gist #44550f2b4cb812b19701</h1>
 </div>
 <div>
     <ul id="gists"></ul>
 </div>
 <script type="text/javascript" src="script/jquery.min.js"></script>
 <script type="text/javascript" src="script/app.js"></script>
 </body>
 </html>

作者简介

邱俊涛,ThoughtWorks咨询师,喜欢技术,崇尚轻量级的开发/工作方式,痛恨冗长的会议和各种繁琐的流程。他还是《JavaScript核心概念及实践》一书的作者,个人博客是http://icodeit.org,博客上经常会有各种技术的分享。


感谢张凯峰对本文的策划,丁晓昀对本文的审校。

给InfoQ中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家通过新浪微博(@InfoQ@丁晓昀),微信(微信号:InfoQChina)关注我们,并与我们的编辑和其他读者朋友交流。

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

赞一个 by tiyo leung

不错,项目正想这么做,跨平台如何?

Re: 赞一个 by li kun

node-webkit是一个跨平台的工具,你可以使用它构建出运行在Mac OS,Linux以及Windows下的应用程序。

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

2 讨论

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT