Jump to content
easynowbaby

Cache busting

Recommended Posts

Hello,

what would be the recommended way of versioning your asset files (css and js)? I know it can be done with AIOM module but it seems it's not longer maintained, since it doesn't work on PHP 7.1. Can anyone recommend any best practices for this?

Thanks!

Share this post


Link to post
Share on other sites

AIOM works for me with PHP 7.1... strange.

Here's a related topic: 

 

 

Share this post


Link to post
Share on other sites

I decided to delegate this problem to gulp. If anyone is interested, I used this package https://github.com/sindresorhus/gulp-rev

I used this modified function for implementation:

function asset_path($filename) {
    $manifest_path = wire('config')->paths->templates . 'versioned/rev-manifest.json';
    if (file_exists($manifest_path)) {
        $manifest = json_decode(file_get_contents($manifest_path), TRUE);
    } else {
        $manifest = [];
    }

    if (array_key_exists($filename, $manifest)) {
        return $manifest[$filename];
    }

    return $filename;
}

and then in my templates

<?php if ($config->debug): ?>
	<link rel="stylesheet" href="<?php echo $config->urls->templates . 'build/main.css'; ?>">
<?php else: ?>
	<link rel="stylesheet" href="<?php echo $config->urls->templates . 'versioned/' . asset_path('main.css'); ?>">
<?php endif; ?>

 

Share this post


Link to post
Share on other sites

I've done a simple version of this by hashing the file's modified time:

$js_version = md5(filemtime($config->paths->assets . 'js/script.js'));
echo sprintf('<script src="%sjs/script.js?v=%s"></script>', $config->urls->assets, $js_version);

 

  • Like 4

Share this post


Link to post
Share on other sites

I also delegate this task to gulp v4 (and I am far to be a gulp guru).

Basically, each process is divided in tasks, some to clean, minify and/or obfuscate.

The final task is :


gulp.task('build', gulp.series('clean-dist', gulp.series('minify-fontello', 'minify-css', 'minify-css-login',
    'vendors-js', 'vendors-css', 'minify-js-login', 'minify-js-main', 'hash', 'main-tpl-css', 'main-tpl-js')));

The best tasks are 'hash',  'main-tpl-css' and 'main-tpl-js'. The 'hash' task generate filename with this pattern : {name}.{hash}.{size}{ext} and the last two tasks automatically parse the _main.tpl (_main.php in the intermediate site-profile) and replace the existing css/js call with the newly generated files :

<html>
  <head></head>
  <body>
    [...]
	echo "<script id='main' src='{$assets_url}dist/mywebsite.main.min.7defab4250a4d9009987b26c8f68d50b.1337.js'></script>\n";
    [...]
  </body>
</html>

 

If someone is interested I can paste the gulpfile.js here.

 

 

Share this post


Link to post
Share on other sites

Hi Flydev

Can you past your gulpfile.js please. I'm interesting to see how you do main-tpl-css/js tasks ?

Thanks a lot

Share this post


Link to post
Share on other sites

Hi @sebr , there you go...

Note :  All the other tasks have as destination wwwroot/assets/dist then the hash task grab the files in this folder and have as destination wwwroot/site/templates/assets/dist then the two tasks below use and rename files in wwwroot/site/templates/assets/dist and update the _main.tpl file :

 

My dir tree :

wwwroot

--- assets

------ bower_components

------ node_modules

------ dist

------ css

------ js

------ ...

------ gulpfile.js

------ bower.json

------ package.json

--- site

------ templates

--------- views

------------ _main.tpl

--------- assets

------------ dist

------------ controller1.php

------------ controller2.php

------------ ...

--- wire

--- index.php

--- ...

 

// require
var path = require('path');
var fs   = require('fs');
var gulp = require('gulp'),
    hash = require('gulp-hash-filename'),
    replace = require('gulp-replace'),
    foreach = require('gulp-foreach');

//tasks

gulp.task('hash', function() {
    return gulp.src(['dist/*'])
        .pipe(hash({
            "format": "{name}.{hash}.{size}{ext}"
        }))
        .pipe(gulp.dest('../site/templates/assets/dist'));
});


gulp.task('main-tpl-css', function() {
    return gulp.src('../site/templates/assets/dist/*.css')
        .pipe(foreach((stream, file) => {
            var id = basename(file.path).split('.');
            var regexp = new RegExp("\\echo \"<link id='"+id[1]+"' rel='stylesheet'.*", "g");
            return gulp.src('../site/templates/views/_main.tpl', { base: './' })
                .pipe(replace(regexp, "echo \"<link id='"+ id[1] +"' rel='stylesheet' type='text/css' href='{$assets_url}dist/" + basename(file.path) + ".css'/>\";"))
                .pipe(gulp.dest('./'))
        }))
});

gulp.task('main-tpl-js', function() {
    return gulp.src('../site/templates/assets/dist/*.js')
        .pipe(foreach((stream, file) => {
            var id = basename(file.path).split('.');
            var regexp = new RegExp('\\<script id=\''+id[1]+'\'.*>', 'g');
            return gulp.src('../site/templates/views/_main.tpl', { base: './' })
                .pipe(replace(regexp, '<script id=\''+ id[1] +'\' src=\'{$assets_url}dist/'+ basename(file.path) + '.js\'></script>'))
                .pipe(gulp.dest('./'))
        }))
});

 

  • Like 1

Share this post


Link to post
Share on other sites
On 3/29/2018 at 5:36 AM, gRegor said:

I've done a simple version of this by hashing the file's modified time:


$js_version = md5(filemtime($config->paths->assets . 'js/script.js'));
echo sprintf('<script src="%sjs/script.js?v=%s"></script>', $config->urls->assets, $js_version);

 

How do you wipe the cache or something.
When i do the filemtime, it doesn't detect the new modified time, it always produce the same $js_version string.
I've tried clearstatecache() but to no avail, it's always producing the same $js_version string.

Share this post


Link to post
Share on other sites

I just found out the issue filemtime doesn't resolve the path of 

$config->paths->assets . 'js/script.js'

You will need to use $_SERVER["DOCUMENT_ROOT"] to get the root of your server. So the line should be something like this 

filemtime($_SERVER["DOCUMENT_ROOT"] . $config->paths->assets . 'js/script.js');

Hope this helps anyone

Share this post


Link to post
Share on other sites

That sounds like an odd server setup. $config->path->assets should give you the full path. Glad you got it working, though.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...