NodeJS 使前后台语言上得到了统一,给 “不就是做网站的” 那些人带来了福音,其基于事件驱动的处理机制更是在并发/CPU 密集型计算上大展身手。
虽然我不怎么做 UI 程序,但对于每一种语言却爱关心它做 GUI 程序是否得心应手。像 Java, Groovy, Scala 等写桌面程序也不怎么样,JavaFX 似乎显现出苗头来,因为 JavaFX 也支持 CSS 了,但布局仍然老套。
HTML + CSS + JS 做页面布局等样式控制有种与身俱来的优越感,于是 NodeJS 的世界里便产生了 Node-Webkit(已更名为 NW.js) 和 Atom Shell,它们各自的代表作有 LightTable 和堪与 Sublime 相媲美的 Atom 编辑器。
Node-Webkit(NW.js) 有两个context,node context 和 web context, 应用入口是一个 html 文件。而在 Atom Shell 只维持一个context,入口是一个 JS 文件,浏览器的启动控制要亲自动手。
完了基本的介绍后,回到原点,来看个 Atom Shell 的 Hello World 程序例子。
1. 前提条件
已安装了 NodeJS, 并且使用 npm install atom-shell -g 全局方式安装了 Atom Shell。这里以 Mac OS X 平台为例,Atom Shell 安装之后,可以直接执行 atom-shell 命令。可以查看下 atom-shell 执行命令在哪
$ which atom-shell
/usr/local/bin/atom-shell
$ ls -l /usr/local/bin/atom-shell
/usr/local/bin/atom-shell -> ../lib/node_modules/atom-shell/run.bat
居然在 Mac 下也用 run.bat 这样带混淆意义的扩展名。此时直接执行 atom-shell 能看到一个 Welcome to Atom Shell 的默认界面。
2. 建立文件目录
hello-atomshell/
├── index.html
├── main.js
└── package.json
package.json 内容为
1 2 3 4 5 |
{ "name" : "your-app", "version" : "0.1.0", "main" : "main.js" } |
main.js 内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
var app = require('app'); var BrowserWindow = require('browser-window'); var mainWindow = null; app.on('window-all-closed', function() { app.quit(); }); app.on('ready', function() { mainWindow = new BrowserWindow({width: 600, height: 200}); mainWindow.loadUrl('file://' + __dirname + '/index.html'); mainWindow.on('closed', function() { mainWindow = null; }); }); |
本文的代码内容来自 https://github.com/atom/atom-shell/blob/master/docs/tutorial/quick-start.md,删除了注释代码。app 就像是 MFC 的 theApp 对象,是个应用入口。
index.html 内容:
1 2 3 4 5 6 7 8 9 10 11 |
<!DOCTYPE html> <html> <head> <title>Hello World!</title> </head> <body> <h1>Hello World!</h1> We are using node.js <script>document.write(process.version)</script> and atom-shell <script>document.write(process.versions['atom-shell'])</script>. </body> </html> |
这是一个 HTML 文件,可以直接使用 Node 的 process 对象。
3. 运行程序
$ atom-shell hello-atomshell
直接指定应用的目录 hello-atomshell,看到
这样基本程序框架是完成了。深入些就是调动 CSS 来进行布局,以及应用 Node 来突破传统的 Web 沙箱限制了。现在发现程序图标菜单都是默认的,可以在打时进行定制。
4. 打包应用程序
比如在 Mac OS X 也可以打包成像 Atom.app 那样的程序,不管是 Node-Webkit 还是 Atom Shell 的独立程序,即使是一个 Hello World 应用包的大小也是惊人,好在现代磁盘空间不在乎。
仍然以 Mac OS X 平台为例,需先在 https://github.com/atom/atom-shell/releases 下载最新的 darwin-x64 的版本包,如当前为 atom-shell-v0.20.6-darwin-x64.zip。下后后解压得到其中的 Atom.app 目录,把前面的项目目录 hello-atomshell 整个拷入它的 Contents/Resources 目录中,并更名为 app。
采用下面的目录结构
Atom.app/
└── Contents
└── Resources
├── app
│ ├── index.html
│ ├── main.js
│ └── package.json
└── atom.icns
Atom.app 可以改成别的名,如 HelloAtomShell,程序图标是 atom.icns。在 Info.plist 文件中
HelloAtomShell.app/Contents/Info.plist
HelloAtomShell.app/Contents/Frameworks/Atom Helper.app/Contents/Info.plist
找到 CFBundleDisplayName, CFBundleIdentifier and CFBundleName 来定制程序的显示名,标识名和程序名称。
现在 Finder 中就可以直接双击 HelloAtomShell.app 启动应用了。
NodeJS 的项目一般都用 Grunt 来管理,同样像程序打包这么重要的事情可以用 grunt-build-atom-shell 来帮忙。同时自己的应用也能打成 app.asar 压缩包放在 Xxx.app/Contents/Resources 目录下。
参考:1. Atom Shell vs Node-Webkit
2. https://github.com/atom/atom-shell/tree/master/docs
本文链接 https://yanbin.blog/nodejs-atom-shell-gui-app-hello-world/, 来自 隔叶黄莺 Yanbin Blog
[版权声明] 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。
Atom Shell 现在又更名为 Electron(http://electron.atom.io/), 所以运行命令也变成了 electron hello-atomshell
谢谢楼上的评论,已拜读您的文章我所想的是基于事件机制,让任务能被分配到其他 CPU 或内核上执行从而提高 CPU 的使用效率。Nodejs 的单线程模型如果 Event Loop 越负荷运转就死翘翘了, Nodejs 编程时 Event Loop 一定得轻量级。找到一篇类似的文章 http://neilk.net/blog/2013/04/30/why-you-should-use-nodejs-for-CPU-bound-tasks/
其基于事件驱动的处理机制更是在并发/CPU 密集型计算上大展身手。 其实Nodejs应该是在IO密集型的场景上有优势,CPU密集型计算是Nodejs的软肋,infoQ上这篇文章支持我的这个观点: http://www.infoq.com/cn/articles/nodejs-weakness-cpu-intensive-tasks/ 如我的观点有不对希望楼主指出