ClojureScript

ClojureScript 命令行

2018 年 3 月 26 日
Mike Fikes

ClojureScript 现在有一个激动人心的新命令行功能,名为 cljs.main,它极大地简化了许多常见用例的 ClojureScript 使用。在这篇文章中,我们将带您快速了解正在引入的功能。

设置 ClojureScript

为了运行这些示例,您需要设置 ClojureScript。您可以通过 clj 命令行工具或下载独立的 JAR 来做到这一点。

macOS 或 Linux:clj

  1. 安装 clj 命令行工具。

  2. 在您的工作目录中,创建一个 deps.edn 文件,其内容如下

{:deps {org.clojure/clojurescript {:mvn/version "1.10.238"}}}

Windows

  1. 下载 ClojureScript JAR cljs.jar.

  2. 将其放置在您的工作目录中。

启动浏览器 REPL

让我们直接开始吧!您可以通过运行以下命令来启动浏览器 REPL

clj -M -m cljs.main

在 Windows 上

java -cp cljs.jar cljs.main

当您执行此操作时,REPL 将启动,并会自动启动浏览器连接回它。

Browser REPL Serving Default index.html

您将在 REPL 终端中看到以下内容

ClojureScript 1.10.238
cljs.user=>

我们现在处于交互式环境中,可以控制页面。尝试在 REPL 中执行以下操作,以在浏览器中弹出警报

(js/alert "Hello CLJS!")

创建浏览器应用程序

现在,让我们拼凑一个简单的基于浏览器的 ClojureScript 应用程序,并探索 cljs.main 编译应用程序源代码的能力。

请注意,在上一节中,cljs.main 为我们合成地生成了一个 index.html。我们将在当前目录中为我们的应用程序创建一个自定义的 index.html

<html>
  <body>
    <canvas id="canvas" width="400" height="300"></canvas>
    <script src="out/main.js"></script>
  </body>
</html>

src/my_app/core.cljs(或在 Windows 上为 src\my_app\core.cljs)中添加以下源代码。

(ns my-app.core)

(def ctx (-> js/document
             (.getElementById "canvas")
             (.getContext "2d")))

(defn draw-shape [x y radius color]
  (set! (.-fillStyle ctx) color)
  (.beginPath ctx)
  (.arc ctx x y radius 0 (* 2 Math/PI))
  (.fill ctx))

(draw-shape 150 150 100 "blue")

现在,让我们使用 cljs.main 首先编译此源代码(使用 -c),然后在完成时启动浏览器 REPL(使用 -r),并另外监视我们源代码中的更改(使用 -w

clj -M -m cljs.main -w src -c my-app.core -r

在 Windows 上

java -cp "cljs.jar;src" cljs.main -w src -c my-app.core -r

请注意,我们还将 src 目录添加到类路径中。

当它启动时,您应该在浏览器中看到一个蓝色圆圈。

Browser REPL Showing Blue Circle

尝试通过绘制其他圆圈来与应用程序进行交互。例如,在 REPL 中尝试以下操作

(my-app.core/draw-shape 350 200 50 "red")
Browser REPL Showing Blue and Red Circle

如果您更改了源代码怎么办?将 draw-shape 实现中的 2 更改为 1,然后刷新您的浏览器。现在,应用程序将绘制半圆而不是圆圈。

创建 Node 应用程序

在前面的部分中,我们依赖 cljs.main 来建立浏览器 REPL 环境。但是,cljs.main 有一个命令行标志(-re),允许您指定备用的 REPL 环境。

例如,如果您安装了 Node,您可以使用 cljs.main 通过提供 -re node 来启动基于 Node 的 REPL

clj -M -m cljs.main -re node

在 Windows 上

java -cp cljs.jar cljs.main -re node

如果您执行此操作,您将直接进入基于 Node 的 REPL

ClojureScript 1.10.238
cljs.user=> (+ 2 3)
5
cljs.user=> (exists? js/require)
true

让我们创建一个小型基于 Node 的应用程序。将 my-app.core 命名空间的内容替换为

(ns my-app.core)

(defn square [x]
  (* x x))

(defn -main [& args]
  (-> args first js/parseInt square prn))

有了这些内容,让我们使用 cljs.main 来运行这个应用程序,以在指定的命名空间中运行 -main(使用 -m

clj -M -m cljs.main -re node -m my-app.core 5

在 Windows 上

java -cp "cljs.jar;src" cljs.main -re node -m my-app.core 5

运行此命令将自动编译我们的命名空间,启动 Node,并执行我们的 -main,传递我们的命令行参数 5,从而导致它打印 25

如果我们想生成一个独立的 JavaScript 文件,我们可以用它与 Node 做同样的事情,该怎么办?

首先,在 my-app.core 的末尾添加一个助手

(set! *main-cli-fn* -main)

现在,我们将编译一个 simple(使用 -O)构建,目标是 Node(使用 -t),指定我们希望最终输出文件的位置(使用 -o

clj -M -m cljs.main -t node -O simple -o main.js -c my-app.core

在 Windows 上

java -cp "cljs.jar;src" cljs.main -t node -O simple -o main.js -c my-app.core

有了这个,您可以将 main.js 复制到任何您想要的位置并运行

node main.js 5

它将打印 25

在 Nashorn 中运行测试

内置的 Nashorn 环境可以使用 cljs.main 访问,并且使用它不需要任何外部 JavaScript 环境。让我们用它来运行一些测试。

首先,为 my-app.core-test 命名空间添加一个新文件

(ns my-app.core-test
  (:require
   [my-app.core]
   [clojure.test :refer [deftest is]]))

(deftest square-test
  (is (== 25 (my-app.core/square 5))))

让我们在 Nashorn 下运行这些测试(通过指定 -re nashorn)。为了以略微不同的方式进行操作,让我们使用 -i 来加载资源,并使用 -e 来评估将启动测试的表单

clj -M -m cljs.main -re nashorn -i src/my_app/core_test.cljs -e "(cljs.test/run-tests 'my-app.core-test)"

在 Windows 上

java -cp "cljs.jar;src" cljs.main -re nashorn -i src\my_app\core_test.cljs -e "(cljs.test/run-tests 'my-app.core-test)"

有了这个,您将看到

Testing my-app.core-test

Ran 1 tests containing 1 assertions.
0 failures, 0 errors.

其他功能

以上内容带您快速了解了 cljs.main 中可用的绝大多数选项。还有其他选项可用,您可以通过运行以下命令获取有关这些选项的帮助

clj -M -m cljs.main -h

在 Windows 上

java -cp cljs.jar cljs.main -h

几个可能对您有用的有趣选项是 -co-ro。它们提供了配置任何编译器 编译器选项REPL 选项(在 -co 下)和 REPL 环境特定选项(在 -ro 下)的能力。如果需要为 cljs.main 没有提供命令行标志的内容指定内容,这些选项可以作为“逃生舱口”。

例如,以下内容将应用 :repl-verbose 选项(因此在使用 REPL 时会显示正在发出的 JavaScript)

clj -M -m cljs.main -co "{:repl-verbose true}" -re node -r

在 Windows 上

java -cp cljs.jar cljs.main -co "{:repl-verbose true}" -re node -r

您可以像上面所示那样直接在命令行中指定 EDN,或者可以提供包含 EDN 的文件名称。有了这种功能,您几乎可以使用 cljs.main 对 ClojureScript 编译器进行任何操作。

我们希望您发现新的 cljs.main 功能有用,并希望它能简化您使用 ClojureScript 编译器需要完成的许多常见任务!