NW.js

Posted by huangqing on April 22, 2017

NW.js

特别说明

花了一天的时间学nw.js,可这个nw.js安装包和npm下载就是无法下载成功,网站也老是连不上。

Inter的开源项目还是不行啊,果断转electron,vscode是用这个做的,nw.js就是个坑。

nw logo node-webkit is renamed NW.js

github

wiki

Official site:

Official documentation:

nw-sample-apps

npm nw

Hybrid 应用

  • 支持用HTML5, CSS3, JS和WebGL来写应用程序,包括桌面端和移动端

  • 完全支持Node.js APIs和所有的第三方模块

  • 性能也不会很差,对于轻量级的应用足够了

  • 对应用进行打包和发布十分简单,也就是说写一份代码很容易移植到不同的平台(包括主流的Linux, Mac OS X 和 Windows)

  • 控制浏览器和浏览器版本(你知道你的应用是调用的什么浏览器)。NW.js hybrid 应用使用 Chromium 来显示— 这是一种开源浏览器,也是 Google Chrome(谷歌浏览器)的核心。因此,能在 Chrome 中运行的应用也能在 NW.js 中运行。

  • 控制视窗。例如,你可以定义一个固定大小,或者最小化/最大化的视窗。

  • 对本地文件的访问不会受同源策略的约束。如果你想在浏览器通过 XMLHttpRequest 打开一个不在相同目录的本地文件,请求会阻止。而 NW.js 应用中关闭了这样的行为。

API

  • 整合 Node.js

  • 访问剪贴板

  • 访问文件系统

  • 访问硬件(比如获取打印机列表)

  • 托盘图标

  • 自定义文件选择对话框

  • 整合 shell(在默认的资源管理器或浏览器中打开文件或 URL)

  • 自定义主窗口的选项(关闭按钮、菜单栏)和上下文菜单

  • 设置和获取绽放等级

原理

nw.js使HTML, CSS, JavaScript写的原本在浏览器上运行的程序,也可以在桌面端运行:

what_is_nw

怎么用nw.js完成任务?

how_package

npm nw installer

Install globally:

sudo npm install -g nw
nw ./my_nwjs_app

Install locally:

npm install nw
node_modules/.bin/nw ./my_nwjs_app

nw 模块安装在 /usr/local/lib/node_modules/nw 目录下,以后可以直接用 nw 命令来测试程序。

/usr/local/lib/node_modules/nw/nwjs/nwjs.app 是一个可用来打包应用的壳,与 Atom Shell 基本一致。

example

If you want a really quick example try this:

git clone https://github.com/zcbenz/nw-sample-apps && cd nw-sample-apps

npm init

npm install nw

“node_modules/.bin/nw” file-explorer

and now you should see a file explorer demo app.

项目结构

demo

首先,我们需要创建项的目录结构和文件:


nw.js-example/
├── src/
│   ├── app/
│   │  └── main.js
│   ├── assets/
│   │  └── icon.png
│   ├── styles/
│   │  └── common.css
│   ├── views/
│   │  └── main.html
│   └── package.json
└── package.json

说明:

src/ 应用程序源文件。

src/app/ JavaScript 文件。

src/assets/ 图片,在我们的例子中只有 icon.png 文件,它将作为一个窗口图标来显示。

src/styles/ 通常包含 SCSS 或 LESS 文件,在我们的例子中,仅仅是一个简单的 CSS 文件。

src/views/ 包含 HTML 视图文件。

src/package.json NW.js 应用程序清单文件(参考清单文件格式),我们也可以在这个文件中为应用程序指定特殊的依赖项。

package.json 是一个 npm 包文件,我们用它来构建工作流,也可以指定特殊的依赖,这在实际的 NW.js 应用程序中不是必须的,例如根据依赖构建。

创建清单文件

现在,我们已经创建了项目结构和文件,可以从 NW.js 的清单文件 src/package.json 开始了。

根据文档,这个文件基本上仅需要两个属性:name,一个应用程序名称,和 main,一个作为入口的 HTML 文件的路径。

但是我们需要添加更多信息,如窗口的图标的路径,以及最小宽度和高度,以确保用户不会看到任何奇怪的事情:

{
  "name":"nw.js-example",
  "main":"views/main.html",
  "window":{
    "min_width":400,
    "min_height":400,
    "icon":"assets/icon.png"
  }
}

应用程序在开始运行后,将打开 src/views/main.html,main 的路径是以清单文件(manifest file)为参考的相对路径。

创建主视图

创建 thesrc/views/main.html 文件。因为它是我们应用程序的入口点。文件内容如下:

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <title>NW.js-example | main</title>
    <link rel="stylesheet" href="../styles/common.css">
</head>
<body>
    <h1>Hello World :-)</h1>
    <script src="../app/main.js"></script>
</body>
</html>

安装 NW.js

现在我们创建了 NW.js 项目,包括清单和主视图。

最终我们需要一个方法直接在开发中运行 NW.js,并通过构建过程生成可运行于多个系统的本地应用。

为达此目的,我们需要两个包:

nw (开发)

nw-builder (生产)

cnpm install nw nw-builder --save-dev

它们与我们的应用功能无关(使用它们只是为了开发和生产目的),在根目录下的 package.json 中创建 devDependencies 配置,加入它们。这个配置与必须的 name 和 version 字段并列:

{
  "name":"nw.js-example",
  "version":"1.0.0",
  "devDependencies":{
    "nw":"^0.18.2",
    "nw-builder":"^3.1.2"
  }
}

现在只需要在项目的根目录下运行下面的命令来安装 devDependencies:

$ npm install

## 打包和发布 How to package and distribute your apps

在 package.json 中加入 npm 脚本来让打包变得简单。

npm 脚本在右边定义要运行的 CLI 命令,在左边定义它的快捷方式,然后允许我们通过 npm run 来运行指定的快捷方式。

现在添加两个脚本,一个用于开发,一个用于生产:

{
  "name":"nw.js-example",
  "version":"1.0.0",
  "devDependencies":{
    "nw":"^0.18.2",
    "nw-builder":"^3.1.2"
  },
  "scripts":{
    "dev":"nw src/",
    "prod":"nwbuild --platforms win32,win64,osx64,linux32,linux64 --buildDir dist/ src/"
  }
}

直接运行 NW.js

直接运行 NW.js 应用,只需要这个命令:

$ npm run dev

这个快捷方式会调用我们定义在 script 下 dev 对应的命令以使用 nw 包。开发机器上直接打开一个新窗口,显示着 src/views/main.html。

生产构建

要进行生产构建需要使用 nw-builder,它支持针对 Windows、Linux 和 macOS 进行输出。

在我们的例子中,我们会针对所有这些平台打包,并且包含32位和64位版本。

对于 macOS 来说,目前只能在以前的模式下构建 32位的版本。(参阅 GitHub 上的这个 issue。)所以,我们只构建64位版本。

运行如下命令进行生产构建:

$ npm run prod

和直接运行 NW.js 一样,它也使用我们定义在 scripts 中的 CLI 命令。

nw builder

完成之后,看看你的 dist/ 目录,就像这样:

dist/
└── nw.js-example/
    ├── linux32/
    ├── linux64/
    ├── osx64/
    ├── win32/
    └── win64/

测试和调试

手工测试

既然 NW.js 是基于 Chrominum 的,那么它的手工测试和 Chrome 一样简单。如果你遇到一个BUG——可视效果或者功能性的——你都可以通过快捷键F12或者下面的程序打开开发者工具:

nw.Window.get().showDevTools();

注意这需要SDK build flavor[译者注:flavor 可以理解为插件或者功能扩展]。

如果你想在生产构建的时候去掉开发者工具,你可以使用另一个flavor或者直接阻止F12事件。

调试

自动化测试

自动化的单元测试广泛用于确保不同的实现能正确工作,这避免了总是进行手工测试。

karma Jasmine

如果你的应用不使用 NW.js API 提供的特有方法,理论上来说你可以停留在一般的Web应用工作流上——例如,把Karma作为一个运行器与作为框架的Jasmine联合使用。

但是如果你使用 NW.js API 特有的方法,你需要在 NW.js 应用中运行测试,这才能确保使用到的 API 方法存在。 一种方法是使用 NW.js 的 Karma 启动器插件,比如 karma-nodewebkit-launcher。 它和其它浏览器的 Karma 启动器插件一样:在 NW.js 容器中打开应用并进行检查,完成之后再自动关闭应用。

不过既然 NW.js 不是 headless(就像 PhantomJS 那样的)[译者注:Headless 浏览器就是没有 GUI 的浏览器], 它总是需要显示出来。 换句话说,它不能在纯 CLI 服务器上运行测试。 幸运的是,这种情况下可以使用 Xvfb 来模拟显示。在 Jenkins[译者注:一个持续集成引擎]中,你需要安装 Xvfb 插件。更多信息参阅 GitHub 上的这个讨论。

打包(原始方式)

Win为例,只需要三步即可:

  • 将所有工程文件,放在一个文件夹下,确保package.json在根目录,然后压缩为.zip格式,并将压缩文件的后缀由.zip改为.nw

  • nw.js的环境目录下执行copy /b nw.exe+you_nw_name.nw you_app_name.exe (这一步之后,就可以在生成的目录中直接运行you_app_name.exe,它依赖同目录下的一些其他库);

  • Enigma Virtual Box将you_app_name.exe和依赖的库打包到单个exe文件中,这样我们的应用在没有任何编程环境的win机器上都可以运行。

参考

Building a Cross-platform Desktop App with NW.js

使用 NW.js 构建跨平台桌面应用程序

electron

Karma

Jasmine