Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I'm currently using a combination of RequireJS and AngularJS in my application and on the server side is ASP.NET.

I chose to use RequireJS for a few of reasons:

  • I started the project with it before discovering Angular.
  • Easy loading of external APIs (eg. Facebook, Google).
  • Easy minification via. R.js
  • Easy to add files to the project as it grows, no need for additional script tags.

As the project has matured most areas I previously used RequireJS for now seem redundant which means most files end up with another level of indentation (and nothing more) thanks to the define wrapper:

define(['angular'], function(angular) {});

There's probably also a small perf. benefit when removing it too :)

So my question is, what's the best (and preferably quickest) way to manage AngularJS applications within the context of an ASP.NET environment? ASP.NET script bundles? Grunt tasks?

share|improve this question
    
If you're worried about performance, I would drop ASP.NET serving the app, and serve it as static content. WebAPI can be used to supply the backend. –  blockhead Dec 30 '13 at 15:34
    
Do you have any stats on the performance difference? How would you then deal with minification / including all files easily for debugging? –  Jamie Dec 30 '13 at 16:11
    
require.js or grunt (or both). –  blockhead Dec 30 '13 at 19:40
1  
If you want to bundle the views and add them to the $templateCache, there is a bundletransform for that –  madsny Jan 17 at 11:40

2 Answers 2

up vote 3 down vote accepted

I was searching for the best design/structure of the Visual Studio Web-Project hosting the Angular SPA. I've found many inspiration and after checking few templates, I realized that what I would like to achieve is:

  • profit from VS resp. ASP.NET (MVC) as much as possible
  • split the functionality into more/smaller files (controller, state, config, directive)
  • keep the logic of each Aspect (usually Entity) inside one folder (e.g. Employee/)
  • keep the files as close together as possible i.e. view, controller, test (ng-boilerplate)
  • the structure of files like this

Example of folder/file structure

 // external libs
 Scripts
 Scripts / angular.js
 Scripts / ui-bootstrap-x.y.js
 Scripts / ...

 // project libs
 MyApp
 MyApp / Module
 MyApp / Module / Employee
 MyApp / Module / Employee / Employee.state.js        // state machine settings
 MyApp / Module / Employee / EmployeeList.ctrl.js     // controllers
 MyApp / Module / Employee / EmployeeDetail.ctrl.js
 MyApp / Module / Employee / DisplayEmployee.dirc.js  // directive
 MyApp / Module / Employee / Employee.spec.js         // tests

 // similar for other stuff
 ...

As we can see, the trick is in suffix of each single/simple js file:

  • ".dirc.js" - directive
  • ".ctrl.js" - controller
  • ".spec.js" - tests
  • ...

Having this in place we can configure the Bundle:

bundles.Add(new ScriptBundle("~/js/app")
    .Include("~/MyApp/app.js")
    .Include("~/MyApp/app.config.js")
    .IncludeDirectory("~/MyApp/", "*.module.js", true)
    .IncludeDirectory("~/MyApp/", "*.dirc.js", true)
    .IncludeDirectory("~/MyApp/", "*.ctrl.js", true)
    .IncludeDirectory("~/MyApp/", "*.state.js", true)
    ...
    );

See that tests are placed inside of this structure, but not part of the bundle...

An extract of the index.cshtml

<html data-ng-app="MyApp">
    <head>
      ...
      @Styles.Render("~/Content/css")
    </head>
    <body>        
        <div class="body" data-ui-view="body"></div>
        @Scripts.Render("~/js/angular")
        @Scripts.Render("~/js/app")
  </body>

During development, small setting in web.config <compilation debug="true" loads all the files separately, easy to debug.

Just change the debug="false" and there are only two JS loads from the server in production

share|improve this answer
1  
Splitting files by the entity type is an interesting approach! I'm pretty happy with the layout of my JS files at the moment. How do you include templates? Can you do this with the bundles? I do this at the moment with a custom HtmlHelper extension that generates a bunch of <script type="text/ng-template"></script> includes depending on the directory you give it. –  Jamie Dec 30 '13 at 16:15
    
At the moment, we do have templates mapped in states (angular-ui-router). But we plan to do some tricks to move all templates into one file: docs.angularjs.org/api/ng.$templateCache. But at this moment, the advantage of the above approach I see in fact, that during development we have all the small files there... modules by Aspects/Entities... and with one change for production we deliver just few minified JS/css files. So I am pretty happy with Asp.NET bundle stuff ;) –  Radim Köhler Dec 30 '13 at 16:37
    
Yes I would very much like to split my templates into chunks too. –  Jamie Dec 30 '13 at 17:05
    
Cool I'll have a look into replacing require with the bundles, performance of them isn't a massive issue as I'm implementing appcache :) –  Jamie Dec 30 '13 at 17:07
    
Good luck with the 1) ASP.NET best features to make 2) amazing Angular running ... approach ;) –  Radim Köhler Dec 30 '13 at 17:15

Normally I use ASP.NET MVC and WebAPI on the server and then using ASP.NET Bundling makes a lot of sense. It is there out of the box and is easy to use. With AngularJS I am less worried about forgetting a script file and not noticing as you declare all dependencies at the module level. If one is missing the whole app doesn't run making these, otherwise hard to spot, errors really obvious.

Grunt is also a powerful option but one I would only go for if I was doing Node on the server. In that case I will be doing a lot more through grunt anyway.

share|improve this answer
    
"Grunt is also a powerful option but one I would only go for if I was doing Node on the server" That is a complete non argument imo, your front end dev tooling shouldn't be influenced by your backend server technology. The two should be completely unrelated, Node just happens to be a great tool to do both. –  Willem D'haeseleer Dec 30 '13 at 14:28
    
"With AngularJS I am less worried about forgetting a script file and not noticing as you declare all dependencies" - that's a nice thought actually! I'll go for the bundles for now, seems like the most appropriate (and fastest choice considering having not touched grunt before). Can always review later, the time consuming part is removing Require! –  Jamie Dec 30 '13 at 17:09

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.