转载

nw.js桌面软件开发系列 第0.1节 HTML5和桌面软件开发的碰撞

0.1 HTML5 和桌面软件开发的碰撞

当我们谈论桌面软件开发技术的时候,你会想到什么?如果不对技术本身进行更为深入的探讨,在我的世界里,有这么多技术概念可以被罗列出来(请原谅我本质上是一个 Windows 程序员的事实)。

操作系统 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 start

代码清单 0-1  汇编 MessageBox

在代码清单 0-1 中,通过汇编调用 MessageBox Api 来呈现一个简单窗口程序。

代码清单 0-1 的运行结果如下:

nw.js桌面软件开发系列 第0.1节 HTML5和桌面软件开发的碰撞

0-1 代码清单 0-1 运行结果

同样的,我们使用 c/c++ 来调用这样一个 win32 API ,代码可能是如下这样的:

#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 运行结果如下图:

nw.js桌面软件开发系列 第0.1节 HTML5和桌面软件开发的碰撞

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 平台。

nw.js桌面软件开发系列 第0.1节 HTML5和桌面软件开发的碰撞

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 控件强依赖系统安装的浏览器,微软的浏览器又和系统依赖过强,导致控件在不同的客户系统上的展现行为也会有差别。当然离跨平台又远了一步。

nw.js桌面软件开发系列 第0.1节 HTML5和桌面软件开发的碰撞

0-4 WebBrower 控件示例

同时我们也应该看到控件的方式虽然精简了浏览器功能,但是也扩展了 Web 应用的能力,控件是可以和调用者进行通信的,也就意味着控件是可以通过“后端代码 访问本地资源的。但是在这一方面并没有长足的发展。同时 Google 开源了 Chromium 项目,基于 C++ CEF 项目,将 Chromium 进行改造使之成为一个控件,相对于微软的 WebBrowser 控件,这一举措意义很大。 Chromium 是开源的,可以更好的和调用代码进行交互,甚至可以扩展 javascript 接口,使之可以调用操作系统资源。

随着 web 应用的发展,浏览器由于本身的定位和安全特性的限制,很多需要和客户端交互的功能无法完成,于是出现了浏览器扩展的概念,但是扩展也不是无限制的。这方面微软对浏览器的扩展最为粗暴,它直接支持 Activex 控件,几乎可以无限制访问本地资源,但是同时也打破了浏览器安全特性,这也是一直到现在很多银行的网银只支持 IE 浏览器的原因。其他浏览器也在这一方面做出了妥协,浏览器的 Js 或者本地扩展功能都被支持起来,不过仅仅是妥协而已,因为浏览器的使命不是开发桌面应用。

在这期间,微软做了很大的尝试,首先是基于 .NET 框架的 WPF ,微软推出了 XAML 语言,全新的声明性语言,想让开发者像写 HTML 一样编写软件的界面和交互,这不正是广大开发者的心声吗?可以说 WPF 是很成功的产品,使用 WPF 我们已经可以能够开发出炫酷的桌面软件了。但是从跨平台性角度讲,受 .NET 本身的制约,另外并没有斩掉开发者和设计师之间的鸿沟。它仍然是传统桌面软件的延伸,面向的是仍然是后端开发人员,前端开发、交互设计师、 UI 设计师并没有被引入进来。

nw.js桌面软件开发系列 第0.1节 HTML5和桌面软件开发的碰撞

0-5 WPF

微软在这个方向上并没有止步,随着 windows8 操作系统的推出, Windows Runtime 浮出水面。微软运行使用 HTML5 Javascript 开发 WinRT 的应用,看起来非常美好的一件事情,但是在微软手里却多出了很多遗憾。虽然我们可以使用 HTML5 Javascript 开发应用,甚至在移动端,但是这些应用只能运行于 Windows Runtime 环境,连 Windows8 的传统桌面环境都不可以,更不要谈什么跨平台了。原因是微软直接扩展了 Javascript 类库,映射到 Windows Runtime 的底层 API 上。

nw.js桌面软件开发系列 第0.1节 HTML5和桌面软件开发的碰撞

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 的基础类库还没有办法和其他后端语言相比,但是语言的功能本质发生了变化,在一个方向上了)。

nw.js桌面软件开发系列 第0.1节 HTML5和桌面软件开发的碰撞

0-7 Html5 新特性

nw.js桌面软件开发系列 第0.1节 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 容器的方式嵌入到桌面应用的工程中。

项目目前处于停滞状态。

nw.js桌面软件开发系列 第0.1节 HTML5和桌面软件开发的碰撞

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 以外,还可以进行跨域访问等操作。

nw.js桌面软件开发系列 第0.1节 HTML5和桌面软件开发的碰撞

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 开发。

nw.js桌面软件开发系列 第0.1节 HTML5和桌面软件开发的碰撞

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 调用呢?

nw.js桌面软件开发系列 第0.1节 HTML5和桌面软件开发的碰撞

0-12 .NET Core 5

在将近两年的 HTML5 桌面软件开发过程中,虽然整体过程是愉快的,但是不可避免的遇到很多问题甚至是无法克服只能绕过的“坑”。两年里我主要使用的框架是 nw.js( 那时还叫 node-webkit) ,也在博客上零星的写了一些 nw.js 入门的教程,虽然不成体系,文章数量也不多,但是仍然是国内最全的教程了。 nw.js 也在不断的迭代更新,于是我产生了重新动手,写一本完整的书来记录两年来的开发经验,这里面重要的不是 nw.js 如何使用,重要的是使用 Html5 node.js 开发桌面应用我们应该怎么做,会遇到什么问题,如何去解决。

在下一节,会给大家阐述下 nw.js 的基本实现原理。

正文到此结束
Loading...