5

CSS プリプロセッサとして Sass を使用しており、アセット パイプライン経由で実行しようとしています。この sassTask をソース ファイル タスクおよび Web アセット タスクとして実装しようとしましたが、どちらの方法でも問題が発生しています。

Sass をソース タスクとして実行すると (以下を参照)、activator runページが要求されたときに Sass がトリガーされ、ページのリロード時に更新されたファイルが見つかります。私が直面している問題は、結果として得られる CSS ファイルがtarget/web/public/main/lib、ディレクトリの下に組み込まれているものを反映するサブディレクトリではなく、すべて に直接ダンプされることresources-managedです。これを実現する方法がわかりません。

代わりに、Sass コンパイルを Web アセット タスクとして実装してみました (以下を参照)。私が知る限り、この方法で作業しても意味がありresources-managedません。そのため、ファイルを直接 にコンパイルしますtarget/web/public/main/lib。私はこれを十分に動的に行っていないと確信していますが、それ以上の方法はわかりません。しかし、ここでの最大の問題は、 を処理しているときにパイプラインが明らかに実行されないことactivator runです。を使用して実行できactivator stageますが、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

Web アセット タスクとしての Sass コンパイル:

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)
4

1 に答える 1

8

Asset Pipelineに関連するドキュメントによると、ソース ファイル タスクは次のような方法であると思います。

プラグインとしてのソース ファイル タスクの例としては、CoffeeScript、LESS、および JSHint があります。これらのいくつかは、ソース ファイルを取得してターゲット Web アセットを生成します。たとえば、CoffeeScript は JS ファイルを生成します。このカテゴリのプラグインは、その機能に関して相互に排他的です。つまり、1 つの CoffeeScript プラグインだけが CoffeeScript ソースを受け取り、ターゲット JS ファイルを生成します。要約すると、ソース ファイル プラグインは Web アセットを生成します。

あなたが達成しようとしていることは、このカテゴリーに分類されると思います。

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>ディレクトリにcssファイルを作成したい場合web/public/main/<whatever>、これができることです。

ディレクトリとサブディレクトリ内のファイルを読み取り、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
}

しかし、これでは十分ではありません。ディレクトリ構造を維持したい場合は、 に追加する必要がsassOutputDirありますresourceDirectories 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
}

これは、マップされていないすべてのファイルが別の flat戦略を使用してマップされることを意味します。ただし、修正は簡単です。これをbuild.sbt

resourceDirectories in Assets += sassOutputDir.value

これにより、ディレクトリ構造が確実に保持されます。

于 2014-06-19T13:33:35.633 に答える