首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >自定义sbt任务,该任务编译JavaScript并仅在生产模式下激活。

自定义sbt任务,该任务编译JavaScript并仅在生产模式下激活。
EN

Stack Overflow用户
提问于 2016-04-29 17:25:45
回答 1查看 779关注 0票数 3

我知道我可以编写自己的sbt任务,并且可以在它们之间创建依赖关系。任务层次结构在我看来有点复杂,这就是我正在努力解决的问题:,我不知道我的任务应该依赖于哪些任务,。情况就是这样。

我的Scala/Play web应用程序有一个非常复杂的前端,用JavaScript/React编写,它是用webpack编译的。在开发期间,我使用webpack-dev-server。它更快,并且支持像热重装这样的功能。然而,在生产模式下部署时,我希望使用sbt构建我的前端。这意味着对于sbt startsbt 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任务,如下所示:

代码语言:javascript
复制
(copyResources in Compile) <<= (copyResources in Compile) dependsOn buildJs

这似乎是可行的,但问题是,在开发模式(即buildJs)中运行时,也会触发自定义任务( sbt run)。这是我想要避免的。

我尝试过的另一种方法是将JavaScript直接编译到target文件夹。这些文件出现在正确的位置,但是应用程序没有意识到它们。他们根本就没时间。获取任何这些文件的HTTP请求都返回空响应。

有什么想法吗?

EN

回答 1

Stack Overflow用户

发布于 2016-05-02 18:34:47

因此,应该依赖于我的自定义任务(构建JavaScript的任务)的任务是stagedist。这是我的build.sbt

代码语言:javascript
复制
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 startsbt dist激活,而不用于sbt run (=开发模式)。为此,我使用了一个单独的webpack-dev-server实例,它处理JavaScript编译。

有可能有一个更简单的方法,但这才是对我有用的方法。

如果您决定使用这种方式将webpack集成到sbt中,最后一个缺失的难题是根据当前模式加载适当的JavaScript文件(在生产模式中,您需要编译的包,在开发模式下,您需要将页面指向webpack服务器)。要点是,为了利用所有webpack特性(如热重载和热响应组件替换),不能通过Scala服务器从静态文件为JavaScripts提供服务,它必须是webpack服务器。从理论上讲,可以将Scala服务器转换为某种代理,然而,下面的解决方案对我来说是有效的,而且非常简单(index.scala.html的一部分):

代码语言:javascript
复制
@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>
}
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36944218

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档