混合Clojure和ClojureScript使用Clojurephant构建



我正在考虑将一个项目从启动转移到Gradle,clojurephant希望更多地利用Gradle生态系统。该项目构建了一个大型uberjar,其中包含一个带有Ring和Jetty的Clojure项目,该项目又提供了一个使用re-frame构建的ClojureScript应用程序。

在引导中,我基本上只需要引导cljs,添加了

(boot-cljs/cljs :optimizations :advanced)

到我的构建任务,它还调用(pom)(aot)(uber)(所有标准引导任务(,一切都很顺利。

使用Clojurephant,我发现Clojure和ClojureScript部分最终位于不同的子目录中。特别是在build下面

  • clojure/main
  • clojurescript/main
  • resources/main(本质上是我的resources项目文件夹的副本(

更让我困惑的是,这些路径并没有以我可以看到的方式转换为Gradle使用影子插件构建的Uberjar的结构

我的build.gradle:摘录

plugins {
id 'dev.clojurephant.clojure' version '0.5.0'
id 'dev.clojurephant.clojurescript' version '0.5.0'
id 'application'
id 'com.github.johnrengelman.shadow' version '5.0.0'
id 'maven-publish'
id 'distribution'
id 'com.meiuwa.gradle.sass' version '2.0.0'
}
// ...
clojure {
builds {
main {
aotAll()
}
}
}
// ...
clojurescript {
builds {
all {
compiler {
outputTo = 'public/app.js'
outputDir = 'public/js/out'
main = 'com.example.mycljsstuff'
assetPath = 'js/out'
}
}
main {
compiler {
optimizations = 'advanced'
sourceMap = 'public/app.js.map'
}
}
dev {
compiler {
optimizations = 'none'
preloads = ['com.example.mycljsstuff']
}
}
}
}

编辑:忘了提一下,在引导时,我配置init函数来开始在一个名为app.cljs.edn的文件中加载CLJS代码。使用Clojurephant,我只找到了一种设置主名称空间的方法,而不是一个函数。

我的问题最终是,如何配置ClojureScript构建,使其在从Uberjar交付时最终能够工作?

Clojure的事情似乎奏效了。Ring和Jetty愉快地运行并交付了第一个静态网页。但是所有的CLJS/JS东西都找不到。

如果能收到一些我可以学习的其他项目、文档或教程的指针,我会非常高兴。我没有发现太多,然后在理解Clojurephant本身的代码时迷失了方向。

一年前,在工作中,我能够拆分一个组合的CLJ&CLJS(backend/frontend(项目分为两个独立的项目:纯Clojure用于后端,纯ClojureScript用于前端。这解决了我们遇到的很多问题,我再也不会试图在同一个项目中保留两个代码库了。

  • 后端CLJ部分继续使用Lein作为构建工具。这并不完美,但大家都很清楚
  • 前端CLJS部分从最初的Figwheel(又名"1.0"(过渡到新的Figweel Main(又名"2.0"(我们选择使用Deps/CLI(最初的组合项目将Lein用于所有内容(来重组构建。从Lein过渡到Deps/CLI是CLJS工作的真正赢家

虽然Deps/CLI非常适合纯Clojure代码,但请注意,它本身并不支持包含Java源代码。我有一个模板项目您可以克隆,它显示了一个简单的解决方法。

对于任何CLJS项目,我强烈建议使用Figfheel Main而不是原来的Figfheer,因为它是一种主要的"2.0"类型的升级,会让你的生活变得更好。

享受吧!

试图在这里回答我自己的问题,因为我设法让它运行起来了。

Clojure

plugins {
id 'dev.clojurephant.clojure' version '0.5.0'
id 'application'
id 'com.github.johnrengelman.shadow' version '5.0.0'
// ... more to come further down
}
group = 'com.example'
version = '1.0.0-SNAPSHOT'
targetCompatibility = 1.8
mainClassName = 'com.example.myproject'
dependencies {
implementation(
'org.clojure:clojure:1.10.1',
'ring:ring:1.8.0',
// and many more
)
testImplementation(
'junit:junit:4.12',
'clj-http-fake:clj-http-fake:1.0.3',
'ring:ring-mock:0.4.0'
)
devImplementation(
'org.clojure:tools.namespace:0.3.0-alpha4',
'cider:cider-nrepl:0.21.1',
'org.clojure:java.classpath',
'jonase:eastwood:0.3.11',
'lein-bikeshed:lein-bikeshed:0.5.2'
)
}
clojure {
builds {
main {
aotAll()
}
}
}
clojureRepl {
handler = 'cider.nrepl/cider-nrepl-handler'
}

当从命令行调用./gradlew shadowJar时,这足以从com.example.myproject命名空间获得运行-main的可执行JAR。不确定application插件是否与此处相关。此外,./gradlew clojureRepl启动一个可以连接Emacs/Cider的nrepl。

ClojureScript

// Merge with plugins above. Reproduced only the CLJS relevant
// part here
plugins {
id 'dev.clojurephant.clojurescript' version '0.5.0'
}
// Again, merge with dependencies above
dependencies {
implementation(
// ....
'org.clojure:clojurescript:1.10.597',
're-frame:re-frame:0.10.5',
'reagent:reagent:0.7.0',
// and a few more
)
}
clojurescript {
builds {
all {
compiler {
outputTo = 'public/app.js'
outputDir = 'public/state/'
main = 'com.example.myproject.webui'
assetPath = 'status/app.out'
}
}
main {
compiler {
optimizations = 'advanced'
sourceMap = 'public/app.js.map'
}
}
dev {
compiler {
optimizations = 'none'
preloads = ['com.example.myproject.webui']
}
}
}
}

这在JAR的顶层创建了一个/public文件夹,在该文件夹中创建了app.js,这就是Ring交付的HTML文件所期望的位置

对我来说,一个重要的步骤是在CLJS文件中调用我的initCLJS函数,该函数以前由其他组件负责。我不确定这个设置是否完全正确,最终是否会进行figwheel设置。也许那时就不需要呼叫init了。

CSS

// Merge ....
plugins {
id 'com.meiuwa.gradle.sass' version '2.0.0'
}
sassCompile {
output = file("$buildDir/resources/main/public/")
source = fileTree("${rootDir}/src/main/resources/public/")
include("**/*.scss")
exclude("**/_*.sass", "**/_*.scss")
}

这会在正确的位置将我的app.scss编译为app.css,我的HTML文件会在那里搜索它

Pro&Con

迁移后,我获得免费

  • 正确设置缓存后,本地和CI中的编译速度更快
  • 使用插件com.github.jk1.dependency-license-reportorg.owasp.dependencycheck进行许可证和OWASP dep检查报告,插件的等效项存在于leiningen中,但不在引导(AFAIK(中
  • Maven发布通过HTTP头进行身份验证,而不是启动时不可用的用户名/密码

缺点:

  • 我的构建文件中的语法很糟糕。不,真的
  • 我必须手动在Emacs中输入nrepl端口号

最新更新