scala - Obtener activos para compilar cuando se ejecuta a través de "activador run" en Play
playframework sbt (1)
Estoy usando Sass como mi preprocesador CSS, y estoy intentando que se ejecute a través de la canalización de activos. Intenté implementar este sassTask como una tarea de archivo de origen y como una tarea de activo web, pero estoy teniendo problemas en ambos sentidos.
Si ejecuto Sass como una tarea de origen (ver a continuación), se activa durante la activator run
cuando se solicita una página y se encuentran los archivos actualizados al recargar la página. El problema al que me estoy enfrentando es que los archivos CSS resultantes se están volcando directamente en target/web/public/main/lib
, en lugar de en los subdirectorios que reflejan los que están integrados en el directorio resources-managed
. No puedo imaginar cómo hacer que esto suceda.
En cambio, traté de implementar la compilación de Sass como una tarea de activos web (ver a continuación). Trabajando de esta manera, por lo que puedo decir, los resources-managed
no entran en juego, y entonces compilo mis archivos directamente en target/web/public/main/lib
. Estoy seguro de que no estoy haciendo esto de forma dinámica, pero no sé cómo hacerlo mejor. Pero el mayor problema aquí es que la tubería aparentemente no se ejecuta cuando se trabaja a través de la activator run
. Puedo hacer que se ejecute usando la activator stage
, pero realmente necesito que esto funcione en el flujo de trabajo de desarrollo normal para poder cambiar los archivos de estilo cuando el servidor de desarrollo se está ejecutando, al igual que con los archivos de Scala.
He intentado peinar a través de estos foros, a través de los documentos sbt-web, y a través de algunos de los complementos existentes, pero encuentro que este proceso es muy frustrante, debido a la complejidad de SBT y la opacidad de lo que realmente está sucediendo en el proceso de construcción.
Compilación Sass como una tarea de archivo de origen:
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
Compilación Sass como tarea de activos web:
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)
Creo que de acuerdo con la documentación relacionada con el Asset Pipeline , una tarea de archivo de origen es un camino a seguir:
Los ejemplos de tareas de archivos fuente como complementos son CoffeeScript, LESS y JSHint. Algunos de ellos toman un archivo fuente y producen un elemento web objetivo, por ejemplo, CoffeeScript produce archivos JS. Los complementos en esta categoría son mutuamente exclusivos en términos de su función, es decir, solo un complemento de CoffeeScript tomará fuentes de CoffeeScript y producirá archivos JS de destino. En resumen, los complementos de archivos de origen producen activos web.
Creo que lo que intentas alcanzar entra en esta categoría.
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
Explicación
Suponiendo que tiene un archivo sass en un directorio de app/assets/<whatever>
, y que desea crear archivos css en web/public/main/<whatever>
directorio web/public/main/<whatever>
, esto es lo que podría hacer.
Cree una tarea, que se leerá en los archivos del directorio / subdirectorios de la app/assets/<whatever>
, y los sassOutputDir
a nuestro sassOutputDir
definido.
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
}
Esto no es suficiente sin embargo. Si desea mantener la estructura del directorio, debe agregar su sassOutputDir
a los resourceDirectories in Assets
. Esto se debe a que las asignaciones en sbt-web se declaran así:
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
}
lo que significa que todos los archivos no asignados se asignan utilizando una estrategia flat
alternativa . Sin embargo, la solución es simple, simplemente agregue esto a su build.sbt
resourceDirectories in Assets += sassOutputDir.value
Esto asegurará que la estructura del directorio se preserve.