Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reverse Router should use minified assets in production automatically #2973

Merged
merged 1 commit into from
Jun 24, 2014

Conversation

huntc
Copy link
Contributor

@huntc huntc commented Jun 14, 2014

Serving assets is usually different between development and production mode. In dev mode, you want to serve the assets as they are, and in production they should be minified, compressed, versioned, and so on.

Using minified resources already works with RequireJS assets that go through r.js. Using versioned assets in prod mode works thanks to the Router's versioned method. Now it'd be nice to combine this, so Play serves versioned and minified LESS/CSS assets.

To put it in code:

@if(current.mode == Mode.Dev) {
  <link rel="stylesheet" media="screen" href="@routes.Assets.versioned("lib/bootstrap/css/bootstrap.css")" />
}
@if(current.mode == Mode.Prod) {
  <link rel="stylesheet" media="screen" href="@routes.Assets.versioned("lib/bootstrap/css/bootstrap.min.css")" />
}

should become

<link rel="stylesheet" media="screen" href="@routes.Assets.versionedAndModeAware("lib/bootstrap/css/bootstrap.css")" />

@jroper
Copy link
Member

jroper commented Jun 3, 2014

I think we can just have versioned handle this by default.

@gmethvin
Copy link
Member

gmethvin commented Jun 3, 2014

@jroper Do you mean doing the minification via the asset pipeline?

@huntc
Copy link
Contributor

huntc commented Jun 3, 2014

I think that @jroper means that the choice of using a .min or -min extension is one that can be made by the versioned method. The actual minification process is a build concern and not a runtime concern.

@gmethvin
Copy link
Member

gmethvin commented Jun 3, 2014

@huntc Right. I was just wondering as you'd need to make sure a minified version exists before you reference it. Creating the minified version via the asset pipeline would work for all assets consistently, but you could also use the minified versions already provided in some webjars.

@huntc
Copy link
Contributor

huntc commented Jun 3, 2014

Creating the minified version via the asset pipeline would work for all assets consistently, but you could also use the minified versions already provided in some webjars

That's already implemented i.e. if a WebJar contains a minified asset then that becomes available as per any other static asset. WebJars are extracted to disk and referenced via a lib/ folder.

BTW the asset controller already makes a similar sort of check for digest files in the versioned method. This processing is cached. We would do the same sort of thing for determining the correct extension to use.

@julienrf
Copy link
Contributor

julienrf commented Jun 3, 2014

Isn’t it possible to have both at and versioned handle the min suffix?

@mariussoutier
Copy link
Contributor Author

Or even merge at and versioned into one?

@jroper
Copy link
Member

jroper commented Jun 10, 2014

The question was whether we should break existing code or not... versioned requires a : Asset type in the routes file. We decided to not break source compatibility here, and introduced a new method.

@huntc
Copy link
Contributor

huntc commented Jun 14, 2014

I've attached a PR to this issue that has the asset controller check for the existence of .min.* and -min.* for all asset requests.

@huntc
Copy link
Contributor

huntc commented Jun 19, 2014

I've now updated this PR so that the checking for minified files is an option that may be disabled; just in case some transitive dependency within a WebJar (for example) appears and breaks things (doubtful). By default the option is enabled.

@mariussoutier
Copy link
Contributor Author

Thanks Christopher!

// Sames goes for the minified paths cache.
val minifiedPathsCache = TrieMap[String, String]()

lazy val checkForMinified = Play.configuration.getBoolean("assets.checkForMinified").getOrElse(true)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should document this in the assets documentation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should that preclude the merging of this? Also there are other options undocumented and in reality, I don't think this is going to be an issue.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well... we've got to start somewhere... :) I'll merge it, but only if you add a comment to this PR with a picture of a kitten in it. I like kittens.

jroper added a commit that referenced this pull request Jun 24, 2014
Reverse Router should use minified assets in production automatically
@jroper jroper merged commit 522d064 into playframework:master Jun 24, 2014
@jroper
Copy link
Member

jroper commented Jun 24, 2014

Backported to 2.3.x 1c9a5f2

@jroper jroper added this to the 2.3.1 milestone Jun 24, 2014
@huntc
Copy link
Contributor

huntc commented Jun 24, 2014

As you requested:

download

@huntc huntc deleted the min-assets branch June 24, 2014 04:41
@jroper
Copy link
Member

jroper commented Jun 24, 2014

Awww.... how cute!

).toString
}

implicit def stringPathBindable(implicit rrc: ReverseRouteContext) = new PathBindable[String] {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't notice this one before. Since it's on the Asset companion object, it never gets used unless you add it to the router imports (the assetPathBindable below does get used, because it provides a path bindable for Asset and is on the Asset companion object, whereas this provides a path bindable for String, and the compiler won't look at the Asset companion object for a path bindable for String). And if you did do that, any reverse route that accepted a String path parameter (eg /user/:username) will use it, and will throw an exception from the code above (with message "Asset path bindable must be used in combination with an action that accepts a path parameter"). I think this should therefore be deleted, I don't think there's any purpose for it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure, but the idea was to provide a string path bindable for situations where the reverse router is required in an assets.at scenario as opposed to assets.versioned. The tests should cover this scenario.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't see any tests that cover it - but the fact remains that an implicit PathBindable[String] in scope will apply to all string parameters, there's no way to make it differentiate between assets and non assets parameters, this is why we had to introduce the Asset type in the first place, otherwise we could have written a PathBindable[String] and have Assets.at use that. The first thing it does is call pathFromParams(rrc) which throws an exception if there's no fixed parameter in the route called path.

@jzahka
Copy link

jzahka commented Apr 7, 2016

@mariussoutier @jroper
I'm having an issue where Play is grabbing the minified asset in Dev mode.

<script src="@routes.Assets.versioned("lib/angularjs/angular.js")"></script>

resolves to (in Dev mode)

<script src="/assets/lib/angularjs/angular.min.js"></script>

I'm definitely in Dev mode, any intuition on what may be happening?
Let me know if you need more details.

@marcospereira
Copy link
Member

Hello @jzahka,

The mailing list would be a better place to discuss this and get more information about your application, etc. If we decide that there is a bug, we can open an issue here. :-)

@mkurz
Copy link
Member

mkurz commented Jul 1, 2016

@jzahka Is right, this is a bug in Play. I can confirm in dev mode also the .min file is served.
Pull request with the fix: #6291
@jzahka Please see #5173 for a workaround.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants