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