我目前有两个项目;一个用于服务器端(Akka-HTTP),另一个用于客户端(ScalaJS)。客户端使用服务器端生成我想要提供的.js
个文件。为了让服务器端访问这些文件,我在服务器端项目中添加了这个build.sbt
条目:
lazy val server = project.in(file("server"))
...
.settings(
(resourceGenerators in Compile) <+= Def.task {
val f1 = (fullOptJS in client).value.data
val f1sm = f1.getParentFile / (f1.getName + ".map")
f1 :: f1sm :: (packageMinifiedJSDependencies in client).value :: Nil
}
)
但是,这会将.js
和.map
文件放在classes
文件夹的根目录中。因为我想像我这样服务我的资产:
pathPrefix("assets") {
...
pathPrefix("client") {
getFromResourceDirectory("<directory where .js and .map files are placed>")
}
}
强调#getFromResourceDirectory
方法,这不适用于我的classes
文件夹根目录中的资源。我的application.conf
与生成的文件位于同一目录中,这使得全世界都可以看到它。
我想要的是.js
目录的子目录中的.map
和classes
个文件。像client/
这样的东西,所以我可以使用像#getFromResourceDirectory
这样的getFromResourceDirectory("client")
方法,不要担心我的配置文件可供外界使用。
我的问题 - 如何实现这一目标?
我已经尝试添加:
lazy val client = project.in(file("client"))
...
.settings(inConfig(Compile)((fullOptJS :: packageMinifiedJSDependencies :: Nil)
.map(a => (crossTarget in a) ~= (_ / "client")))
)
到我的客户端项目,它只将生成的.js
和.map
文件放在客户端项目的客户端文件夹中scala-2.11
文件夹中:
但该设置不会传播到服务器端项目classes
文件夹:
答案 0 :(得分:3)
潜入SBT让我走下一条路;首先,我检查了server/compile:resourceGenerators
(使用sbt inspect server/compile:resourceGenerators
):
[info] ...
[info] Dependencies:
[info] server/compile:discoveredSbtPlugins
[info] server/compile:resourceManaged
[info] client/compile:packageMinifiedJSDependencies
[info] client/compile:fullOptJS
[info] Reverse dependencies:
[info] server/compile:managedResources
[info] ...
然后我检查了server/compile:managedResources
:
[info] ...
[info] Dependencies:
[info] server/compile:resourceGenerators
[info] Reverse dependencies:
[info] server/compile:resources
[info] ...
然后我检查了server/compile:resources
:
[info] ...
[info] Dependencies:
[info] server/compile:managedResources
[info] server/compile:unmanagedResources
[info] Reverse dependencies:
[info] server/compile:copyResources
[info] ...
然后我检查了server/compile:copyResources
:
[info] ...
[info] Defined at:
[info] (sbt.Defaults) Defaults.scala:295
[info] Dependencies:
[info] server/compile:classDirectory
[info] server/compile:resources
[info] server/compile:resourceDirectories
[info] server/compile:copyResources::streams
[info] ...
然后我在第295行检查了SBT的Defaults.scala
文件:
copyResources <<= copyResourcesTask
然后我检查了这个copyResourcesTask
定义:
def copyResourcesTask =
(classDirectory, resources, resourceDirectories, streams) map { (target, resrcs, dirs, s) =>
val cacheFile = s.cacheDirectory / "copy-resources"
val mappings = (resrcs --- dirs) pair (rebase(dirs, target) | flat(target))
s.log.debug("Copy resource mappings: " + mappings.mkString("\n\t", "\n\t", ""))
Sync(cacheFile)(mappings)
mappings
}
mappings
val在这种情况下非常重要。它创建由负责所有资源的各种任务创建的路径与这些资源将在target
文件夹中接收的最终路径之间的映射。 #rebase
方法(主要)负责这些映射,但如果资源路径中没有单个resourceDirectories
条目,则它会回退到#flat
方法。只需将我的客户端项目的crossTarget
路径添加到resourceDirectories
设置,rebase就会替换所有内容,直到client/<filename>
和.js
的{{1}}部分为止。文件而不是在.map
方法上退回,只替换#flat
部分,并结合此设置:
<filename>
正是我想要的行为。
添加到您的客户端项目:
lazy val client = project.in(file("client"))
...
.settings(inConfig(Compile)((fullOptJS :: packageMinifiedJSDependencies :: Nil)
.map(a => (crossTarget in a) ~= (_ / "client")))
)
添加到服务器端项目:
.settings(inConfig(Compile)((fullOptJS :: packageMinifiedJSDependencies :: Nil)
.map(a => (crossTarget in a) ~= (_ / "client")))
)
答案 1 :(得分:0)
@Martijn,thx为伟大的解决方案。
这对我很有帮助。 这里很少更新。
用于前端/客户端设置。
.settings(inConfig(Compile)(
(fullOptJS :: fastOptJS :: packageScalaJSLauncher
:: packageJSDependencies :: packageMinifiedJSDependencies :: Nil)
.map(f => (crossTarget in f) ~= (_ / "sjsout"))
))
用于后端/服务器设置。
.settings(
(resourceGenerators in Compile) += Def.task {
val fastJsOut = (fastOptJS in Compile in frontend).value.data
val fastJsSourceMap = fastJsOut.getParentFile / (fastJsOut.getName + ".map")
val fullJsOut = (fullOptJS in Compile in frontend).value.data
val fullJsSourceMap = fullJsOut.getParentFile / (fullJsOut.getName + ".map")
Seq(
fastJsOut,
fastJsSourceMap,
//fullJsOut,
//fullJsSourceMap,
(packageScalaJSLauncher in Compile in frontend).value.data,
(packageJSDependencies in Compile in frontend).value
//(packageMinifiedJSDependencies in Compile in frontend).value
)
}.taskValue,
(resourceDirectories in Compile) += (crossTarget in frontend).value,
watchSources ++= (watchSources in frontend).value
)