Search code examples
angularjsgruntjsminifygrunt-usemingrunt-contrib-imagemin

Dynamic image ng-src doesn't change to minified image name


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..


Solution

  • 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']
          ]
        }
      }