From 97d08e77c87cf44b3d3487cabcd4ef817eca9d36 Mon Sep 17 00:00:00 2001 From: WayneWang12 Date: Tue, 8 Feb 2022 20:27:39 +0800 Subject: [PATCH] 1. fix managed resource not found issue; 2. add versioned resource finder; --- src/main/g8/build.sbt | 2 +- .../$package$/VersionedResourceFinder.scala | 63 +++++++++++++++++++ .../src/main/twirl/$package$/main.scala.html | 6 +- 3 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 src/main/g8/server/src/main/scala/$package$/VersionedResourceFinder.scala diff --git a/src/main/g8/build.sbt b/src/main/g8/build.sbt index c7f222f..2506531 100644 --- a/src/main/g8/build.sbt +++ b/src/main/g8/build.sbt @@ -17,7 +17,7 @@ lazy val server = project "com.vmunier" %% "scalajs-scripts" % "1.2.0" ), Assets / WebKeys.packagePrefix := "public/", - Runtime / managedClasspath += (Assets / packageBin).value + Runtime / unmanagedClasspath += (Assets / packageBin).value ) .enablePlugins(SbtWeb, SbtTwirl, JavaAppPackaging) .dependsOn(shared.jvm) diff --git a/src/main/g8/server/src/main/scala/$package$/VersionedResourceFinder.scala b/src/main/g8/server/src/main/scala/$package$/VersionedResourceFinder.scala new file mode 100644 index 0000000..aeb6705 --- /dev/null +++ b/src/main/g8/server/src/main/scala/$package$/VersionedResourceFinder.scala @@ -0,0 +1,63 @@ +import java.net.URL +import scala.collection.concurrent.TrieMap +import scala.concurrent.blocking + +/** + * Copy from play framework. + */ +object VersionedResourceFinder { + // Sames goes for the minified paths cache. + private lazy val minifiedPathsCache = TrieMap[String, String]() + + private def resource(str: String): Option[URL] = Option( + getClass.getClassLoader.getResource(str) + ) + + private def minifiedPath(path: String): String = { + minifiedPathsCache.getOrElse( + path, { + def minifiedPathFor(delim: Char): Option[String] = { + val ext = path.reverse.takeWhile(_ != '.').reverse + val noextPath = path.dropRight(ext.length + 1) + val minPath = noextPath + delim + "min." + ext + Option(getClass.getResource(minPath)).map(_ => minPath) + } + + val maybeMinifiedPath = + minifiedPathFor('.').orElse(minifiedPathFor('-')).getOrElse(path) + minifiedPathsCache.put(path, maybeMinifiedPath) + maybeMinifiedPath + } + ) + } + + private lazy val digestCache = TrieMap[String, Option[String]]() + + lazy val digestAlgorithm: String = "md5" + + private def digest(path: String): Option[String] = { + digestCache.getOrElse( + path, { + val maybeDigestUrl: Option[URL] = + resource(path + "." + digestAlgorithm) + val maybeDigest: Option[String] = maybeDigestUrl.map { url => + val source = scala.io.Source.fromURL(url) + try source.getLines.mkString.trim + finally source.close() + } + if (maybeDigest.isDefined) digestCache.put(path, maybeDigest) + maybeDigest + } + ) + } + + def findAssetPath(base: String, path: String): String = blocking { + val minPath = minifiedPath(path) + digest(minPath) + .fold(minPath) { dgst => + val lastSep = minPath.lastIndexOf("/") + minPath.take(lastSep + 1) + dgst + "-" + minPath.drop(lastSep + 1) + } + .drop(base.length + 1) + } +} diff --git a/src/main/g8/server/src/main/twirl/$package$/main.scala.html b/src/main/g8/server/src/main/twirl/$package$/main.scala.html index 6608acc..497f3cb 100644 --- a/src/main/g8/server/src/main/twirl/$package$/main.scala.html +++ b/src/main/g8/server/src/main/twirl/$package$/main.scala.html @@ -8,6 +8,10 @@ @content - @scalajs.html.scripts("client", name => s"/assets/$name", name => getClass.getResource(s"/public/$name") != null) + @scalajs.html.scripts("client", + name => { + val versionedJs = VersionedResourceFinder.findAssetPath("public", s"public/$name") + s"/assets/$versionedJs" + }, name => getClass.getResource(s"/public/$name") != null)