如何将npm/gulp/bower构建过程集成到sbt中?

9
我有两个独立的Git仓库,一个是使用sbt构建的Scala服务器,另一个是使用npm/bower/gulp构建的WebApp前端。
在服务器仓库中,我已经有了一个任务来构建一个独立的jar(不是标准的package任务);在前端仓库中,我可以使用npm install && npm run build 命令构建,会生成一个独立的目录_public
现在我想在sbt构建jar任务期间包括UI目录_public,请问是否有更好的方法实现这一点,而不是手动在sbt中启动外部进程来调用npm?

生成外部进程有什么问题吗? - Rüdiger Klaehn
3个回答

6
当前 sbt-web 和其所依赖的 webjars 状态不佳,它们已经跟不上 Node.js 和 npm 的增长速度。例如,sbt-hbs 插件已经不再维护,而我的经验表明它无法与任何 Node.js 8 或更高版本配合使用。在某些基于 webjar 的前端工具中,对 sbt 1.0 的支持也不完整。
因此,与问题所建议的不同,直接通过 sbt 生成 npm 进程来构建前端是一个更好的解决方案。 这个来自另一个问题的答案给出了一种足够可靠的方法,可以从 sbt 中调用 npm,我在这里只是为了完整起见进行复制。
buildFrontend := {
  val s: TaskStreams = streams.value
  val shell: Seq[String] = if (sys.props("os.name").contains("Windows")) Seq("cmd", "/c") else Seq("bash", "-c")
  val npmInstall: Seq[String] = shell :+ "npm install"
  val npmTest: Seq[String] = shell :+    "npm run test"
  val npmLint: Seq[String] = shell :+    "npm run lint"
  val npmBuild: Seq[String] = shell :+   "npm run build"
  s.log.info("building frontend...")
  if((npmInstall #&& npmTest #&& npmLint #&& npmBuild !) == 0) {
    s.log.success("frontend build successful!")
  } else {
    throw new IllegalStateException("frontend build failed!")
  }
}

3
如果您的前端使用NPM和Gulp构建应用程序,则需要使用NodeJS引擎(或者可能是Rhino或Nashorn这样的JVM引擎?不确定),并且它需要外部进程来运行。
你需要考虑的问题是:你真的想将后端的部署与前端的部署耦合在一起吗?难道没有任何情况,你只想部署一个而不是另一个吗?
我认为使用SBT部署前端很不错,但如果您的前端很复杂,最好将其与SBT分开。
您的JS应用程序不一定需要作为Play公共资产提供服务,您可以将其部署到自己的位置,并在Play HTML模板中引用它。

0

我同意Sebastien的想法,建议前端开发(甚至部署)与后端分离。因为我自己正在学习这个课题。

除此之外,可以看一下SbtWeb(任务工作流)和WebJars(包管理)。SbtWeb有几个插件可以涵盖基本内容(uglify、concat、filter),有些情况下如果安装了node,它甚至可以直接使用它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接