我知道我可以编写自己的sbt任务,并且可以在它们之间创建依赖关系。任务层次结构在我看来有点复杂,这就是我正在努力解决的问题:,我不知道我的任务应该依赖于哪些任务,。情况就是这样。
我的Scala/Play web应用程序有一个非常复杂的前端,用JavaScript/React编写,它是用webpack编译的。在开发期间,我使用webpack-dev-server。它更快,并且支持像热重装这样的功能。然而,在生产模式下部署时,我希望使用sbt构建我的前端。这意味着对于sbt start或sbt dist,我希望将我的前端与Scala源代码一起编译,但是对于sbt run,应该完全省略这个阶段(因为这需要相当多的时间,而webpack-dev-server负责处理这个阶段)。
我创建了自己的sbt任务,它几乎只运行npm install && npm run build ,但我不知道如何连接它。
我认为,由于sbt对待“资产”的方式,情况更加复杂。我的项目中有一个public文件夹,它包含样式、脚本或图像等资产。这些东西通过构建过程复制到target文件夹,然后在最终的应用程序中获得。在我的当前解决方案中,原始的React/JavaScript文件被分开,自定义sbt任务将其编译到public文件夹中,将编译后的包复制到target文件夹中。这是预期的工作流,但此时必须手动调用自定义sbt任务。我想让整个过程自动化,但我不知道在将JavaScript复制到target文件夹之前将任务链接到哪里来编译它。我试着执行copyResource任务,如下所示:
(copyResources in Compile) <<= (copyResources in Compile) dependsOn buildJs这似乎是可行的,但问题是,在开发模式(即buildJs)中运行时,也会触发自定义任务( sbt run)。这是我想要避免的。
我尝试过的另一种方法是将JavaScript直接编译到target文件夹。这些文件出现在正确的位置,但是应用程序没有意识到它们。他们根本就没时间。获取任何这些文件的HTTP请求都返回空响应。
有什么想法吗?
发布于 2016-05-02 18:34:47
因此,应该依赖于我的自定义任务(构建JavaScript的任务)的任务是stage和dist。这是我的build.sbt
lazy val buildJs = taskKey[Unit]("Build JavaScript frontend")
buildJs := {
println("Building JavaScript frontend...")
"npm install" #&& "npm run build" !
}
stage <<= stage dependsOn buildJs
dist <<= dist dependsOn buildJs此任务仅为sbt start和sbt dist激活,而不用于sbt run (=开发模式)。为此,我使用了一个单独的webpack-dev-server实例,它处理JavaScript编译。
有可能有一个更简单的方法,但这才是对我有用的方法。
如果您决定使用这种方式将webpack集成到sbt中,最后一个缺失的难题是根据当前模式加载适当的JavaScript文件(在生产模式中,您需要编译的包,在开发模式下,您需要将页面指向webpack服务器)。要点是,为了利用所有webpack特性(如热重载和热响应组件替换),不能通过Scala服务器从静态文件为JavaScripts提供服务,它必须是webpack服务器。从理论上讲,可以将Scala服务器转换为某种代理,然而,下面的解决方案对我来说是有效的,而且非常简单(index.scala.html的一部分):
@if(play.Play.isDev()) {
<script src="http://localhost:9090/webpack-dev-server.js"></script>
<script src="http://localhost:9090/build/@{bundleName}.bundle.js"></script>
} else {
<script src="@routes.Assets.versioned("javascripts/" + bundleName + ".bundle.js")"></script>
}https://stackoverflow.com/questions/36944218
复制相似问题