One of the main features of the Asset component is the ability to manage the versioning of the application's assets. Asset versions are commonly used to control how these assets are cached. For example, if you define this config for your assets:
1 2 3 4 5
# app/config/config.yml
framework:
# ...
assets:
version: 'v2'
And use the asset()
function to reference your assets in the templates:
1
<img src="{{ asset('images/logo.png') }}" />
Then, the URL generated for the image will be /images/logo.png?v2
. This is
managed by the StaticVersionStrategy
class, which is one of the built-in
versioning strategies provided by Asset.
The static strategies that append some changing values to the query string are becoming less and less popular, so developers need to create a custom versioning strategy to keep up with the latest trends in asset versioning.
That's why in Symfony 3.3 we've decided to add a new versioning strategy based on a JSON file manifest. This is the strategy used by popular tools such as Webpack, which generate a JSON file mapping all source file names to their corresponding output file. For example:
1 2 3 4 5
{
"css/app.css": "build/css/app.b916426ea1d10021f3f17ce8031f93c2.css",
"js/app.js": "build/js/app.13630905267b809161e71d0f8a0c017b.js"
"...": "..."
}
The random-looking part of the paths is called "chunk hash" in Webpack and it's a hash of the file contents. This is the best strategy for long-term asset caching, because the hash, and therefore the asset path, will change as soon as you make any change in the asset file, busting any existing cache.
In order to use this strategy in a Symfony application, define the new
json_manifest_path
asset config option:
1 2 3 4 5
# app/config/config.yml
framework:
# ...
assets:
json_manifest_path: '%kernel.root_dir%/../web/build/manifest.json'
Then, keep using the asset()
function as before:
1
<link href="{{ asset('/css/app.css') }}">
The new version strategy will turn that link into <link href="/build/css/app.b916426ea1d10021f3f17ce8031f93c2.css">
and it will update it as soon as you change the original asset file.
Thanks for this feature, BTW should be json_manifest_path: '%kernel.root_dir%/../web/build/manifest.json' not %kernel.root_dir/../web/build/manifest.json%'
@Patrik fixed! Thanks.
The manifest example in the article is also inversed: it's file path to hashed path dictionary.
https://github.com/symfony/asset/blob/master/Tests/fixtures/manifest-valid.json
@Ivan I've made some changes in that part of the post. Thanks!
Is this useful when I wish to avoid caching problem like this:
How to force browser to update JS and CSS files cache after Deploy: https://laracasts.com/discuss/channels/laravel/how-to-force-browser-to-update-js-and-css-files-cache-after-deploy?page=1
How can I achieve that in Symfony 2.8?
Thanks in advance and sorry for my english.
Won't this create multiple outdated output files that in time with each asset change will occupy a lot of space on the server since old files are never deleted?Or are they deleted when a new hash is generated?
Symfony will not create such hashed files. This is up to your asset pipeline (webpack and gulp are able to generate such files for instance). And the cleaning of previous files is also up to the asset pipeline. Symfony is now able to consume the manifest generated by webpack/gulp/whatever making it compatible with using this feature.
@Mark https://packagist.org/packages/irozgar/gulp-rev-versions-bundle provides a similar feature
Great feature! @Mark Here's another solution (Twig filter) in this tuto by @weaverryan: https://knpuniversity.com/screencast/gulp/version-cache-busting
Nice!
@Mark Here's a gulpfile creating the hashed files using gulp-buster: https://github.com/snoek09/symfony-bug-tracker/blob/master/gulpfile.js