Clojurescript与JavaScript的互操作性

11

我已经使用大部分Angular构建了一个应用程序。现在我想将项目转移到Clojurescript。众所周知Clojurescript与JavaScript有很好的互操作性,但是反过来是否可行呢?

常规的JavaScript / Angular代码如何利用从Clojurescript生成的JavaScript?

理想情况是在Clojurescript中编写新功能,并使其与旧代码并存。

欢迎提供任何关于此方面的提示或技巧。


4
一篇不错的博客文章 http://www.spacjer.com/blog/2014/09/12/clojurescript-javascript-interop/该文章介绍了ClojureScript和JavaScript之间的互操作性,包括如何在ClojureScript中调用JavaScript函数、如何从ClojureScript传递参数给JavaScript函数以及如何使用JavaScript库。还提供了一些示例代码和解释。 - aarti
2个回答

15
Clojurescript的变量、函数和deftype/records都是普通的JS变量、函数和构造函数/对象,因此您可以在JavaScript中使用cljs.core.abc()并调用Clojurescript而不会出现问题。
注意事项如下:
  1. 名称混淆。Clojurescript名称允许比javascript更广泛的字符范围,因此许多函数名称将被混淆。例如:cljs.core/<变成了cljs.core._LT_
  2. 宏。宏仅存在于Clojurescript编译时,因此无法从javascript中使用CLJS宏。
  3. 高级编译。Clojurescript核心非常大,并且它依赖Google Closure编译器来进行死代码消除,该编译器仅在高级编译中可用。在纯Clojurescript代码中安全地使用高级编译非常容易但在javascript代码中较难。(最大的危险是混合使用字符串和符号属性访问)。
您有多种选择:
  • CLJS将遗留代码作为库嵌入。您的程序入口点是CLJS,但使用遗留代码就像使用外部库一样。您的遗留代码提供了一个外部函数,CLJS调用该函数。只有使用^:export(如果定义名称)或类似goog.exportSymbol的方式显式导出的CLJS函数才能被遗留代码调用。CLJS和遗留代码部署在分别构建的不同JS文件中。
  • CLJS直接嵌入遗留代码。程序入口点是CLJS,但您的遗留代码是编译到同一项目中的其他js。 CLJS和遗留代码部署在由clojurescript编译器构建的单个JS文件中。要使用高级编译,您的遗留代码必须安全地使用高级编译并结构化以便与Google Closure编译器(goog.provides/requires、类型注释等)一起使用。Angular可能仍需要保持独立,但有一个angular extern available
  • 遗留代码将CLJS代码作为库调用。这与“CLJS将遗留代码作为库嵌入”几乎相同,只是您的入口点是遗留代码,并且它调用已导出的cljs函数。
  • 遗留代码通过库(例如mori)使用某些CLJS功能。在这里,您不直接使用CLJS,而是使用公开一些clojurescript功能的JS库作为普通JS。它仍然是一个单独的js库,您永远不会编写任何clojurescript。

感谢您提供详细的说明,这让我更好地了解了可行的选项。作为后续问题:对于数据密集型应用程序,在浏览器中使用Mori是否可以?我指的是速度方面,或者它会比直接使用Cljs更慢吗? - droidballoon
2
Mori 就是 ClojureScript,只是为了从JS中方便使用而进行了良好的打包。在cljs中与数据结构无关的内容会被死代码消除自动删除,因此没有速度差异。Facebook有一个名为ImmutableJs的库,其目的类似于Mori,但与cljs没有任何共享代码。它的速度也是可比较的。 - Francis Avila

2
对于ClojureScript中的Angular集成,您可以使用 gyr扩展。 对于从Clojure类型到JavaScript类型的数据转换,您可以使用clj->js

好的。必须彻底审查一下。 - droidballoon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接