1

我想知道是否有人尝试过将实现 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)。

干杯

4

1 回答 1

0

RingoJS 可以做这样的事情:

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

每个 JavaScript 文件都被视为生活在其自己的顶级范围内的模块。

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

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

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

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

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

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

设置 RINGO_MODULE_PATH 环境变量。

设置 ringo.modulepath Java 系统属性。

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

将 module-path servlet 初始化参数与 JsgiServlet 一起使用。

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

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

{
    "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 中的 directory.lib 属性覆盖 lib 目录的位置。

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

CommonJS 模块规范故意保持较小。Ringo 为导出和导入内容提供了一些额外的细节。使用这些的缺点是您的代码与 Ringo 相关联,但是将代码转换为“纯”CommonJS 相对容易,并且还有一个用于此目的的命令行工具。

一个 Ringo 扩展是包含功能。这类似于 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 数组中的第一个元素是脚本文件的名称。

参考

于 2017-07-04T15:39:48.053 回答