DI Services & RequireJS

1,444 views
Skip to first unread message

davidc...@gmail.com

unread,
Sep 10, 2012, 6:03:43 PM9/10/12
to ang...@googlegroups.com
I'm playing with Angular & RequireJS. I've built a little custom service that I'm injecting into a controller. Works great. But as I look at it I realize there's some redundancy going on. RequireJS loads the service singleton as a dependency, passing it in to the module. Angular does the same thing, but injects it into the controller. I guess my question is, what's the advantage of organizing my code as Angular services over Require modules? Require handles the dependency AND loads the file (no need for script tag) plus gives me automated optimization for free. Maybe RequireJS and Angular have too much overlap to be useful together? 

geraldodev

unread,
Sep 10, 2012, 6:52:44 PM9/10/12
to AngularJS
Not really. I prefer to think this way, I use requireJS to reach code
and by reach I mean:

1) It allows you to concatenate and minify your code.
2) You can even embed texts (with text plugin)
3) You can integrate jquery, underscore, and the others very useful
but not amd converted libraries with the new shim 2.0 configuration.

Angular is another story. It's dependency injection mechanism allows
you to write testable code, because you can use mocks in your tests.
$httpBackend is a good example of this. You can have tests that
doesn't need a server.
And the idea of declaring the dependency as a String is wonderful. It
allows a decoupled environment that is just resolved at execution
time.
Always resolving the dependencies using the injector that is created
for you at bootstrap time. Very clever.

Regards,

Geraldo

davidc...@gmail.com

unread,
Sep 10, 2012, 8:02:07 PM9/10/12
to ang...@googlegroups.com
But with RequireJS you specify your dependencies as strings, just like angular. And for tests you can reconfigure your "paths" to load mocks/stubs, but that might not be as elegant as the DI. 

Here's an example as Angular Service:

Same example as RequireJS module:

As you can see, they pretty much do the same thing. If I wanted to use RequireJS for its benefits, that means either duplication with what Angular does, or not using Angular's DI right?

geraldodev

unread,
Sep 10, 2012, 8:32:16 PM9/10/12
to AngularJS
Right ! and for that reason I've choosed to use both. requirejs to
reach the code and angular for assembling.

geraldodev

unread,
Sep 10, 2012, 8:33:49 PM9/10/12
to AngularJS
Sorry the misspell of chosen

Cary Landholt

unread,
Sep 11, 2012, 2:40:29 AM9/11/12
to ang...@googlegroups.com, davidc...@gmail.com
Angular can only manage what's been loaded in memory.  RequireJS can load dependent files.
I personally don't use RequireJS for its asynchronous loading of modules but for dependency management, optimization, and the text plugin.

I've created a sample application using Angular and RequireJS.

I prefer to include directive templates with the directive code and do this using the text plugin for RequireJS.  There's an example in the aforementioned repo.


Thanks,
Cary

davidc...@gmail.com

unread,
Sep 11, 2012, 3:21:09 AM9/11/12
to ang...@googlegroups.com, davidc...@gmail.com
Thanks Cary, that's quite helpful. What's still bothering me is that now I have two envelopes around my code (one for require, one for angular), and they do almost the same thing. That and I'm used to writing anonymous modules with require, where with Angular I have to explicitly name everything :(

davidc...@gmail.com

unread,
Sep 11, 2012, 3:27:55 AM9/11/12
to ang...@googlegroups.com, davidc...@gmail.com
I'm too new to Angular to know if there are any disadvantages to using RequireJS modules instead of Angular's module API (factory(), controller(), filter() etc). Other than easier mocks? 

Kai Groner

unread,
Sep 11, 2012, 3:09:37 PM9/11/12
to ang...@googlegroups.com
On Tue, Sep 11, 2012 at 3:27 AM, <davidc...@gmail.com> wrote:
I'm too new to Angular to know if there are any disadvantages to using RequireJS modules instead of Angular's module API (factory(), controller(), filter() etc). Other than easier mocks? 


The other thing Angular's module system does is it provides an application life cycle. A page containing two Angular applications would have two separate instances of $http (assuming they both used it), which could have different configurations.  The application life cycle is also used heavily in testing.

I imagine there are ways of doing this with RequireJS, but it might need some glue to integrate with Angular.

I don't think you can avoid registering filters, directives, and controllers with an Angular module.

On Tue, Sep 11, 2012 at 3:21 AM, <davidc...@gmail.com> wrote:
Thanks Cary, that's quite helpful. What's still bothering me is that now I have two envelopes around my code (one for require, one for angular), and they do almost the same thing. That and I'm used to writing anonymous modules with require, where with Angular I have to explicitly name everything :(


Maybe a RequireJS plugin would remove the need for some of the duplicate code?

Cary Landholt

unread,
Sep 11, 2012, 10:55:22 PM9/11/12
to ang...@googlegroups.com
Yeah - it's possible a plugin could help.  I'll have to think on that one.

Brian Ford

unread,
Sep 12, 2012, 2:57:04 AM9/12/12
to ang...@googlegroups.com, davidc...@gmail.com
I think it's worth looking at the index-async.html in angular-seed: https://github.com/angular/angular-seed/blob/master/app/index-async.html

And for anyone interested, there's a related Github issue around AngularJS and Require.js in the Yeoman AngularJS generators: https://github.com/yeoman/generators/issues/33

My personal take is that RequireJS does too much; the only feature that AngularJS's DI system is really missing is the async loading. But I'm definitely taking a closer look at all of these different suggestions, so thanks for all of the ideas and feedback, guys!

Cary Landholt

unread,
Sep 13, 2012, 7:52:34 AM9/13/12
to ang...@googlegroups.com, davidc...@gmail.com
Arguably async loading is of minimal value; however, AngularJS' DI system is still missing the ability to load modules in dependent order if your needs move beyond AngularJS components.

For example, jQuery and jQuery plugins may be dependencies for a given application.  jQuery plugins must load after jQuery.
Module loaders help out significantly here.

This is aside from minification and other optimizations script loaders provide.

Cheers - thanks for the conversation.

Cary

passelin

unread,
Sep 13, 2012, 9:27:41 PM9/13/12
to ang...@googlegroups.com, davidc...@gmail.com
I too agree that requirejs is a little too much, at least for what I needed. The only thing that I needed that angular was not providing was automatic resource loading in dependent order. Angular does define the dependency order of modules to load but doesn't go the extra step of loading files. I suppose because it would require them to define for you a way to organize your files. I added automatic loading of modules (and module library dependencies) by using angular-loader.js, yepnope (because I use modernizr) and a simple naming convention for my merged module js file.

I created a simple api with a bootstrap method that takes the same module name input as angular's bootstrap method but before invoking angular.bootstrap, 
  1. Using yepnope, I load the module file using a convention (let's say [moduleName]/js/[moduleName].min.js). 
  2. I then inspect the loaded module object to see its library dependencies. For this, in the module file, I add a custom property to the angular module object: angular.module('myApp',['dep1'])._requiredResources = yepnope test object for lib dependencies of this module. 
  3. Using yepnope, I load all lib dependencies using the yepnope object: angular.module('myApp')._requiredResources.
  4. I then inspect the module again to find the module dependencies: angular.module('myApp').requires. This returns you the array of module names your module depends on.
  5. Iterate over the array and for each module that follow the naming convention, go back to #1.
That's the general idea, I'll try to find some time to create a working example somewhere (not sure plunker would work). The good thing is that the developer using this API only needs to call bootstrap('myApp') and all resources get loaded in the correct order before angular.bootstrap is loaded (assuming, of course, that he followed the naming convention and uses the custom property to define his module's library dependencies). 

davidc...@gmail.com

unread,
Sep 13, 2012, 10:39:33 PM9/13/12
to ang...@googlegroups.com
@passelin that sounds way more complicated than using the already existing AMD standard, which has many benefits. Don't discount the async loading and concat/compression, they make a huge difference. Plugins are also extremely useful.

Anyway, thanks for the comments everybody. I think if Angular does eventually support module loading it should provide a lightweight one that is easily replaceable with a more robust loaded like requirejs.

I'll post more findings as I integrate these two awesome tools.

passelin

unread,
Sep 14, 2012, 12:43:12 AM9/14/12
to ang...@googlegroups.com, davidc...@gmail.com

My goal was not to have something as complete as requirejs, it was to have something less complete :) I wanted to re-use the dependencies I'm already defining in angular and there are other tools for other concerns addressed by requirejs like resource (js & css) optimization for example. Also, yepnope is all about async resource loading (not just js either).

Maybe I made it sound complicated but using this is quite simple and DRY. It will also allow me to have a prod/dev mode to my app where optimized resources are loaded in prod and unmerged/not optimized files are used in dev.

Anyway, I'm not discrediting your choice of requirejs and encourage people to use it if it fits their needs. AMD's a very well conceived standard and I agree that  if module loading comes to Angular it should be easily replaceable (I'm not worried about that, angular's very well designed). I just hope my solution can help someone else looking for a lightweight solution to modular resource loading (only).

david.jona...@gmail.com

unread,
Oct 20, 2012, 8:00:01 AM10/20/12
to ang...@googlegroups.com
I'm curious how these work together too. My use case is I want to avoid having to do anything special when I build my app for concatenation. I want to develop the code in small files and intelligently concatenate it all together in the right order automatically. Does angular do anything like this? All the examples I see use script tags. I noticed yeoman has something along these lines, but I think it requires comments or something. Thanks.
Reply all
Reply to author
Forward
0 new messages