I was able to load the sbt-uglify 1.0.3 plugin in my Play Framework 2.3.1 app. Loading of the non-minified javascripts is pretty straightforward, but loading the minified versions seems to be impossible.
In my template I use <script>
tags similar to this:
<script src="@routes.Assets.at("javascripts/app.js")"></script>
In dev mode, the non-minified javascript version is loaded, which is fine. In prod mode (using activator start
) I see sbt-uglify generating the minified versions to the target/web/uglify/build
folder, but because I didn't change the above <script>
tag line in my templates, the non-minified versions of the javascripts files are loaded.
Is there a way to do a prod-only mapping of such routes to load the minified versions?
The issue Reverse Router should use minified assets in production automatically was fixed in Play 2.3.1 that exactly matches your requirement.
According to Play 2.3.1 Changelog:
The behaviour of the Assets reverse router has changed, if minified versions of assets exist, it now returns a URL for those instead. To disable this behaviour, set
assets.checkForMinified=true
inapplication.conf
.
NOTE It should rather read set assets.checkForMinified=false
, but anyway...
What follows works in production mode only so start the application with activator start
not run
or use the generated start scripts (after stage
).
The behaviour of using minified versions of assets in production should be enabled by default in the version of Play with @routes.Assets.versioned
(not routes.Assets.at
).
It does require that the appropriate route declaration in conf/routes
is:
GET /assets/*file controllers.Assets.versioned(path="/public", file: Asset)
What I found a bit unclear at first was the order of elements in pipelineStages
as well as the requirement to include sbt-rjs in it.
And just after I'd written the sentence about the order I found in the section "RequireJS" in Play 2.3 Migration Guide:
The order of stages is significant. You first want to optimize the files, produce digests of them and then produce gzip versions of all resultant assets.
I've also found in Play 2.3 Migration Guide in the section "Closure Compiler":
UglifyJS 2 is presently provided via the RequireJS plugin (described next). The intent in future is to provide a standalone UglifyJS 2 plugin also for situations where RequireJS is not used.
It all started with the answer to Play 2.3 sbt-web plugin Javascript minification.
So, the below pipelineStages
is the working one - mind the order and rjs
:
pipelineStages := Seq(rjs, uglify, digest, gzip)
project/plugins.sbt
used was as follows:
resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/"
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.3.5")
addSbtPlugin("com.typesafe.sbt" % "sbt-digest" % "1.0.0")
addSbtPlugin("com.typesafe.sbt" % "sbt-uglify" % "1.0.3")
addSbtPlugin("com.typesafe.sbt" % "sbt-gzip" % "1.0.0")
addSbtPlugin("com.typesafe.sbt" % "sbt-rjs" % "1.0.6")
Don't forget to create an empty app/assets/javascripts/main.js
file to let sbt-rjs
do its job.
As a test, I created a Play application with activator new playApp play-scala
and applied the above changes in the build as well as in app/views/main.scala.html
that ultimately looked as follows (note @routes.Assets.versioned
):
@(title: String)(content: Html)
<!DOCTYPE html>
<html>
<head>
<title>@title</title>
<link rel="stylesheet" media="screen" href="@routes.Assets.versioned("stylesheets/main.css")">
<link rel="shortcut icon" type="image/png" href="@routes.Assets.versioned("images/favicon.png")">
<script src="@routes.Assets.versioned("javascripts/hello.js")" type="text/javascript"></script>
</head>
<body>
@content
</body>
</html>
Executing activator start
and calling curl http://localhost:9000
gives (formatting's mine for the sake of readability):
➜ play-uglify curl http://localhost:9000
<!DOCTYPE html>
<html>
<head>
<title>Welcome to Play</title>
<link rel="stylesheet" media="screen" href="/assets/stylesheets/d41d8cd98f00b204e9800998ecf8427e-main.css">
<link rel="shortcut icon" type="image/png" href="/assets/images/84a01dc6c53f0d2a58a2f7ff9e17a294-favicon.png">
<script src="/assets/javascripts/4302136334616ae0605d47a1932ee262-hello.min.js" type="text/javascript"></script>
</head>
<body>
<h1>Your new application is ready.</h1>
</body>
</html>
Note 4302136334616ae0605d47a1932ee262-hello.min.js
and the non-JavaScript resources digested.