nodejs 中调用java

java由于其历史悠久,有很多有用的jar包,nodejs作为比较新的平台,相比之下还是有所欠
缺的。本篇文章介绍如何在nodejs中调用java程序,这样既能用你熟悉的js语言,又能享用
java的成熟工具。

下面以nodejs中调用 yuicompressor.jar 这个jar包进行压缩的示例来说明node调用java的
完整过程——尽管yuicompressor.jar已经很大程度上被uglifyjs代替了。

类似的,这个例子也可以调用 google 的压缩工具 compiler.jar

windows 环境中 nodejs 调用 java

  1. 确保你已经正确的安装了java,你可以通过下面的代码来检查是否安装成功
java -version

若看到类似下面的截图,表示安装成功了
Alt Text

  1. 用nodejs封装cmdline下的命令

下载yuicompressor.jar ,建立一个测试文件test.js,内容随便写点什么

在windows命令行中,压缩这个js的命令是:

java -jar yuicompressor.jar test.js

上面的命令实际上完整的是(windows有个cmd.exe来完成实际的工作)

cmd /c java -jar yuicompressor.jar test.js

nodejs提供了spawn工具来执行外部程序命令,详见 nodejs文档

完整的代码如下

var spawn = require('child_process').spawn;


exe(["/c","java","-jar","yuicompressor.jar","test.js"]);
// 相当于在命令行下执行 cmd /c java -jar yuicompressor.jar test.js
// 也可以加入更多的参数

function exe(command){
    // windows下 
    var cmd = spawn("cmd",command);

    cmd.stdout.setEncoding("ASCII");
    cmd.stdout.on("data",function(data){
    console.log("------------------------------");
    console.log("exec",command);
    console.log("stdout:"+data);
    });

    cmd.stderr.on("data",function(data){
    console.log("------------------------------");
    console.log("stderr:"+data);
    console.log("------------------------------");
    });

    cmd.on("exit",function(code){
    console.log("exited with code:"+code);
    console.log("------------------------------");
    });
};

将上面的代码保存为 node-compress.js,执行即可

node node-compress.js

linux 版本

linux 调用java不用像windows 那样:

cmd /c java -jar yuicompressor.jar test.js

而是直接调用

java -jar yuicompressor.jar test.js

即可

所以完整的代码是:

var spawn = require('child_process').spawn;

exe(["-jar","yuicompressor.jar","test.js"]);
// 相当于在命令行下执行 java -jar yuicompressor.jar test.js

function exe(command){

    // linux下,不用 cmd /c java -jar yuicompressor.jar test.js,这种形式,直接
    // java -jar yuicompressor.jar test.js 即可
    var cmd = spawn("java",command);

    cmd.stdout.setEncoding("ASCII");
    cmd.stdout.on("data",function(data){
    console.log("------------------------------");
    console.log("exec",command);
    console.log("stdout:"+data);
    });

    cmd.stderr.on("data",function(data){
    console.log("------------------------------");
    console.log("stderr:"+data);
    console.log("------------------------------");
    });

    cmd.on("exit",function(code){
    console.log("exited with code:"+code);
    console.log("------------------------------");
    });
};

raphaeljs 在 IE8 下性能差的问题及解决方案

Raphaël 具有良好的兼容——IE能兼容到ie6,非常适合国情,但是情况正在发生变化,尤其是
在国外,考虑到IE9以及其他浏览器的份额,Raphaël 的作者推出了一个叫 Snap.svg
图形库,跟Raphaël 不同,Snap.svg完全是基于svg的图行库,少了些束手束脚。

不过在国内,ie6/7/8/仍然不可忽视,因此Raphaël 仍然是比较好的选择。

微软从IE9开始支持svg矢量图形技术,Raphaël 在 ie6/7/8 上使用的是专有的vml技术来模
拟svg的特性。

vml在IE8浏览器下性能非常之差

我们知道,直到IE9才支持svg,微软必须跟上开放标准的潮流,vml的没落就像很多IE其它专
有特性一样,渐渐被抛弃,到IE8最终发布的时候,对vml的支持已经非常不好了 [1]


“vml\:*”这个选择器被IE8认为不合法

并且,相比IE6/7,IE8下vml性能问题差了很多,可以看 stackoverflow上的一个用户测试

测试代码如下:

<script src="http://fiddle.jshell.net/js/lib/raphael-1.5.2-min.js"></script>
<div id="time-result"></div>
<div id="canvas"></div>
<script>
window.onload = function() {
    var timer = new Date();
    var paper = Raphael('canvas', 400, 400);
    var length = 25;
    for (var i = 0; i < 10; i++) {
        for (var j = 0; j < 10; j++) {
        paper.rect(length * i, length * j, length, length);
        }
    }
    $('#time-result').text('Rendered in ' + (new Date() - timer) + ' milliseconds.');
};
</script>

Raphael IE8 性能差的应对方案

通过修改meta标签,让IE8运行在IE7模式下,于是有了

改进1

<meta http-equiv="X-UA-Compatible" content="IE=7" >

但是,如果仅仅是这样的化会误伤IE9 —— IE9 已经支持svg了,如果页面上还有这个声明的
化,那么IE9也会以IE7模式来渲染页面。抛弃svg而使用vml,这样显然是很不合理的。

我困惑了很久,想尝试使用IE的另一个奇葩特性——条件注释来避免这个问题:

改进2 ——失败的尝试

将meta标签放在条件注释中,像这样

<!doctype html>
<html>
  <head>
    <!--[if lt IE 9]>
    <meta http-equiv="X-UA-Compatible" content="IE=7">
    <![endif]-->
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>

  </body>
</html>

但是遗憾的是,浏览器根本就不识别这样注释后的meta标签,所以这种方案以失败告终

改进3 —— 通过在服务器返回的header中设置,这个方案我没亲自尝试过

但是,PHP使用者,可以尝试下面的方案 [2]

header("X-UA-Compatible: IE=7,IE=9");

改进4 —— 最终方案

因为,我找到了更好的方案了,其实很简单,只要在 方案1 的基础上,做一点改变

<meta http-equiv="X-UA-Compatible" content="IE=7,IE=9" >

IE确实支持这样的写法,不过还是有坑的,在iframe下有问题,详细参看stackoverflow上的
讨论 [3]

[1] http://www.cnblogs.com/rubylouvre/archive/2009/10/12/1581891.html

[2] http://stackoverflow.com/questions/6156639/x-ua-compatible-is-set-to-ie-edge-but-it-still-doesnt-stop-compatibility-mode

[3] http://stackoverflow.com/questions/3413629/emulate-ie7-for-ie8-but-not-for-ie9-using-x-ua-compatible

ubuntu 13.10 通过chrome vnc viewer 插件连接 windows7

chrome 安装 vnc viewer 插件就不说了,具体看这里

关键在于,windows7 安装了vnc server 后,通过ubuntu上的vnc viewer 连接 不上的问题

原因在与,win7 默认开启了防火墙设置。具体解决步骤如下:

点击windows徽标,搜索防火墙,打开“高级安全 Windows防火墙”

step1

step2

step3

接下来下一步,到结束,起个名字再用vnc viewer 连接就能成功了

ubuntu 13.10 下面安装 grunt 报错

$ npm install grunt #产生报错
npm ERR! Error: No compatible version found: underscore.string@'~2.2.0rc'
npm ERR! Valid install targets:

原因是ubuntu13.10中的npm版本过低

$ npm -v
1.2.18

解决办法 ,用npm重新安装npm

$ sudo npm install npm -g

使用inkscape和fontforge制作iconfont

iconfont是通过矢量字体的方式来做icon,可以在高分辨率的屏幕上
也不会失真,能通过css来控制其样式,就像控制普通的文字一样。

像很多浏览器特性一样,使用iconfont是有兼容性问题的,要使用
iconfont,你不得不这样写字体声明:

@font-face {
  font-family: 'mui-wl';
  src: url('http://at.alicdn.com/t/font_1384420140_864115.eot');                                        /* IE9*/
  src: url('http://at.alicdn.com/t/font_1384420140_864115.eot?#iefix') format('embedded-opentype'),        /* IE6-IE8 */
  url('http://at.alicdn.com/t/font_1384420140_8889937.woff') format('woff'),                            /* chrome、firefox */
  url('http://at.alicdn.com/t/font_1384420140_8170962.ttf') format('truetype'),                            /* chrome、firefox、opera、Safari, Android, iOS 4.2+*/
  url('http://at.alicdn.com/t/font_1384420140_9259503.svg#svgFontName') format('svg');                    /* iOS 4.1- */
}

字体编辑的工具,windows平台下有fontlab配合AI能很好的生成
iconfont,具体介绍参看这里,CSS3 icon font完全指南

生成ttf格式的文件后,要兼容ie系列浏览器,还需要转为其它几种
格式

网上有一些工具能够进行字体转化的工具,能将ttf格式的字体文件,
转为各种格式的iconfont字体文件,比如这
个:http://www.fontsquirrel.com/fontface/generator

那么整个过程就完毕了,下面要介绍的是在linux环境下进行字体文
件的的制作


需要的环境

  1. inkscape ,用于生成字体路径
  2. fontforge ,linux下面的字体编辑器,需要忍耐下,界面非常丑,
    有很多快捷键

制作过程

  1. 准备好svg字体路径,可以用inkscape ,或者AI
    步骤一
  2. 用fontforge打开一个svg字体文件(也可以是ttf格式的),比如
    http://at.alicdn.com/t/font_1384420140_9259503.svg ,看到很多图形
    步骤二
  3. 点击一个字体空位,复制画好的svg路径到空位上
    步骤三
  4. 文件->生成字体,完成
    步骤四
  5. 借助上面的字体转换工具,将生成的ttf文件上传,生成其它格
    式的文件
  6. demo

需要注意的点

  1. fontforge 打开生成的ttf文件,前32个字符是不可见字符,如
    果你在这前32个字符中填充了图形也是没用的
  2. 如果你自己托管字体文件的的话,需要注意字体的跨域问题:
    firefox和IE9不支持对icon font字体的跨域。解决办法是在服
    务器的header中添加acceess-control

    http-header-access-control

总结

这样的制作过程还是比较麻烦的,但是能通过操作fontforge这个
软件,对字体文件有个感性的认识,再使用在线的工具的时候就不
会觉得完全是个黑箱了

更佳的方案——使用在线的工具

  1. http://fontello.com/
  2. http://icomoon.io/app

用iconfont实现loading的icon