I'm looking for some best practices and instructions on how to set up and integrate angular-cli (webpack) with Visual Studio 2015 in MVC 5 (not Core).
I realize there's a similar question asked here (how to set up asp.net angular 2 project using Angular-Cli with ASP.NET Core in Visual Studio 2015?), but that was for Asp.net Core only. My project could not move over to Core yet due to server technical issues.
Here is my solution:
Keep an empty index.html
Run ng build to generate index.html with scripts and styles links injected
It works perfectly for my ASP.net MVC 5 project.
However it cannot work with route lazy load until publicPath is supported, because the url for chunk js files is loaded from root folder not dist folder.
For example:
The correct chunk js files should be:
www.example.com/MyApp/dist/[id].chunk.js
But it will load from:
www.example.com/MyApp/[id].chunk.js
I already created a PR to add pulishPath for angular-cli to solve this issue.
https://github.com/angular/angular-cli/pull/3285
Update:
The PR for publicPath has been merged, lazy loading is no long an issue.
My approach to integrating Angular/CLI and MVC: The idea here is to separate the front end development experience from the MVC part, so you don’t have to deal with any of the Visual Studio BS, and enjoy the benefits of the Angular CLI and VS Code.
My app is a hybrid app - most pages and main navigation is classic MVC, but some views are in fact single page applications, where the NG app is embedded into an existing view.
ng new
)ng serve
. The development experience with VS Code is awesome!ng build --prod
. This creates the bundles in the dist folder.A gulp task in the MVC project is responsible for copying the bundles from the SPAs' dist folders into the appropriate folders under Scripts\Frontend. Using Task Runner, the task was bound to to Before Build, so it is automatically executed whenever the app is built. The important gulp command is:
gulp.src('../FrontEndProj/spa1/dist/*bundle.*')
.pipe(gulp.dest('Scripts/Frontend/spa1'));
of course, you need to delete the existing files etc.
In bundles config, I've created a bundle for the styles and a bundle for the scripts. Since prod bundle names are generated with hash by the CLI, I use wildcards:
bundles.add(new script("~/Scripts/spa1/js")
.IncludeDirectory("~/Scripts/Frontend/spa1", inline.*")
.IncludeDirectory("~/Scripts/Frontend/spa1", "polyfills.*")
.IncludeDirectory("~/Scripts/Frontend/spa1", "vendor.*")
.IncludeDirectory("~/Scripts/Frontend/spa1", "main.*"));
(Note that the order you add the files to the bundle is important!)
bundles.add(
new StyleBundle("/Scripts/spa1.css")
.IncludeDirectory("~/Scripts/Frontend/spa1", "*.css")
In your view, add the ng app directive and use the bundles:
@section head {
@Styles.Render("~Scripts/spa1/css")
}
<app-root>Loading...</app-root>
@Scripts.Render("~/Scripts/spa1/js")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With