custom-dev-tools / grunt-cache-killer

Grunt cache killer is a Grunt plugin that circumvents http(s) cache problems when asset files (such as css, js and img files) are updated. This plugin automatically updates the specified asset filename(s) and any reference to them within your specified (template) files.
MIT License
2 stars 0 forks source link

Issue: In a special case the CSS file names are not replaced correctly in the HTML code #2

Closed alchemist-153 closed 2 years ago

alchemist-153 commented 2 years ago

Hello,

I am working on a project that is based on HTML5 Boilerplate. Unfortunately, grunt-cache-killer is not correctly replacing CSS files names in index.php; this is due to a file named style.css, this file is part of HTML5 Boilerplate.

Before running the task:

<link rel="stylesheet" href="css/vendor/bootstrap-5.1.3.min.css">
<link rel="stylesheet" href="css/style.min.css">
<link rel="stylesheet" href="css/custom.min.css">

After:

<link rel="style.20220813212624.min.css">
<link rel="style.20220813212624.min.css">
<link rel="style.20220813212624.min.css">

This is the task's configuration:

    cacheKiller: {
      options: {
        mask: '{datetimestamp}',
        prepend: '.'
      },
      build: {
        files: {
          'dist/css/style[mask].min.css' : ['dist/index.php'],
          'dist/css/custom[mask].min.css' : ['dist/index.php']
        }
      }
    },

And this is the debug output:

[D] Options object: { prepend: '.', append: '', mask: '{datetimestamp}', length: -1 }

[D] Validating option types.
[D] Success..!

[D] Validating mask function type.
[D] Success..!

[D] Building tasks list.
[D] Working..!.

[D] Validating template filenames.
[D] Success..!

[D] Validating position of mask placeholder.
[D] Success..!

[D] Validating asset filename.
[D] Success..!

[D] Validating template filenames.
[D] Success..!

[D] Validating position of mask placeholder.
[D] Success..!

[D] Validating asset filename.
[D] Success..!

[D] Build tasks list.
[D] Success..!

[D] Tasks list object:
{
  '0': {
    asset: {
      name: {
        full: 'dist/css/style[mask].min.css',
        base: 'dist/css/',
        file: 'style[mask].min.css',
        pre: 'style',
        post: '.min.css'
      },
      mask: {
        prepend: '.',
        value: { raw: '20220813212624', computed: '20220813212624' },
        append: ''
      },
      rename: {
        from: { file: 'style.min.css', full: 'dist/css/style.min.css' },
        to: {
          file: 'style.20220813212624.min.css',
          full: 'dist/css/style.20220813212624.min.css'
        }
      }
    },
    templates: [ 'dist/index.php' ]
  },
  '1': {
    asset: {
      name: {
        full: 'dist/css/custom[mask].min.css',
        base: 'dist/css/',
        file: 'custom[mask].min.css',
        pre: 'custom',
        post: '.min.css'
      },
      mask: {
        prepend: '.',
        value: { raw: '20220813212624', computed: '20220813212624' },
        append: ''
      },
      rename: {
        from: { file: 'custom.min.css', full: 'dist/css/custom.min.css' },
        to: {
          file: 'custom.20220813212624.min.css',
          full: 'dist/css/custom.20220813212624.min.css'
        }
      }
    },
    templates: [ 'dist/index.php' ]
  }
}

[D] Synchronously renaming asset file.
[D] Success..!

>> build : Asset file 'style.min.css' renamed to 'style.20220813212624.min.css'.
[D] 
[D] Synchronously read contents of template.
[D] Success..!

[D] Replace template's matching content.
[D] Success..!

[D] Synchronously write contents to template.
[D] Success..!

>> build : Reference(s) updated in template file 'dist/index.php'.

[D] Synchronously renaming asset file.
[D] Success..!

>> build : Asset file 'custom.min.css' renamed to 'custom.20220813212624.min.css'.
[D] 
[D] Synchronously read contents of template.
[D] Success..!

[D] Replace template's matching content.
[D] Success..!

[D] Synchronously write contents to template.
[D] Success..!

>> build : Reference(s) updated in template file 'dist/index.php'.

Success..!

Done.
custom-dev-tools commented 2 years ago

@alchemist-153 Within your cacheKiller task configuration, try removing dist/ from the beginning of both CSS asset file paths and their associated template paths as shown below.

    cacheKiller: {
      options: {
        mask: '{datetimestamp}',
        prepend: '.'
      },
      build: {
        files: {
          'css/style[mask].min.css' : ['index.php'],
          'css/custom[mask].min.css' : ['index.php']
        }
      }
    },

This script does not change the asset and template file paths, only the asset file names and their reference in the template(s).


I assume you are using other CSS build tools and cacheKiller to achieve the following.

<!-- Before build tools and cacheKiller -->
<link rel="stylesheet" href="css/vendor/bootstrap-5.1.3.min.css">
<link rel="stylesheet" href="css/style.min.css">
<link rel="stylesheet" href="css/custom.min.css">

<!-- After build tools and cacheKiller -->
<link rel="stylesheet" href="dist/css/vendor/bootstrap-5.1.3.min.css">
<link rel="stylesheet" href="dist/css/style.20220813212624.min.css">
<link rel="stylesheet" href="dist/css/custom.20220813212624.min.css">

If that is the case, then either run cacheKiller:

  1. Before your CSS build tool processes and moves your CSS files to the dist directory, and drop reference to dist/ in the cacheKiller task configuration (as initially shown above).

  2. After your CSS build tool copies your processed CSS files to the dist directory, and leave reference to dist/ in the cacheKiller task configuration (as your CSS build tool would have prepended dist/ to the front of the your asset file path(s)).

Let me know how you go...

alchemist-153 commented 2 years ago

Thank you for your reply! I tried all the solutions you kindly provided, but unfortunately Grunt Cache Killer fails again to correctly replace the strings.

One easy solution that works, but I don't like for some reasons, is to rename style.css to main.css, doing it like this, Grunt Cache Killer works very well and I can use the html code and task configuration I posted at the beginning of my previous post.

After running Cache Killer this is what I get now, and it's correct:

<link rel="stylesheet" href="css/vendor/bootstrap-5.1.3.min.css">
<link rel="stylesheet" href="css/main.20220814161445.min.css">
<link rel="stylesheet" href="css/custom.20220814161445.min.css">

I think that these new results suggest that the problem is caused by the string 'style', not the string 'dist'.

My knowledge of JavaScript is very basic, but please consider this as the possible explanation:

When using 'style.min.css' as the name of a file, and 'style[mask].min.css' as the new name of the file, Cache Killer makes this:

$tasks[i].asset.name.pre = 'style';

Then, Cache Killer scans my html code and finds the first link tag:

<link rel="stylesheet" href="css/vendor/bootstrap-5.1.3.min.css">

And it matches the value of the variable name.pre ('style') with the string 'style' that is inside rel="stylesheet", this leads to rel="stylesheet" being replaced with rel="style.20220814121121.min.css" (Please see the section 'After running the task' of my first post). The same happens with the rest of the link tags. Please note that href attributes are being deleted.

I think that maybe there is a minor error in a regular expresssion.

custom-dev-tools commented 2 years ago

@alchemist-153 Good news. I have been able to reproduce the error in a new test (test 6) as shown below.

Testing test6.js.F
>> cacheKiller - test_2
>> Message: File names and contents should match.
>> Actual:
>>   '<!DOCTYPE html>\r\n' +
>>     '<html lang="en">\r\n' +
>>     '<head>\r\n' +
>>     '    <!-- Metadata -->\r\n' +
>>     '    <meta charset="UTF-8">\r\n' +
>>     '\r\n' +
>>     '    <!-- Title -->\r\n' +
>>     '    <title>Test HTML Template - Master</title>\r\n' +
>>     '\r\n' +
>>     '    <!-- Stylesheets -->\r\n' +
>>     '    <link rel="style.9063da07.min.css">\r\n' +
>>     '</head>\r\n' +
>>     '<body>\r\n' +
>>     '    <h1 id="heading">Test HTML Template - Master</h1>\r\n' +
>>     '</body>\r\n' +
>>     '</html>'
>> Operator:
>>   ==
>> Expected:
>>   '<!DOCTYPE html>\r\n' +
>>     '<html lang="en">\r\n' +
>>     '<head>\r\n' +
>>     '    <!-- Metadata -->\r\n' +
>>     '    <meta charset="UTF-8">\r\n' +
>>     '\r\n' +
>>     '    <!-- Title -->\r\n' +
>>     '    <title>Test HTML Template - Master</title>\r\n' +
>>     '\r\n' +
>>     '    <!-- Stylesheets -->\r\n' +
>>     '    <link rel="stylesheet" href="../css/style.9063da07.min.css">\r\n' +
>>     '</head>\r\n' +
>>     '<body>\r\n' +
>>     '    <h1 id="heading">Test HTML Template - Master</h1>\r\n' +
>>     '</body>\r\n' +
>>     '</html>'
>> at Object.test_2 (tests\functional\test6.js:24:14)
>> at processImmediate (node:internal/timers:464:21)
>> at process.topLevelDomainCallback (node:domain:152:15)
>> at process.callbackTrampoline (node:internal/async_hooks:128:24)

Warning: 1/15 assertions failed (28ms) Use --force to continue.

Aborted due to warnings.

Process finished with exit code 6

As mentioned, line 362 will be the problem.

var result = content.replace(new RegExp($tasks[k].asset.name.pre + '.*' + $tasks[k].asset.name.post, "g"), $tasks[k].asset.rename.to.file);

I'll look at geting this fixed as soon as possible for you.

Thank you @alchemist-153 for bringing it to my attention.

custom-dev-tools commented 2 years ago

@alchemist-153 All fixed.

grunt-cache-killer : v1.3.7 has now been pushed to GitHub and NPM.

Let me know if you continue to have any problems.

alchemist-153 commented 2 years ago

Hello @custom-dev-tools, I tried the new version of cacheKiller a moment ago and it works very well 👏🏼

Thank you very much!