Reputation: 1988
I am using Visual Studio 2017 to develop an Angular 4.1 SPA application that is hosted in an MVC application (.Net 4.6). I created the Angular part using @angular/cli and then merged it into the existing MVC application. It is structured as described in the CandorDeveloper article(http://candordeveloper.com/2017/04/12/how-to-use-angular-cli-with-visual-studio-2017/).
This all works well but as @angular/cli uses Webpack it is painfully slow. Any change to Html, typescript, or css requires a build which takes about 4 minutes. I had previously had an application that was set up the same but didn't use @angular/cli or Webpack. It was still a Visual Studio 2017 MVC application (.Net 4.6) hosting an Angular 4.1 SPA application but it used SystemJs. It was very fast to build and I had the same excellent debugging experience in VS2017 as I would with any .net web application. Because of this I thought I would try to use both SystemJs and Webpack.
My idea was to build the application with SystemJs in VS2017 "Debug" mode to get the speed and convenience and then use Webpack for "Release" mode to build the production version and be able to use AOT. To try to achieve this, I put the following in my _Layout.cshtml file:
@if(!HttpContext.Current.IsDebuggingEnabled)
{
<script type="text/javascript" src="~/Scripts/NgApp/inline.bundle.js"></script>
<script type="text/javascript" src="~/Scripts/NgApp/polyfills.bundle.js"></script>
<script type="text/javascript" src="~/Scripts/NgApp/styles.bundle.js"></script>
<script type="text/javascript" src="~/Scripts/NgApp/vendor.bundle.js"></script>
<script type="text/javascript" src="~/Scripts/NgApp/main.bundle.js"></script>
}
else
{
<!-- 1. Load libraries -->
<!-- Polyfill(s) for older browsers -->
<script src="~/MyAppCli/node_modules/core-js/client/shim.min.js"></script>
<script src="~/MyAppCli/node_modules/zone.js/dist/zone.js"></script>
<script src="~/MyAppCli/node_modules/systemjs/dist/system.src.js"></script>
<script src="~/MyAppCli/src/systemjs.config.js"></script>
<script>
System.import('src/main.js')
.catch(function (err) { console.error(err); });
</script>
}
To my project's pre-build event, I added:
if $(ConfigurationName) == Release (
echo "cd $(SolutionDir)MyApp\MyAppCli" &&^
cd "$(SolutionDir)MyApp\MyAppCli" &&^
echo "building v" &&^
npm run build
)
I then added systemjs to the devDependencies of the package.json file and created an appropriate systemjs.config.js file.
My systemjs.config.js:
(function (global)
{
System.config({
paths: {
// paths serve as alias
'npm:': MyAppCli/node_modules/'
},
// map tells the System loader where to look for things
map: {
// our app is within the app folder
'app': 'src',
// angular bundles
'@angular/animations': 'npm:@angular/animations/bundles/animations.umd.js',
'@angular/animations/browser': 'npm:@angular/animations/bundles/animations-browser.umd.js',
'@angular/core': 'npm:@angular/core/bundles/core.umd.js',
'@angular/common': 'npm:@angular/common/bundles/common.umd.js',
'@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
'@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
'@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
'@angular/platform-browser/animations': 'npm:@angular/platform-browser/bundles/platform-browser-animations.umd.js',
'@angular/http': 'npm:@angular/http/bundles/http.umd.js',
'@angular/router': 'npm:@angular/router/bundles/router.umd.js',
'@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
// other libraries
'cldr-data': 'npm:cldr-data',
'rxjs': 'npm:rxjs',
'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js',
'jszip': 'npm:jszip',
'systemjs-plugin-json': 'npm:systemjs-plugin-json',
// Kendo UI for Angular scopes
'@progress': 'npm:@progress',
'@telerik': 'npm:@telerik'
},
meta: {
'*.json': {
loader: 'systemjs-plugin-json'
}
},
// packages tells the System loader how to load when no filename and/or no extension
packages: {
app: {
defaultExtension: 'js',
meta: {
'./*.js': {
loader: 'systemjs-angular-loader.js'
}
}
},
rxjs: {
defaultExtension: 'js'
},
jszip: {
defaultExtension: 'js',
main: './dist/jszip.js'
},
'systemjs-plugin-json': {
defaultExtension: 'js',
main: 'json.js'
},
// Kendo UI for Angular packages
'npm:@progress/kendo-angular-buttons': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-charts': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-dateinputs': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-dropdowns': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-dialog': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-grid': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-inputs': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-intl': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-l10n': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-excel-export': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-layout': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-scrollview': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-sortable': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-popup': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-resize-sensor': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-upload': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-charts': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-data-query': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-date-math': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-drawing': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-file-saver': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-intl': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-ooxml': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-popup-common': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@telerik/kendo-draggable': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@telerik/kendo-dropdowns-common': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@telerik/kendo-intl': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@telerik/kendo-inputs-common': {
main: './dist/npm/main.js',
defaultExtension: 'js'
}
}
});
})(this);
The project works find in "Release" (using Webpack) and can be built or served using @angular/cli. The problem is trying to run it in "Debug" with SystemJs. It starts out ok and loads the main.js file but is not able to load the app.module. I get the error: "(SystemJS) XHR error (404 Not Found) loading http://localhost/MyApp/MyAppCli/src/app/app.module Error loading http://localhost/MyApp/MyAppCli/src/app/app.module as "./app/app.module" from http://localhost/MyApp/MyAppCli/src/main.js"
The main files and app structure is:
MyApp
|-----MyAppCli
| |----src
| | |----app
| | | |----app.module.js
| | |
| | |----main.js
| | |----systemjs.config.js
| | |----systemjs-angular-loader.js
| |
| |----node_modules
| |----package.json
|
|-----Views
| |----Shared
| |----_Layout.cshtml
|
|-----web.config
Is it possible to use both Systemjs and Webpack and if so, How can I get this working?
Please help.
Upvotes: 0
Views: 1025
Reputation: 1988
Thanks yurzui! That last comment of yours was what resolved this issue. Once I had 'map': { app: 'MyAppCli/src' in the systemjs.config.js and System.import('app/main') in the _Layout.cshtml (I'm not using Index.html) it worked. I am now able to use both Systemjs and Webpack in my project. The only odd thing is that IE11 is very slow to load but can quickly close while Chrome is very quick to load but closing the VS2017 debugger takes ages. I'm guessing this is a VS2017 bug with the new debugging functionality they have for IE and Chrome because Firefox loads and unloads quickly but doesn't have the breakpoint debugging in VS2017.
Thanks again!
Upvotes: 1