gpt4 book ai didi

scala - 在 Play 中通过 "activator run"运行时获取要编译的资源

转载 作者:行者123 更新时间:2023-12-02 19:32:00 27 4
gpt4 key购买 nike

我使用 Sass 作为我的 CSS 预处理器,并且我试图让它通过 Assets 管道运行。我尝试将此 sassTask 实现为源文件任务和 Web Assets 任务,但两种方式都遇到了问题。

如果我将 Sass 作为源任务运行(见下文),当请求页面并在页面重新加载时找到更新的文件时,它会在激活器运行期间被触发。我遇到的问题是,生成的 CSS 文件都直接转储到 target/web/public/main/lib 中,而不是转储到反射(reflect)它们构建到的子目录中资源管理目录。我不知道如何实现这一点。

相反,我尝试将 Sass 编译实现为 Web Assets 任务(见下文)。据我所知,以这种方式工作,资源管理不会发挥作用,因此我将文件直接编译到target/web/public/main/lib >。我确信我做得不够动态,但我不知道如何做得更好。但这里最大的问题是,在通过 activator run 工作时,管道显然没有运行。我可以使用激活器阶段运行它,但我确实需要它在常规开发工作流程中工作,以便我可以在开发服务器运行时更​​改样式文件,与 Scala 文件相同。

我尝试梳理这些论坛、sbt-web 文档以及一些现有的插件,但由于 SBT 的复杂性和实际内容的不透明性,我发现这个过程非常令人沮丧。发生在构建过程中。

Sass 编译作为源文件任务:

lazy val sassTask = TaskKey[Seq[java.io.File]]("sassTask", "Compiles Sass files")

sassTask := {
import sys.process._
val x = (WebKeys.nodeModules in Assets).value
val sourceDir = (sourceDirectory in Assets).value
val targetDir = (resourceManaged in Assets).value
Seq("sass", "-I", "target/web/web-modules/main/webjars/lib/susy/sass", "--update", s"$sourceDir:$targetDir").!
val sources = sourceDir ** "*.scss"
val mappings = sources pair relativeTo(sourceDir)
val renamed = mappings map { case (file, path) => file -> path.replaceAll("scss", "css") }
val copies = renamed map { case (file, path) => file -> targetDir / path }
copies map (_._2)
}

sourceGenerators in Assets <+= sassTask

Sass 编译为 Web Assets 任务:

lazy val sassTask = taskKey[Pipeline.Stage]("Compiles Sass files")

sassTask := {
(mappings: Seq[PathMapping]) =>
import sys.process._
val sourceDir = (sourceDirectory in Assets).value
val targetDir = target.value / "web" / "public" / "main"
val libDir = (target.value / "web" / "web-modules" / "main" / "webjars" / "lib" / "susy" / "sass").toString
Seq("sass", "-I", libDir, "--update", s"$sourceDir:$targetDir").!
val sources = sourceDir ** "*.scss"
val mappings = sources pair relativeTo(sourceDir)
val renamed = mappings map { case (file, path) => file -> path.replaceAll("scss", "css") }
renamed
}

pipelineStages := Seq(sassTask)

最佳答案

我认为根据与Asset Pipeline相关的文档,源文件任务是一种方法:

Examples of source file tasks as plugins are CoffeeScript, LESS and JSHint. Some of these take a source file and produce a target web asset e.g. CoffeeScript produces JS files. Plugins in this category are mutually exclusive to each other in terms of their function i.e. only one CoffeeScript plugin will take CoffeeScript sources and produce target JS files. In summary, source file plugins produce web assets.

我认为您想要实现的目标属于这一类。

TL;DR; -build.sbt

val sassTask = taskKey[Seq[File]]("Compiles Sass files")

val sassOutputDir = settingKey[File]("Output directory for Sass generated files")

sassOutputDir := target.value / "web" / "sass" / "main"

resourceDirectories in Assets += sassOutputDir.value

sassTask := {
val sourceDir = (sourceDirectory in Assets).value
val outputDir = sassOutputDir.value
val sourceFiles = (sourceDir ** "*.scss").get
Seq("sass", "--update", s"$sourceDir:$outputDir").!
(outputDir ** "*.css").get
}

sourceGenerators in Assets += sassTask.taskValue

说明

假设你有 sass 文件在 app/assets/<whatever>目录,并且您要在 web/public/main/<whatever> 中创建 css 文件目录,这就是你可以做的。

创建一个任务,该任务将读取 app/assets/<whatever> 中的文件目录和子目录,并输出到我们定义的sassOutputDir .

val sassTask = taskKey[Seq[File]]("Compiles Sass files")

val sassOutputDir = settingKey[File]("Output directory for Sass generated files")

sassOutputDir := target.value / "web" / "sass" / "main"

resourceDirectories in Assets += sassOutputDir.value

sassTask := {
val sourceDir = (sourceDirectory in Assets).value
val outputDir = sassOutputDir.value
val sourceFiles = (sourceDir ** "*.scss").get
Seq("sass", "--update", s"$sourceDir:$outputDir").!
(outputDir ** "*.css").get
}

但这还不够。如果你想保留目录结构,你必须添加 sassOutputDirresourceDirectories in Assets 。这是因为 sbt-web 中的映射是这样声明的:

mappings := {
val files = (sources.value ++ resources.value ++ webModules.value) ---
(sourceDirectories.value ++ resourceDirectories.value ++ webModuleDirectories.value)
files pair relativeTo(sourceDirectories.value ++ resourceDirectories.value ++ webModuleDirectories.value) | flat
}

这意味着所有未映射的文件都使用 alternative 进行映射flat战略。然而解决方法很简单,只需将其添加到您的 build.sbt 中即可。

resourceDirectories in Assets += sassOutputDir.value

这将确保保留目录结构。

关于scala - 在 Play 中通过 "activator run"运行时获取要编译的资源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24286551/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com