ericclemmons / grunt-angular-templates

Grunt build task to concatenate & pre-load your AngularJS templates
MIT License
711 stars 108 forks source link

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

Open eddiemonge opened 10 years ago

eddiemonge commented 10 years ago

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

ericclemmons commented 10 years ago

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 commented 10 years ago

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.

eddiemonge commented 10 years ago

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.

ericclemmons commented 10 years ago

@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!

zfogg commented 10 years ago

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.

ericclemmons commented 10 years ago

@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?

ninelb commented 10 years ago

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.

santervo commented 10 years ago

@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
zxbodya commented 10 years ago

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'
        ]]
    }
  }
},
ericclemmons commented 10 years ago

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

zxbodya commented 10 years ago

@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:


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:

spalladino commented 10 years ago

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

santervo commented 10 years ago

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

fabiopaiva commented 9 years ago

Thanks @zxbodya. Works fine