Hello World
Spiga

Jscex预编译器及其DocPad插件

2012-06-04 22:34 by 老赵, 1424 visits

需求本身会是最好的动力。上个周末除了忙于构建Jscex主站以外,我还重新整理了Jscex的预编译器——或者说是AOT编译器。Jscex自带一个JIT编译器,配合eval可以在开发时避免额外的编译过程,这也可以说是Jscex的亮点之一。不过对于线上环境,一般都还是建议进行预编译,也就是将Jscex方法定义直接替换为目标代码。这么做的好处主要是为了降低部署时的脚本体积(摆脱对编译器的依赖所有代码加起来不到4KB),或是让异常情况下的错误定位变得容易(主要面向Node.js生产环境)。此外,为了便于编写文档,我还为DocPad开发了一个插件,用于对Jscex脚本进行预编译。

与其他Jscex的包不同,Jscex预编译器的定位不是一个Jscex模块,而是一个独立的工具。因此,它的第一种使用方式是作为一个命令:

> npm install jscexc
...

> node node_modules/jscexc
Usage: node ./node_modules/jscexc --input <input_file> --output <output_file>

Options:
  --input, -i   The input file   [required]
  --output, -o  The output file  [required]

Missing required arguments: input, output

但其实最好是将这个包构造为一个可以直接执行的命令,但我还不是还不是很清楚如何让它像mocha那样同时支持Windows和*nix,所以暂时还没去实现。等搞定这个问题之后,就可以像下面这样使用jscexc命令了:

> [sudo] npm -g install jscexc
...

> jscexc --input test.js --output test.aot.js

于是这样便能将test.js的内容转化为test.aot.js,其中的Jscex方法定义都会被直接替换成目标代码。

这么做便达到了预编译的效果,但Jscex预编译器同样可以当作模块使用。例如,我在编写首页示例的时候,我就利用DocPad提供的插件机制,直接将*.jscex文件经过预编译,转化为最终的JavaScript代码:

# Export Plugin
module.exports = (BasePlugin) ->
    # Define Plugin
    class JscexcPlugin extends BasePlugin
        name: "jscexc"
        
        # Render some content
        render: (opts, next) ->
            # Prepare
            {inExtension, outExtension, templateData, file} = opts

            # Check extensions
            if inExtension in ["jscex"] and outExtension in ["js"]
                # Requires
                jscexc = require("jscexc")

                # Render
                opts.content = jscexc.compile(opts.content)

            # Done, return back to DocPad
            return next()

虽然docpad-plugins-jscexc插件使用CoffeeScript编写,但看懂这段代码应该不成问题。总体而言,就是在需要的时候(这里是将*.jscex文件转化为*.js文件)把jscexc当作模块引入进来,再调用它的compile方法,任何Node.js文件都能这么使用jscexc包。现在,我在使用DocPad编写文档示例的时候,只要直接编写Jscex代码,DocPad会自动生成其目标内容,而在页面上只需要引入最基本的Jscex异步类库即可,非常方便。

当然也有一些已知问题,例如输入文件的换行符必须是Unix下的\n而不能是Windows下的\n\r,这问题到不大,使用dos2unix或者随便哪个文本编辑器都能轻松搞定(当然我还是会修复这个问题的)。还有同学汇报说不能使用module语句——Jscex预编译器为了尽可能保留输入文件的内容,于是使用了能提供更多信息的Narcissus分析器,可惜它实在太自作多情了一些,把module当作保留字了,所以我对Narcissus Parser做了简单的修补,也算是绕过了这个问题。

总有天我会换掉这个中看不中用的Narcissus分析器,例如Esprima似乎就挺不错的,而且实在不行就自己写一个。

Creative Commons License

本文基于署名 2.5 中国大陆许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名赵劼(包含链接),具体操作方式可参考此处。如您有任何疑问或者授权方面的协商,请给我留言

Add your comment

9 条回复

  1. 老赵
    admin
    链接

    老赵 2012-06-06 14:26:18

    好多天了居然一条回复都没有……

  2. jackfu
    115.216.67.*
    链接

    jackfu 2012-06-06 21:27:36

    配合回复下,呵呵

  3. wowdd1
    113.88.105.*
    链接

    wowdd1 2012-06-06 22:48:19

    看不懂 很有压力 555 还是问个比较简单的问题吧 月薪多少

  4. 老赵
    admin
    链接

    老赵 2012-06-07 08:42:54

    @wowdd1

    五位数。

  5. 链接

    2012-06-07 10:55:56

    哈哈 我来回复 主要是被生词Jscex吓到了

    顺便问一下 老赵书托系列除了(1)(2)还有后续么?

    另外。刚回复过一次没成功,提示"Strange things happend, please reload the page"

  6. 链接

    2012-06-07 10:56:30

    终于换chrome回复成功了 360浏览器一直失败 。。:(

  7. 老赵
    admin
    链接

    老赵 2012-06-07 11:14:21

    @羽

    看来真得测下IE了……

  8. gyf19
    218.82.21.*
    链接

    gyf19 2012-06-10 01:33:25

    页面中有很多 链接开不开。例如: JIT编译器模块

  9. itsor
    183.157.7.*
    链接

    itsor 2012-10-03 11:17:44

    请教DocPad是啥东东啊

发表回复

登录 / 登录并记住我 ,登陆后便可删除或修改已发表的评论 (请注意保留评论内容)

昵称:(必填)

邮箱:(必填,仅用于Gavatar

主页:(可选)

评论内容(大于5个字符):

  1. Your Name yyyy-MM-dd HH:mm:ss

使用Live Messenger联系我