ClojureScript

JavaScript 模块支持(Alpha)

本页面介绍如何将 JavaScript 模块包含到 ClojureScript 项目中。请注意,本指南中描述的功能仍处于 Alpha 阶段。

动机

除了代码优化和依赖项管理之外,Google Closure 编译器还可以将常见的 JavaScript 模块转换为 Google Closure 模块。与 JavaScript 模块相比,Google Closure 模块具有以下优势

  • Google Closure 模块包含在源代码优化中

  • 无需指定 externs

包含 JavaScript 模块

接下来,我们将看到如何将以下简单的 CommonJS 模块包含到 ClojureScript 项目中。

// calculator.js
var calculator = {
    add: function (a, b) {
        return a + b;
    },
    subtract: function (a, b) {
        return a - b;
    }
};

module.exports = calculator;

在项目配置中添加 JavaScript 模块

如果要将 JavaScript 模块包含到项目中,需要将其添加为外部库,并使用 :module-type 编译器选项指定其模块类型。目前支持的模块类型有 CommonJSAMDECMAScript 6。分别地,可以为 :module-type 编译器选项指定的的值为 :commonjs:amd:es6。例如,上面所示 CommonJS 模块的编译器选项如下所示

:foreign-libs [{:file "resources/libs/calculator.js"
                :provides ["calculator"]
                :module-type :commonjs}]

在代码中使用 JavaScript 模块

可以使用为模块指定的名称,并使用 :provides 编译器选项,将 JavaScript 模块包含到 ClojureScript 命名空间中。对于上面显示的 CommonJS 模块,我们指定了名称 calculator。现在,我们可以在 ClojureScript 代码中使用该模块,就像使用来自 Google Closure 库 的模块一样。

(ns my-project.core
  (:require [calculator :as calc]))

(enable-console-print!)

(println (calc/add 4 5))

限制

Google Closure 编译器的限制

Google Closure 编译器期望其 JavaScript 输入在使用优化级别 :simple:advanced 时符合一些限制。这意味着如果要使用这些优化级别,则 JavaScript 模块必须符合 Google Closure 编译器施加的限制。有关限制的更多详细信息,请参见 https://developers.google.com/closure/compiler/docs/limitations

指定模块依赖项

如果 JavaScript 模块依赖于其他模块,则还需要将这些模块添加到项目配置中。对于具有许多不同模块的大型项目来说,这可能不可行。在这种情况下,您可能需要先捆绑项目,然后将其作为单个模块包含。

Node.js 模块

Node.js 模块规范CommonJS 规范 略有不同,因为传递给 require() 的模块标识符并不总是需要是绝对路径或相对路径。这使得 Google Closure 编译器难以解析节点模块的依赖项,因为编译器是按照标准 CommonJS 规范实现的。因此,节点模块可能无法转换为 Google Closure 模块。