grunt-angular-templates icon indicating copy to clipboard operation
grunt-angular-templates copied to clipboard

Usemin doesn't change when references assets are in the views

Open eddiemonge opened this issue 11 years ago • 14 comments

How would you handle updating references to assets in the views when using usemin?

eddiemonge avatar Dec 13 '13 22:12 eddiemonge

I think I missed this issue. Whatcha mean, @eddiemonge? The URLs should be the same, as the path to the template (minus the cwd) should be the web-resolvable path, too.

So, if you have a non-grunt-angular-templates-compiled app with the following structure:

public/
  index.html
  app/
    app.js
    templates/
      home.html

If your app.js has a route with templateUrl: 'app/templates/home.html', that will resolve just fine via AJAX.

Then, if you were to use this project to automatically combine all templates under public/ into a single templates.js file, the URL app/templates/home.html will already be registered with Angular's $templateCache so the AJAX round-trip is saved.

Did I read ya right?

ericclemmons avatar Dec 16 '13 00:12 ericclemmons

Maybe you can also chime in with the revision stuff, too.

It seems more and more in my personal & professional development, I'm pushed away from grunt-usemin.

ericclemmons avatar Dec 16 '13 05:12 ericclemmons

The revision stuff is what Im talking about. If you have an img in a view, usemin doesnt get a chance to update the paths unless there is a lot more work done in the build system. Im not sure if it should be handled here or in usemin or in the individual projects. It would be interesting if this could hook into grunt-rev to see what it changes and then this updates its in memory references as well. But like i said, it might need to be in the build process instead.

eddiemonge avatar Dec 16 '13 18:12 eddiemonge

@eddiemonge Can you come up with a test-case so I can actually see what you're referring to? I haven't used the revision stuff for grunt-usemin, so I need something concrete to keep the issue open :)

Thanks!

ericclemmons avatar Dec 23 '13 22:12 ericclemmons

Is this still not implemented? I would LOVE rev support. Basically 'rev' will go through your assets and prepend them with a random ID. Then it goes through your HTML and CSS and updates the references to those assets with the new filenames. This prevents your client's browsers from having caching problems, because the client will be requesting new filenames once you rebuild with Grunt.

zfogg avatar Feb 11 '14 07:02 zfogg

@zfogg I'm not sure what even needs to be implemented, TBH. No one's provided an example, much less a PR, and I don't use usemin anymore because my applications are no longer trivial, single index.html pages.

Isn't the "problem" solved by referencing the compiled template so usemin can make a special revision for that file, too?

ericclemmons avatar Feb 11 '14 14:02 ericclemmons

The problem seems to be with assets that are referenced from the templates themselves.

If I have a template with this img tag:

<img src="images/logo.png"/>

usemin will update that reference to:

<img src="images/62b5015d.logo.png"/>

With the templates cached inside of templates.js, usemin is not able to operate on them.

ninelb avatar Feb 21 '14 04:02 ninelb

@ninelb I think you need to split the process in two:

  1. rev assets other than script (css, images etc) and execute usemin task so that references to static assets are replaces in view templates
  2. compile templates, concatenate and rev scripts (including templates), and execute usemin again so that references to revved scripts are updated

santervo avatar Jul 14 '14 09:07 santervo

This can be solved by adding additional patterns for usemin to process image references inside templates embedded in javascript files…

In my case usemin configuration is following:

usemin: {
  html: ['<%= yeoman.dist %>/**/*.html'],
  css: ['<%= yeoman.dist %>/styles/{,*/}*.css'],
  js: ['<%= yeoman.dist %>/scripts/scripts.*.js'],
  options: {
    assetsDirs: ['<%= yeoman.dist %>', '<%= yeoman.dist %>/images'],
    patterns: {
      js: [[ // rule from, grunt-usemin/lib/fileprocessor.js:7
          /<img[^\>]*[^\>\S]+src=['"]([^"']+)["']/gm,
          'Update the JS with the new img filenames'
        ]]
    }
  }
},

zxbodya avatar Sep 04 '14 21:09 zxbodya

It seems @santervo has it right: usemin needs to rewrite the HTML before it's processed and turned into JS via this plugin.

@zxbodya Can you elaborate? I compared your JS pattern to that in fileprocessor.js:7, and they appear to be the same, so I'm not sure how it solves the problem...

ericclemmons avatar Sep 05 '14 00:09 ericclemmons

@ericclemmons, yes - it the same expression... But it would be applied to resulting js file with html templates embedded into it.

@santervo idea also look good, but i didn't found an easy way to do this(at first I also thought to do it this way) In general, there is no difference when to do it... But, right now, I am convinced that variant with usemin rules for templates embedded in js files is better:

  • it looks more clear
  • it will handle all other templates embedded in js
  • it is easy to extend to handle assets references in places other than templates(at the moment, I have few such references in my project code)

Probably in some cases this pattern would be not suitable(for example if there is single quotes in html in my case), but in general such solution works ok.

If it is required pattern can be replaced with something more generic, for example:

  • /\\?['"]([^'"]+?\.(?:jpe?g|png|gif))\\?['"]/gm - to select everything that looks like an image path
  • /\\?['"]((?:images|img)\/[^'"]+?\.(?:jpe?g|png|gif))\\?['"]/gm to select only image paths in images and img folder

zxbodya avatar Sep 05 '14 01:09 zxbodya

@santervo Could you provide an example on how to set that up? I've been struggling with that with no luck. I'd like to leave js files untouched by usemin, so @zxbodya 's approach would not work for me.

spalladino avatar Sep 23 '14 22:09 spalladino

@spalladino

Here's the relevant build configuration from a project where I used this:

  grunt.registerTask('build', [
    ...,
    // rev static assets other than scripts
    'rev:assets',
    // Run usemin, replace references to revved assets
    'usemin',
    // compile templates (that now have updated references to static assets)
    'html2js',
    // concatenate compiled templates to script file
    'concat:templates',
    'uglify',
    // rev script files
    'rev:scripts',
    // Run usemin again, now replace references to scripts
    'usemin',

Here's the relevant rev configuration with two targets, assets and scripts:

    rev: {
      assets: {
        files: {
          src: [
            '<%= yeoman.dist %>/styles/{,*/}*.css',
            '<%= yeoman.dist %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
            '<%= yeoman.dist %>/styles/fonts/*'
          ]
        }
      },
      scripts: {
        files: {
          src: [
            '<%= yeoman.dist %>/scripts/{,*/}*.js'
          ]
        }
      }
    },

Hope this helps.

santervo avatar Sep 24 '14 06:09 santervo

Thanks @zxbodya. Works fine

fabio-paiva-sp avatar Oct 20 '15 23:10 fabio-paiva-sp