Reputation: 1267
I want Play to send GZipped JS and CSS to the browser. In the Build.scala, I added
val gzipAssets = TaskKey[Seq[File]]("gzip-assets", "GZIP all assets")
lazy val gzipAssetsSetting = gzipAssets <<= gzipAssetsTask
lazy val gzipAssetsTask = (gzippableAssets, streams) map {
case (finder: PathFinder, s: TaskStreams) => {
finder.get.map { file =>
val gzTarget = new File(file.getAbsolutePath + ".gz")
IO.gzip(file, gzTarget)
s.log.info("Compressed " + file.getAbsolutePath + " " + file.length / 1000 + " k => " + gzTarget.getName + " " + gzTarget.length / 1000 + " k")
gzTarget
}
}
}
val main = PlayProject(appName, appVersion, appDependencies, mainLang = JAVA).settings(
// Twitter Bootstrap v2.0.1 compilation (https://plus.google.com/u/0/108788785914419775677/posts/QgyUF9cXPkv)
lessEntryPoints <<= (sourceDirectory in Compile)(base => ((base / "assets" / "stylesheets" / "twitterbootstrap" / "styles.less"))),
// set up gzip of assets
gzippableAssets <<= (resourceManaged in (ThisProject))(dir => ((dir ** "*.js") +++ (dir ** "*.css"))),
gzipAssetsSetting,
playPackageEverything <<= playPackageEverything dependsOn gzipAssets
).settings( ...
which generates me files in the target when I dist :
[info] Compressed /Users/wimha/Documents/**/target/scala-2.9.1/resource_managed/main/public/stylesheets/twitterbootstrap/styles.min.css 183 k => styles.min.css.gz 27 k
but then, in prod, the file is not available :
Failed to load resource: the server responded with a status of 404 (Not Found) http://ec2-54-228-70-193.eu-west- 1.compute.amazonaws.com/assets/stylesheets/twitterbootstrap/styles.min.css.gz
I have 2 questions :
Thanks Julien
Upvotes: 0
Views: 551
Reputation: 21
I lost hours looking for a solution for the same problem.
Try this: http://play.lighthouseapp.com/projects/82401/tickets/841-gzip-assets. It will package the .gz
files whether you run play dist
or play stage
.
Given that Play is already smart enough to serve assets gzipped when a corresponding .gz file exists, it would make sense to gzip assets when doing 'stage' or 'dist'. Some reverse proxies can gzip resources, but this is either less efficient (if done for each request) or more complicated (if resources are cached, and can end up being stale).
Here's a half-baked solution using the Build.scala:
val gzippableAssets = SettingKey[PathFinder]("gzippable-assets", "Defines the files to gzip") val gzipAssets = TaskKey[Seq[File]]("gzip-assets", "gzip all assets") lazy val gzipAssetsSetting = gzipAssets <<= gzipAssetsTask dependsOn (copyResources in Compile) lazy val gzipAssetsTask = (gzippableAssets, streams) map { case (finder: PathFinder, s: TaskStreams) => { var count = 0 var files = finder.get.map { file => val gzTarget = new File(file.getAbsolutePath + ".gz") IO.gzip(file, gzTarget) count += 1; gzTarget } s.log.info("Compressed " + count + " asset(s)") files } } val main = PlayProject(appName, appVersion, appDependencies, mainLang = JAVA).settings( ... gzippableAssets <<= (classDirectory in Compile)(dir => (dir ** ("*.js" || "*.css" || "*.html"))), gzipAssetsSetting, playPackageEverything <<= playPackageEverything dependsOn gzipAssets )
Upvotes: 1