本篇将介绍开发者在使用node-webkit中可能会遇到的故障。
(1)Audio故障
媒体文件在node-webkit开发中应该有用到,常遇到的问题是MP3格式和其他非自由媒体格式的编码器问题。详细请查看:
https://github.com/nwjs/nw.js/wiki/Using-MP3-%26-MP4-%28H.264%29-using-the--video--%26--audio--tags.
(2)WebGL故障
使用WebGL不可缺少来自DirectX 的两个DLL动态链接库,或者你的显卡驱动/程序不能再谷歌核心的黑名单中,详细请参考:
https://github.com/rogerwang/node-webkit/issues/185
有时候CSS不能正确的显示,比如说-webkit-transform:translateZ(-1000px);这可能就是WebGL的故障的原因了。
(3)node-webkit运行故障
node-webkit无法再你的电脑运行,可以参考:
https://github.com/nwjs/nw.js/issues/136
https://github.com/nwjs/nw.js/issues/770
(4)编程陷阱-Console and timers
Node.js 和 Chromium 各自有实现 setTimeout 和 console的方法。通常我们使用的console是由Chromium 实现的。因为可以在浏览器的开发者工具中查看到打印信息。
相对于 setTimeout 方法, WebKi实现的方法是window.setTimeout,Node实现的方法是global.setTimeout。
如果浏览器正在轮询渲染界面,这时建议使用global.setTimeout,因为它的准确度比window.setTimeout要高。
(5)编程陷阱-Transfer objects between window and node
当你在<script>标签使用require方法时,很可能会诱惑你去做一件事情:把所有的JavaScript库都包装进第三模块并使用require方法去调用。大多时候这种做法是没有问题的,但是针对某些例子这却是一个非常错误的方法。
Contexts
首先,我有必要介绍一下context的概念。所有的js变量都存在于js context中,而且所有的js context在<script>中都有一个根变量且能被其调用的。
在浏览器的世界里,你打开的所有窗口都有一个window对象,而且全局变量会存在于你所创建的window中,所以不同窗口的变量并不会冲突。这是因为所有的浏览器窗口都有独立的js context。而window就是调用这些js context的全局根变量。
在Node.js世界里,事情就更加简单了。每一个模块都有自己独立的context(如require(fs)就是其中一个模块),所以模块之间的变量并不会冲突。如果你想要在两个context中传递参数,你必须使用require 和 export ,这是Node.js的系统的基本方法。
与webkit相同,Node.js的context之间也有一个全局根变量如global ,所有模块的context都存在于global的context中。所以像元素global、process 和 console都可以在模块间通用。
Bridge between window and node
为了实现window和node互相调用,node-webkit做的事情,就是在window context创建时,利用node context给window context创建成员变量。如window context中需要调用jQuery,则添加语句
global.$ = $;
require方法是使用node.js的基本方法,如果需要调用某个模块,则使用require(module),这时,node-webkit将会执行node.js调用的的模块代码,并且能够获得该模块代码的window context。
<script src="js/jquery-1.8.0.js"></script>
<h1 id="content">Hello GUI菜单</h1>
<script>
//在global定义$($就是jQuery),会在hello.js中用到
global.$ = $;
global.mm = "mm";<span style="white-space:pre"> </span> require('./js/hello.js');
console.log(window.hh);
</script>
window.hh = "hello world!!";
//使用到jQuery
$('#content').text('Modifying DOM elements');<span style="white-space:pre"> </span> console.log(global.mm);
Operations that require window context
调用require请求的window context中的方法,代码如下:
<script src="js/jquery-1.8.0.js"></script>
<script>
global.window = window;
var cache = require('./js/cache');
console.log(cache);
</script>
// In cache.js
exports.get111 = function (key, callback) {}
(注)如果你想把js编写成一个类库让require直接调用(隐藏地址),如一个node context相对于多个窗口调用,请参照下面节内容:
nw.js node-webkit系列(15)如何使用内部模块和第三方模块进行开发
(6)打开app,窗口内显示找不到文件
有一种情况是,因为app路径带空格或者特殊字符,nw执行程序无法解析app路径以致无法打开app的情况,如Windows XP系统的桌面目录是C:\Documents and Settings\,当app在XP系统的桌面将无法被nw执行程序识别。针对这种情况,我们可以使用隐藏目录,只需要在package.json文件里修改如下即可:
{
"main": "app://AppName/index.html"
}
(注):AppName可以取任意值,这里但是app://是必须的。
(7)在Windows系统上无法使用WebGL
只要在nw根目录上添加这两个文件即可:D3DCompiler_XX.dll and d3dx9_XX.dll
(8)node.js在nw上如何写服务端脚本
详细信息请查看:https://github.com/nwjs/nw.js/wiki/About-Node.js-server-side-script-in-nw.js
(9)nw的require()方法和RequireJS的require()冲突怎么办?
默认情况下系统使用的是nw的require()方法,针对这个问题,现在的RequireJS已经新增了一个调用名称requirejs,可以用此名称防止与nw的require()方法冲突。