2

I've got two images, a green check mark and a grey check mark. These are shown/hidden as the user checks or unchecks an item in a list. The problem I'm having is that when minifying the app's images with grunt-contrib-imagemin, these two images ng-src doesn't change to the minified image name. Any ideas why this happens and how to fix it?

<img ng-if="item.checkedState === 'unchecked'" ng-src="images/unchecked.png" ng-click="changeCheckedState(item)">
<img ng-if="item.checkedState === 'checked'" ng-src="images/checked.png" ng-click="changeCheckedState(item)">

My usemin task:

usemin: {
  html: ['<%= yeoman.dist %>/{,*/}*.html'],
  css: ['<%= yeoman.dist %>/styles/{,*/}*.css'],
  options: {
    assetsDirs: ['<%= yeoman.dist %>','<%= yeoman.dist %>/images']
  }
}

EDIT: By testing @Tony Barnes solution:

usemin: {
  html: ['<%= yeoman.dist %>/{,*/}*.html'],
  css: ['<%= yeoman.dist %>/styles/{,*/}*.css'],
  options: {
    assetsDirs: ['<%= yeoman.dist %>','<%= yeoman.dist %>/images'],
    patterns: {
    html: [
        [/<img[^\>]*[^\>\S]+ng-src=[""]([^'"\)#]+)(#.+)?["']/gm, 'Update the HTML with non standard ng-src attribute on img']
    ]
    }
  }
}

The other src names for scripts and styles fails, i.e. the file vendors132918.js becomes vendor.js in the src which then throws a 404 not found error since the file isn't called vendor.js. What is causing the other src's to fail here? The pattern shouldn't change anything except for the src on images as far as I can see..

Chrillewoodz
  • 27,055
  • 21
  • 92
  • 175
  • It looks like the images will get minified because `imagemin` is watching everything in the `images/` directory. Are you sure they are not in the directory? Maybe, depending on your setup, after minifying, the image's are renamed and your `ng-src`'s are not updated with the new file name. – Tony Barnes Mar 16 '15 at 11:50
  • @TonyBarnes All images are in there, the images themselves are getting minified but the source doesn't change to the minified ones. Maybe I was a bit unclear. – Chrillewoodz Mar 16 '15 at 11:51
  • Do you have a usemin task in your grunt setup? Are other images renamed in the HTML after minifying? – Tony Barnes Mar 16 '15 at 11:54
  • @TonyBarnes Yes and yes, other images gets minified and have their source renamed accordingly. But as soon as I use ng-if or ng-show/hide then it doesn't work. – Chrillewoodz Mar 16 '15 at 11:57
  • Interesting, can you post your usemin task? – Tony Barnes Mar 16 '15 at 12:09
  • How would the pattern change if my HTML looked like this? `` – Cole Oct 18 '16 at 02:32

2 Answers2

4

The issue lays with the grunt-usemin task that replaces the references. By default, ng-src is ignored by usemin.

If you include this html pattern, the ng-src references will be replaced correctly.

usemin: {
  options: {
    patterns: {
      html: [

        [/<img[^\>]*[^\>\S]+ng-src=[""]([^'"\)#]+)(#.+)?["']/gm, 'Update the HTML with non standard ng-src attribute on img']

      ]
    }
  }
}

(Inspired by this recent commit)

However, this breaks other references to styles and scripts. It seems that other default usemin patterns are overridden by the above addition.

To get this all working, you need to combine the above pattern and the default pattern's from usemin:

options: {
    assetsDirs: ['<%= yeoman.dist %>', '<%= yeoman.dist %>/images'],
    patterns: {
      html: [
         [/(images\/.*?\.(?:gif|jpeg|jpg|png|webp|svg))/gm,
         'Update the angular directives that ref revved images'],

         //defaults from node module
         [ /<script.+src=['"]([^"']+)["']/gm,
         'Update the HTML to reference our concat/min/revved script files'
         ],
         [ /<link[^\>]+href=['"]([^"']+)["']/gm,
         'Update the HTML with the new css filenames'
         ],
         [ /<img[^\>]+src=['"]([^"']+)["']/gm,
         'Update the HTML with the new img filenames'
         ],
         [ /data-main\s*=['"]([^"']+)['"]/gm,
         'Update the HTML with data-main tags',
         function (m) { return m.match(/\.js$/) ? m : m + '.js'; },
         function (m) { return m.replace('.js', ''); }
         ],
         [ /data-(?!main).[^=]+=['"]([^'"]+)['"]/gm,
         'Update the HTML with data-* tags'
         ],
         [ /url\(\s*['"]([^"']+)["']\s*\)/gm,
         'Update the HTML with background imgs, case there is some inline style'
         ],
         [ /<a[^\>]+href=['"]([^"']+)["']/gm,
         'Update the HTML with anchors images'
         ],
         [/<input[^\>]+src=['"]([^"']+)["']/gm,
         'Update the HTML with reference in input'
         ]
       ],
      js: [
          [/(images\/.*?\.(?:gif|jpeg|jpg|png|webp|svg))/gm, 
          'Update the JS to reference our revved images']
      ]
    }
  }
Tony Barnes
  • 2,625
  • 1
  • 18
  • 29
  • I tried adding patterns like you suggested but I received a warning: "Unsupported pattern: patterns". I also posted my original usemin. – Chrillewoodz Mar 16 '15 at 12:30
  • @Chrillewoodz Sorry, patterns should be inside the `options` object - updated. I hope it works! – Tony Barnes Mar 16 '15 at 12:32
  • It seems as if this pattern causes all scripts and styles rewrites to fail, because I get a bunch of 404 errors when trying to load those resources when including your solution. Any idea why? – Chrillewoodz Mar 16 '15 at 12:42
  • I'm not sure off hand - later I will look at re-creating the issue :) – Tony Barnes Mar 16 '15 at 12:52
  • @Chrillewoodz I replicated and solved the issue - see the updated answer. – Tony Barnes Mar 16 '15 at 20:01
  • I updated question with your solution, but problems remain. When you replicated the problem did you also try it with scripts and style files? – Chrillewoodz Mar 17 '15 at 08:08
  • @Chrillewoodz You're right, I just checked. This solves the `ng-src` issue, but causes the scripts and CSS references to be ignored. I'm having a play with the usemin task from the default yeoman `generator-angular` - seems to be a bug! – Tony Barnes Mar 17 '15 at 18:01
  • @Chrillewoodz I've got it working - let me know if you experience other issues :) – Tony Barnes Mar 17 '15 at 18:15
  • Works ^_^ +1 for being awesome and for taking your time :) Really appreciate it. – Chrillewoodz Mar 18 '15 at 08:35
0

if you use some curly brackets to the beginning of your ngSrc directive value. You must to use the regex above in your Gruntfile.

/<img[^\>]*[^\>\S]+ng\-src=['"][\{\}\:\w\s]*([^'"\)#]+)(#.+)?["']/gm
Guillaume
  • 111
  • 1
  • 5