用clojurescript repl增压您的JS/TS项目
#javascript #初学者 #生产率 #clojure

如果还没有

您可能有现有的项目可以增压。例如,在这里我们首先创建全新的Vite项目。

$ mkdir -p /tmp/hi && cd /tmp/hi
$ pnpm create vite@latest . --template react-ts

我们现在有一个工作项目,例如pnpm run build && pnpm exec vite preview --open

现在,添加shadow-cljs

$ pnpm install --save-dev shadow-cljs
$ pnpm exec shadow-cljs init
$ pnpm exec shadow-cljs info

最后一个命令将花费一些时间,同时抓住所有所需的依赖项。请耐心等待,此后,如果所有安装都正确,所有疑问将被还清。

如果您的结果看起来或多或少如下,那么恭喜,您已经迈出了启蒙的第一步。

shadow-cljs - config: /private/tmp/x3/shadow-cljs.edn
=== Version
jar:            2.22.10
cli:            2.22.10
deps:           1.3.4
config-version: 2.22.10

=== Paths
cli:     /private/tmp/x3/node_modules/.pnpm/shadow-cljs@2.22.10/node_modules/shadow-cljs/cli/dist.js
config:  /private/tmp/x3/shadow-cljs.edn
project: /private/tmp/x3
cache:   .shadow-cljs

=== Java
openjdk version "19.0.2" 2023-01-17
OpenJDK Runtime Environment Homebrew (build 19.0.2)
OpenJDK 64-Bit Server VM Homebrew (build 19.0.2, mixed mode, sharing)

=== Source Paths
/private/tmp/x3/src/dev
/private/tmp/x3/src/main
/private/tmp/x3/src/test

...
=== Dependencies
shadow-cljs - updating dependencies
Retrieving...

...
...

...
shadow-cljs - dependencies updated
[thheller/shadow-cljs "2.22.10" :classifier "aot"]
[com.bhauman/cljs-test-display "0.1.1"]
[cider/piggieback "0.5.3" :exclusions [[org.clojure/clojure] [org.clojure/clojurescript] [nrepl]]]
[io.methvin/directory-watcher "0.17.1"]
  [net.java.dev.jna/jna "5.12.1"]
  [org.slf4j/slf4j-api "1.7.36"]
[org.clojure/clojure "1.11.1"]
  [org.clojure/core.specs.alpha "0.2.62"]
  [org.clojure/spec.alpha "0.3.218"]
[com.cognitect/transit-cljs "0.8.280"]
  [com.cognitect/transit-js "0.8.874"]
[org.clojure/google-closure-library "0.0-20230227-c7c0a541"]
[thheller/shadow-cljsjs "0.0.22"]
[org.clojure/core.async "1.5.648"]
  [org.clojure/tools.analyzer.jvm "1.2.2"]
    [org.clojure/core.memoize "1.0.253"]
      [org.clojure/core.cache "1.0.225"]
        [org.clojure/data.priority-map "1.1.0"]
    [org.clojure/tools.analyzer "1.1.0"]
    [org.ow2.asm/asm "9.2"]
[com.google.javascript/closure-compiler-unshaded "v20230228"]
  [com.google.code.gson/gson "2.9.1"]
  [com.google.guava/guava "31.0.1-jre"]
    [com.google.code.findbugs/jsr305 "3.0.2"]
    [com.google.guava/listenablefuture "9999.0-empty-to-avoid-conflict-with-guava"]
    [com.google.j2objc/j2objc-annotations "1.3"]
    [org.checkerframework/checker-qual "3.12.0"]
  [com.google.guava/failureaccess "1.0.1"]
  [org.jspecify/jspecify "0.2.0"]
  [com.google.auto.value/auto-value-annotations "1.6"]
  [javax.annotation/jsr250-api "1.0"]
  [args4j "2.33"]
  [com.google.errorprone/error_prone_annotations "2.15.0"]
  [com.google.protobuf/protobuf-java "3.21.12"]
  [org.apache.ant/ant "1.10.11"]
    [org.apache.ant/ant-launcher "1.10.11"]
  [com.google.re2j/re2j "1.3"]
[ring/ring-core "1.9.6" :exclusions [[clj-time]]]
  [commons-fileupload "1.4"]
  [commons-io "2.11.0"]
  [crypto-equality "1.0.1"]
  [crypto-random "1.2.1"]
    [commons-codec "1.15"]
  [ring/ring-codec "1.2.0"]
[hiccup "1.0.5"]
[thheller/shadow-undertow "0.3.1"]
  [io.undertow/undertow-core "2.2.4.Final"]
    [org.jboss.logging/jboss-logging "3.4.1.Final"]
    [org.jboss.threads/jboss-threads "3.1.0.Final" :exclusions [[org.wildfly.common/wildfly-common]]]
    [org.jboss.xnio/xnio-api "3.8.0.Final" :exclusions [[org.jboss.threads/jboss-threads]]]
      [org.wildfly.client/wildfly-client-config "1.0.1.Final"]
      [org.wildfly.common/wildfly-common "1.5.2.Final"]
    [org.jboss.xnio/xnio-nio "3.8.0.Final" :scope "runtime" :exclusions [[org.wildfly.common/wildfly-common]]]
[thheller/shadow-client "1.3.3"]
[fipp "0.6.26"]
  [org.clojure/core.rrb-vector "0.1.2"]
[org.clojure/google-closure-library-third-party "0.0-20230227-c7c0a541"]
[org.clojure/clojurescript "1.11.60" :exclusions [[com.google.javascript/closure-compiler-unshaded] [org.clojure/google-closure-library] [org.clojure/google-closure-library-third-party]]]
[org.clojure/tools.reader "1.3.6"]
[org.clojure/tools.cli "1.0.206"]
[org.clojure/data.json "2.4.0"]
[nrepl "1.0.0"]
[com.cognitect/transit-clj "1.0.329"]
  [com.cognitect/transit-java "1.0.362"]
    [com.fasterxml.jackson.core/jackson-core "2.8.7"]
    [javax.xml.bind/jaxb-api "2.3.0"]
    [org.msgpack/msgpack "0.6.12"]
      [com.googlecode.json-simple/json-simple "1.1.1" :exclusions [[junit]]]
      [org.javassist/javassist "3.18.1-GA"]
[expound "0.9.0"]
[thheller/shadow-util "0.7.0"]

哦,好吧,请不要感到恐吓。如果您与NPM node_modules中的所有那些(例如,pnpm ls --depth 15)。


好,目前,我认为您已经了解并完成了JS或打字稿部分,它与往常相同。

现在,增压部分是,我们如何让clojurescript重新开始启蒙。

pnpm exec shadow-cljs browser-repl

如果一切顺利,我们会受到CLJ SPERP的欢迎以及一个开放的浏览器窗口,在此浏览器窗口中,我们对REPP进行的每个评估都将执行。

shadow-cljs - config: /private/tmp/x3/shadow-cljs.edn
shadow-cljs - server version: 2.22.10 running at http://localhost:9630
shadow-cljs - nREPL server started on port 65047
[:browser-repl] Configuring build.
[:browser-repl] Compiling ...
[:browser-repl] Build completed. (119 files, 118 compiled, 0 warnings, 10.19s)
cljs.user=>

此替补几乎具有与浏览器控制台相同的目的,我们可以在其中键入有效的表达式以快速检查结果。但是,这或多或少是强大的LISP REPL而不是JavaScript控制台。

使用此补充,我们可以实时执行任何允许的操作,与实时运行时进行互动,调用所有可用的JS API并修改它的各个方面 live - 不重新启动,重新加载或类似的东西。

我们将获得与我们自己可爱的编辑(例如EmacsVSCode。如果您刚开始,我建议您设置Calvaget started指南是如此新手友好。

在这篇文章中,我们将简单地与命令行互动以显示一些演示。

将其粘贴到repl:

(ns my.app
  (:require ["react" :as react]))

现在创建了名为my.appnamespace,我们的活动名称空间已从cljs.user转到my.app,如提示。

my.app=>

此名称空间现在可以通过名为react的符号访问React JS模块。在称为 Indusning 的命名空间中绑定符号的过程。

让我们尝试安装新的NPM软件包,例如uid。一个微小的(130b至205b)和快速实用程序,以随机化固定长度的唯一ID。

打开新的终端外壳,做:

$ pnpm install --save uid

回到我们的cljs repl,我们现在可以将my.app ns更新为实习生。

(ns my.app
  (:require ["react" :as react]
            ["uid" :as uid]))

现在我们可以访问uid模块,我们可以调用uid模块提供的uid函数,例如:

;; call uid function
(uid/uid)

;; call it 100 times, return a list of 100 random uid
(repeatedly 100 #(uid/uid))

接下来,我们定义一个名为new-rand-div的函数,它将返回新的HTMLDIVELEMENT,其中包含一个随机的UID字符串。

(defn new-rand-div []
  (let [x (. js/document createElement "div")]
    (set! (.-innerText x) (uid/uid))
    x))

和测试调用以验证。

(new-rand-div)

现在,让我们激活在替补开始期间打开的浏览器窗口,如果检查该窗口,它的div元素名为“ app”。我们将修改DOM,以显示我们如何与运行时进行交互以轻松修改页面。

(let [x (. js/document getElementById "app")] 
  (dotimes [i 100]
    (. x append (new-rand-div))))

验证浏览器窗口现在显示了100个随机UID。

好吧,那是现在。我希望能说服我们如何被增压,即使只是被录音也是如此。

很好,保存一些资源,我们现在应该退出替补来停止它。

:cljs/quit

谢谢您的阅读,让我知道您是否需要更多此类,我会花一些时间来创建后续帖子,这应该很有趣。