带有sbt本机打包程序的附加资源生成器

带有sbt本机打包程序的附加资源生成器,sbt,sbt-native-packager,Sbt,Sbt Native Packager,我有一个子模块,它是通过调用外部命令编译的。我想将生成的文件包含到jar中。所以我写了一个任务: ``` myTask:={ 导入sys.process.stringSeqToProcess 我的命令! } Compile+=baseDirectory.value/“dist”中的UnmanagedResourceDirectory cleanFiles base/“dist”} key.`package`有几个选项可以解决这个问题。我假设您想将dist文件夹添加到生成的应用程序jar中 您的配

我有一个子模块,它是通过调用外部命令编译的。我想将生成的文件包含到jar中。所以我写了一个任务: ```

myTask:={
导入sys.process.stringSeqToProcess
我的命令!
}
Compile+=baseDirectory.value/“dist”中的UnmanagedResourceDirectory
cleanFiles base/“dist”}

key.`package`有几个选项可以解决这个问题。我假设您想将
dist
文件夹添加到生成的应用程序jar中

您的配置不起作用,因为
阶段
不依赖于
。这将导致未调用
npmBuildTask

1.向后台添加依赖项 解决此问题的最简单方法是简单地将
npmBuildTask
作为依赖项添加到
stage

stage <<= stage dependsOn npmBuildTask.toTask
或者您可以在
AutoPlugin
中提取此信息,以区分“什么”和“如何”

3.自动加载和资源生成器 创建
project/NpmPlugin.scala
并添加以下内容

import sbt._
import sbt.Keys._
import sbt.plugins.JvmPlugin

object NpmPlugin extends AutoPlugin {

  override val requires = JvmPlugin
  override val trigger = AllRequirements

  object autoImport {
    val npmBuildTask = TaskKey[Seq[File]]("npm-build-task", "Runs npm and builds the application")
  }

  import autoImport._

  override def projectSettings: Seq[Setting[_]] = Seq(
    // define a custom target directory for npm
    target in npmBuildTask := target.value / "npm",
    // the actual build task
    npmBuildTask := {
      val npmSource = (target in npmBuildTask).value
      val npmTarget = (resourceManaged in Compile).value / "dist"
      // run npm here, which generates the necessary values
      streams.value.log.info("running npm generator")
      // move generated sources to target folder
      IO.copyDirectory(npmSource, npmTarget)
      // recursively get all files in the npmTarget
      (npmTarget ***).get
    },
    resourceGenerators in Compile += npmBuildTask.taskValue
  )

}
然后,
build.sbt
将如下所示

resourceGenerators in Compile += Def.task {
  streams.value.log.info("running npm generator")
  val base = (resourceManaged in Compile).value / "dist"

  // A resource generator returns a Seq[File]. This is just an example
  List("index.js", "test.js").map { file =>
    IO.writeLines(base / file, List("var x = 1"))
    base / file
  }
}.taskValue
name := "resource-gen-test"
version := "1.0"

enablePlugins(JavaAppPackaging)
相当干净:)

4.使用映射 最后但并非最不重要的一点是,您可以使用
映射
。它们是在sbt中驱动大量包生成的低级细节。此解决方案的主要思想是

  • 创建一个返回映射定义的任务(
    Seq[(文件,字符串)]
  • 将其附加到适当的映射
这种方法的优点是,您可以更灵活地放置映射

import sbt._
import sbt.Keys._
import sbt.plugins.JvmPlugin
import com.typesafe.sbt.SbtNativePackager.Universal
import com.typesafe.sbt.SbtNativePackager.autoImport.NativePackagerHelper._

object NpmMappingsPlugin extends AutoPlugin {

  override val requires = JvmPlugin
  override val trigger = AllRequirements

  object autoImport {
    val npmBuildTask = TaskKey[Seq[(File, String)]]("npm-build-task", "Runs npm and builds the application")
  }

  import autoImport._

  override def projectSettings: Seq[Setting[_]] = Seq(
    // define a custom target directory for npm
    target in npmBuildTask := target.value / "npm" / "dist",
    // the actual build task
    npmBuildTask := {
      val npmTarget = (target in npmBuildTask).value
      // run npm here, which generates the necessary values
      streams.value.log.info("running npm generator")   
      // recursively get all files in the npmTarget
      // contentOf(npmTarget) would skip the top-level-directory
      directory(npmTarget)
    },
    // add npm resources to the generated jar
    mappings in (Compile, packageBin) ++= npmBuildTask.value,

    // add npm resources to resulting package
    mappings in Universal ++= npmBuildTask.value
  )

}
正如您在这种方法中看到的,我们可以轻松地将结果文件添加到不同的映射中

import sbt._
import sbt.Keys._
import sbt.plugins.JvmPlugin
import com.typesafe.sbt.SbtNativePackager.Universal
import com.typesafe.sbt.SbtNativePackager.autoImport.NativePackagerHelper._

object NpmMappingsPlugin extends AutoPlugin {

  override val requires = JvmPlugin
  override val trigger = AllRequirements

  object autoImport {
    val npmBuildTask = TaskKey[Seq[(File, String)]]("npm-build-task", "Runs npm and builds the application")
  }

  import autoImport._

  override def projectSettings: Seq[Setting[_]] = Seq(
    // define a custom target directory for npm
    target in npmBuildTask := target.value / "npm" / "dist",
    // the actual build task
    npmBuildTask := {
      val npmTarget = (target in npmBuildTask).value
      // run npm here, which generates the necessary values
      streams.value.log.info("running npm generator")   
      // recursively get all files in the npmTarget
      // contentOf(npmTarget) would skip the top-level-directory
      directory(npmTarget)
    },
    // add npm resources to the generated jar
    mappings in (Compile, packageBin) ++= npmBuildTask.value,

    // add npm resources to resulting package
    mappings in Universal ++= npmBuildTask.value
  )

}

但是,如果您需要这种灵活性,我只建议您使用这种方法,因为它需要更多的本地packager知识。

回答得很好,谢谢!我自己找到了基于映射的解决方案,但这是在黑暗中行走,现在我明白我在做什么了:)。