编译需要CommonJS功能的JavaScript到本机Java

时间:2012-09-08 22:42:29

标签: javascript java native rhino commonjs

我想知道是否有人尝试将实现CommonJS API(require())的JavaScript文件编译成本机Java代码。

我目前有一个我正在构建的网站将使用类似于这个的文本编辑器,stackoverflow开源(WMD编辑器的一个端口): http://code.google.com/p/pagedown/

该项目附带了一些JavaScript文件,用于清理编辑器的标记语言并将其转换为有效的HTML格式。

在使用Rhino 1.7R4时,我已经设法在运行时加载JavaScript文件/模块,并且能够在何时执行require函数。

但是,我宁愿将这些脚本预编译为本机Java代码。我已经设法编译了这个Rhino doc之后不使用CommonJS功能的单个脚本:

https://developer.mozilla.org/en-US/docs/Rhino/JavaScript_Compiler

但是我对编译实现CommonJS功能的多个依赖脚本的正确方法感到茫然,而Rhino本身并没有很好地记录。

我们的想法是拥有用于标记转换和清理的本机Java代码,而无需编写/维护两个不同代码库的翻译成本(通过将JS转换为JAVA)。

干杯

1 个答案:

答案 0 :(得分:0)

RingoJS可以做这样的事情:

  

Ringo实现了CommonJS Modules规范。简而言之,这意味着:

     

每个JavaScript文件都被视为一个模块,它位于自己的顶级范围内。

     

附加到模块的导出对象的任何函数或属性都将被公开。

     

require()函数返回模块的导出对象。

     

如果给定的标识符字符串以./或../开头,则Ringo的模块加载程序搜索文件并尝试加载它。因此,需要(' ./ foo')建议Ringo将文件./foo.js加载为模块。

     

否则Ringo会在模块路径的每个文件夹中查找模块。

     

模块路径是Ringo将查找模块的标准位置列表。

     

可以通过以下方式设置模块路径:

     

设置RINGO_MODULE_PATH环境变量。

     

设置ringo.modulepath Java系统属性。

     

对ringo命令行工具使用-m或--modules选项。

     

将module-path servlet init参数与JsgiServlet一起使用。

     

在Ringo中向require.paths类似数组的属性添加或删除元素。

     

包提供了将多个模块和其他资源捆绑到一个单元中的方法。包是包含package.json包描述符文件的目录。 package.json描述符中的main属性被Ringo的模块加载器识别为模块的主要入口点:

{
    "main": "lib/main.js"
}
  

如果模块id直接解析为package目录而package.json定义了一个main属性,Ringo将尝试加载指定的资源。 main属性的值必须是相对于包根的路径。

     

如果模块ID解析为不包含package.json文件的目录,或者package.json没有定义主属性,则Ringo将尝试在该目录中加载文件index.js。

     

如果模块id的一部分解析为包目录,Ringo将尝试针对该包的lib目录解析id的剩余部分。可以使用package.json中的directories.lib属性覆盖lib目录的位置。

{
    "directories": {
        "lib": "new-lib"
    }
}
  

CommonJS模块规范故意保持较小。 Ringo为出口和进口东西提供了一些额外的细节。使用它们的缺点是你的代码与Ringo绑定,但是将代码转换为"纯粹的"相对容易。 CommonJS,还有一个命令行工具。

     

一个Ringo扩展是包含功能。这与require类似,但它不是将整个其他模块的导出对象作为一个整体返回,而是直接将其每个属性复制到调用模块的范围,使它们像在本地定义一样可用。

     

include非常适合shell工作和快速脚本,其中打字经济是最重要的,这是它的意义所在。将它用于大型长寿程序通常不是一个好主意,因为它隐藏了程序中使用的顶级函数的起源。

     

为此,使用require与JavaScript 1.8解构赋值相结合以明确包含本地范围内另一个模块的选定属性更为明智:

var {foo, bar} = require("some/module");
  

以上陈述导入" foo"和" bar"由" some / module"导出的API的属性直接在调用范围内。

     

使用Ringo编写命令行脚本非常简单。每个任意JavaScript文件都可以作为[script-file]参数传递给ringo命令:

ringo [script-file] [script-arg1] [script-arg2] ...
  

Ringo加载脚本文件并通过系统模块的args数组提供参数。 args数组中的第一个元素是脚本文件的名称。

<强>参考