2017 年 7 月 20 日
Juho Teperi
使用 JSX 或其他语法扩展的 JavaScript 库通常与已处理的代码一起打包,因此它们无需任何额外操作即可使用。不过,在某些情况下,用户可能希望直接在项目中包含此类代码。例如,在将项目从 JavaScript 转换为 ClojureScript 时,重用现有代码比尝试一次性重写所有内容要容易得多。此外,构建复杂的用户界面是一个团队合作的过程,而 JSX 等工具可以通过为设计师提供熟悉的工具来使这个过程更加友好。通过允许 ClojureScript 访问 JSX 和其他流行的语法特性,ClojureScript 开发流程可以更加包容。
在原始设计中,预处理是通过向 foreign-lib 映射 提供 :preprocess
来启用的。该值是针对 cljs.closure/js-transforms
多方法的关键字分派。用户可以实现新的多方法案例,例如使用 Java 的内置 Nashorn JavaScript 引擎来运行像 Babel 这样的 JavaScript 编译器。
然而,这种方法会给流行的 Clojure 和 ClojureScript 构建工具带来一些问题。提供预处理多方法的 Clojure 命名空间必须在运行 ClojureScript 编译器之前由用户加载。虽然这在显式构建脚本中是可行的,但由于 Leiningen 和 Boot 将构建隔离到自己的类路径中,因此这种需求实际上并不实用。
有几种方法可以解决原始设计的问题
提供一个新的配置选项,用于在运行编译器之前列举要 require
的命名空间。
在多方法分派关键字和提供实现的命名空间之间建立一种关系。例如,如果关键字是带命名空间的,那么关键字的命名空间部分可以用来按需 require
该命名空间。
这两种解决方案都可以在构建工具中或直接在 ClojureScript 编译器中实现。从最终用户的角度来看,第一个选项似乎很绕,而第二个选项虽然强调了根本问题,但使用关键字来实现这种模式似乎并不符合惯例。如果我们简单地将关键字切换为符号,我们就可以与现有的先例保持一致。
ClojureScript 的下一个版本将支持符号作为 :preprocess
选项值的类型。使用完全限定的符号可以清楚地表明该值是指一个函数,并且符号的命名空间部分可以用来自动加载用户指定的命名空间。
cljsjs/babel-standalone 已经更新,并且提供了一种简单的方法,可以使用 Babel 与 ClojureScript 工具一起使用,遵循这种新的模式。