ericclemmons / grunt-angular-templates

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

Added support for use a customized template and some text decorators #29

Closed IvanGuardado closed 11 years ago

IvanGuardado commented 11 years ago
juniorplenty commented 11 years ago

Please - either this or some kind of "requirejs" option that allows you to specify a list of modules to require before loading the template code...

IvanGuardado commented 11 years ago

@juniorplenty could you write an example?

ericclemmons commented 11 years ago

Yes, example please. I wouldn't mind a requirejs: true option, but I'd like to see how your RequireJS + Angular app looks, and then we can make this compatible.

Truth be told, I tried RequireJS originally, find it extremely verbose, attempted browserify, found it slightly better, but meant more overhead on top of Angular's built in dependency resolution, and finally have settled on simply concat'ing all JS (each file is a stand-alone module by definition) and specifying them as Angular-dependencies.

That's not to say this project won't support how you do it, but that I've seen enough variation to not know exactly how to best adapt to your project.

IvanGuardado commented 11 years ago

@ericclemmons my project seed works based on modules. It's designed to build huge projects in which you don't want to load the whole resource set in the first loading. This ensures you to save bandwidth and makes the site more suitable for mobiles and tablets.

But requirejs might be a double-edged sword, if the app downloads each file independently it could lie on bandwith problems again, due to open too many connections. This is the reason I create modules.

Each module has its own controllers, locales, services, directives and templates. In a development context, each file is download separately, but I package them into a module file for a production context.

So this is a module structure:

The main.js file is responsible to hold the module configuration in order to know which files to download (or package) when the module is required. It could look this way:

define(function(require){
  return {
    templates: require('../templates/moduleA'),
    locales: [
      {lang: 'en', translations: require('./locale/en_US')}
    ],
    controllers: [
      {name: 'MainCtrl', body: require('./controller/MainCtrl')},
      {name: 'OtherCtrl', body: require('./controller/OtherCtrl')}
    ],
    services: [],
    factories: []
  };
});

The interesting here is that it needs all the moduleA views compiled in the file templates/moduleA.js, but I can't do that with your current task because it creates a file with all templates. However, with my extension, I can get that configuring the grunt task as follow:

...
ngtemplates: {
      compile: {
        "options": {
          "baseIdent": 4,
          "modulePath": "app/",
          "template": "define([],function(){\n  return {\n    loadTemplates: function($templateCache){{{content}}    }\n  };\n});"
        },
        "src": ["app/**/view/*.html"],
        "dest": "../.tmp/templates/"
      }
    }
...

This way the task will consider each folder inside the app folder is a module and it'll iterate over each one, creating a separated file per module with all the compiled templates in "../.tmp/templates/"

Ofcourse, the basic configuration task works perfectly. This is a solution for people who need a better control on the output.

joshuacc commented 11 years ago

@IvanGuardado I'm curious. Is there a reason that you couldn't just add a separate configuration under ngtemplates for each module instead of using one compile configuration?

IvanGuardado commented 11 years ago

@joshuacc This was my first bet, but I think it is too verbose because I had to add a configuration section foreach module in which only the src option changed. I know it's a solution but I think the way I propose is smarter since allows to developers forget about the ngtemplate grunt task in their workflow

joshuacc commented 11 years ago

@IvanGuardado That's a good point. Though if you want temporary solution, this might work for you...

ngmodules = ["moduleA", "moduleB"];

ngtemplateConfig = ngmodules.reduce(function(collector, val) {
    collector[val] = {
        src: ["app/" + val + "/view/*.html"],
        dest: "../.tmp/templates/"
    };

    return collector;
}, {});

ngtemplateConfig.options =  {
    baseIdent: 4,
    modulePath: "app/",
    template: "define([],function(){\n  return {\n    loadTemplates: function($templateCache){{{content}}    }\n  };\n});"
}

// ...

ngtemplates: ngtemplateConfig

At least this way the only thing you need to do is add a new string to the ngmodules array. :smile:

IvanGuardado commented 11 years ago

@joshuacc thanks for your tip, although I don't need a temporary solution because I've already implemented on my fork :D

Really, that was not a hard change in the code and I think it's useful.

ericclemmons commented 11 years ago

I looked over the tons of discussion here between @IvanGuardado and @juniorplenty (along with several other PRs), and did a complete rewrite here:

https://github.com/ericclemmons/grunt-angular-templates/pull/38

I hope that PR helps with what you're trying to accomplish, as it lets you provide your own callbacks for generating the url, the template source, and even the bootstrap wrapper.

Please leave comments on that PR with any thoughts you have. I've removed a lot of the cruft from this task with the cleanup, too! :)

Thanks!