After exploring different designs and structures for hosting an Angular SPA in a Visual Studio Web-Project, I have found my inspiration. My goal is to:
- Utilize Visual Studio and ASP.NET (MVC) functionalities to the fullest
- Organize functionality into smaller, more manageable files (controller, state, config, directive)
- Group the logic of each aspect (usually entities) within their own folders (e.g. Employee/)
- Maintain close proximity between view, controller, test following a structure like ng-boilerplate
- Structuring files as shown below:
An example folder/file structure
// external libraries
Scripts
Scripts/angular.js
Scripts/ui-bootstrap-x.y.js
Scripts/...
// project libraries
MyApp
MyApp/Module
MyApp/Module/Employee
MyApp/Module/Employee/Employee.state.js
MyApp/Module/Employee/EmployeeList.ctrl.js
MyApp/Module/Employee/EmployeeDetail.ctrl.js
MyApp/Module/Employee/DisplayEmployee.dirc.js
MyApp/Module/Employee/Employee.spec.js
// same approach for other components
...
The key lies in the suffix of each JavaScript file:
- ".dirc.js" - directive
- ".ctrl.js" - controller
- ".spec.js" - tests
- ...
With this structure 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)
...
);
Notice that tests are included in the structure but not in the bundle...
A snippet from 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, by setting web.config <compilation debug="true"
, all files load separately for easy debugging.
Simply changing debug="false"
results in only two JS loads from the server in production settings.