Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[Asset] Versionize assets according to a Manifest #19418

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

Closed
wants to merge 1 commit into from
Closed

[Asset] Versionize assets according to a Manifest #19418

wants to merge 1 commit into from

Conversation

psrpinto
Copy link
Contributor

@psrpinto psrpinto commented Jul 25, 2016

Q A
Branch? master
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets
License MIT
Doc PR

Overview

Add the ability for the Asset component to version assets according to a Manifest. A manifest is simply a map of paths to their versioned selves, for example:

/images/foo.png => /images/foo-123abc.png
/css/bar.css    => /css/bar-789xyz.css

This is achieved by a ManifestVersionStrategy class whose constructor takes an array representing the manifest:

$manifest = array(
    '/images/foo.png' => '/images/foo-123abc.png',
    '/css/bar.css'    => '/css/bar-789xyz.css',
);

$versionStrategy = new ManifestVersionStrategy($manifest);

// Returns '/images/foo-123abc.png'
$versionStrategy->applyVersion('/images/foo.png');

// Returns '/css/bar-789xyz.css'
$versionStrategy->applyVersion('/css/bar.css');

// Returns an empty string
$versionStrategy->getVersion('/images/foo.png');

Motivation

To optimize client-side caching, an asset's URL should only change when its contents change. A simple way to achieve this is to append a hash of the file's content to the name of the file, as part of the build process.

Many frontend build tools do this and at the same time generate a manifest that maps the file's original name to its versioned name.

Supporting this use case would make it easy to "hook" frontend build tools with the Asset component.

A starting point

This PR is deliberately simple because it's not the concern of the Asset component to produce the manifest or even to parse it. However, having the Asset component include a ManifestVersionStrategy would pave the way for improved support further up the stack (framework-bundle? symfony-standard?).

If this PR is accepted and/or if its usefulness is acknowleged I'm willing to further contribute "up the stack" to better support this use case.

*/
public function __construct($manifest)
{
if (!is_array($manifest)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not simply __construct(array $manifest)?

Copy link
Member

Choose a reason for hiding this comment

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

much better

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You're right, fixed it.

@stof
Copy link
Member

stof commented Jul 25, 2016

I have something similar in a WIP (outside the core for now, to experiment with it before being restricted by the Symfony release schedule and its BC rules). However, in my case, I'm using a mapping path => version (similar to what gulp-buster creates), and then using the strategy to alter the path based on this version (making it suitable for cases where you use ?=v<version> too.

Your proposal has a big drawback: it is not compatible with getVersion(). So I'm not in favor of adding it in the core as is. I suggest you to maintain it in your own bundle for now, to experiment with the associated tooling first.

@psrpinto
Copy link
Contributor Author

@stof

Your proposal has a big drawback: it is not compatible with getVersion()

Not being compatible with getVersion() indeed felt like a smell while I was preparing this PR. I agree that a path => version mapping makes more sense for the Asset component, even though I don't really understand the usefulness of the getVersion method by itself, but that's off topic.

However, in my case, I'm using a mapping path => version

The only drawback I see with the name of the file not being altered across versions is with CDNs that would not support query string parameters. I don't have much experience with CDNs myself but a quick google search shows that both CloudFront and Akamai support query string parameters, so this might not be an issue.

I suggest you to maintain it in your own bundle for now, to experiment with the associated tooling first.

I'm already using this strategy at regularjack/frontend-bundle. I'm looking into implementing your alternative (using a query string parameter) too.

Any chance you can link your WIP here?

@stof
Copy link
Member

stof commented Jul 25, 2016

@regularjack my WIP is currently only on my computer. I haven't pushed the code yet

I don't have much experience with CDNs myself but a quick google search shows that both CloudFront and Akamai support query string parameters, so this might not be an issue.

From a quick search, MaxCDN and Cloudflare support it as well

@fabpot
Copy link
Member

fabpot commented Sep 14, 2016

Closing for the reasons explained by @stof

@regularjack Can you create an issue so that we keep track of the feature request? Thanks.

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.

5 participants