我想知道是否有人尝试/通过将实现CommonJS API(require())的JavaScript文件编译为本机Java代码来取得好运。

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

该项目带有一些JavaScript文件,这些文件可以清除编辑器的标记语言并将其转换为有效的HTML。

在Rhino 1.7R4上玩了一些之后,我设法在运行时加载JavaScript文件/模块,并且能够在任何时候执行require函数。

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

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

但是我对编译实现CommonJS功能的多个依赖脚本的正确方法一无所知,Rhino本身的文档也很少。

想法是拥有用于标记转换和卫生处理的本机Java代码,而无需编写/维护两个不同的代码库(只需将JS转换为JAVA)即可获得翻译成本。

干杯

最佳答案

RingoJS可以做这样的事情:


  Ringo实现CommonJS模块规范。简而言之,这意味着:
  
  每个JavaScript文件都被视为一个位于其自身顶级范围内的模块。
  
  附加到模块导出对象的任何函数或属性都将被公开。
  
  require()函数返回模块的导出对象。
  
  如果给定的标识符字符串以./或../开头,则Ringo的模块加载器将搜索文件并尝试加载该文件。因此require('./ foo')建议Ringo将文件./foo.js作为模块加载。
  
  否则,Ringo将在模块路径的每个文件夹中查找模块。
  
  模块路径是Ringo在其中查找模块的标准位置的列表。
  
  可以通过以下方式设置模块路径:
  
  设置RINGO_MODULE_PATH环境变量。
  
  设置ringo.modulepath Java系统属性。
  
  在ringo命令行工具中使用-m或--modules选项。
  
  将模块路径servlet init参数与JsgiServlet一起使用。
  
  从Ringo中向require.paths类似于数组的属性添加或删除元素。
  
  包提供了一种将多个模块和其他资源捆绑到一个单元中的方法。软件包是包含package.json软件包描述符文件的目录。 Ringo的模块加载器将package.json描述符中的main属性识别为模块的主要入口点:


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



  如果模块ID直接解析到软件包目录,并且package.json定义了main属性,则Ringo将尝试加载指定的资源。 main属性的值必须是相对于包根目录的路径。
  
  如果模块ID解析为不包含package.json文件的目录,或者package.json没有定义main属性,则Ringo将尝试在该目录中加载文件index.js。
  
  如果模块ID的一部分解析为软件包目录,Ringo将尝试根据该软件包的lib目录解析ID的其余部分。可以使用package.json中的directorys.lib属性覆盖lib目录的位置。


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



  CommonJS模块规范被故意减小了。 Ringo为导出和导入内容提供了一些额外的细节。使用这些漏洞的缺点是您的代码与Ringo绑定在一起,但是将代码转换为“纯” CommonJS相对容易,并且还有一个用于此目的的命令行工具。
  
  一个Ringo扩展是include函数。这与require相似,但是它没有将整个模块的输出对象作为一个整体返回,而是直接将其每个属性复制到调用模块的作用域,从而使它们像在本地定义的那样可用。
  
  include非常适合shell工作和快速脚本,在这些情况下,输入经济性至关重要。通常,将它用于大型的,寿命长的程序不是一个好主意,因为它掩盖了程序中使用的顶级函数的来源。
  
  为此,建议将require与JavaScript 1.8解构分配结合使用,以显式包括本地范围内另一个模块中的选定属性:


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



  上面的语句直接在调用范围内导入“ some / module”导出的API的“ foo”和“ bar”属性。
  
  用Ringo编写命令行脚本非常简单。每个任意的JavaScript文件都可以作为[script-file]参数传递给ringo命令:


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



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


参考文献


Modules in Ringo - RingoJS
Command line tools - RingoJS
Java Integration - RingoJS
rhino/RELEASE-NOTES.md at master · mozilla/rhino

08-28 20:00