Skip to content

Commit 5ade33b

Browse files
Update to Angular 4 (but leave directory name as Angular2Spa until finished)
1 parent b5636ea commit 5ade33b

File tree

9 files changed

+132
-106
lines changed

9 files changed

+132
-106
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { NgModule } from '@angular/core';
2+
import { BrowserModule } from '@angular/platform-browser';
3+
import { FormsModule } from '@angular/forms';
4+
import { HttpModule } from '@angular/http';
5+
import { sharedConfig } from './app.module.shared';
6+
7+
@NgModule({
8+
bootstrap: sharedConfig.bootstrap,
9+
declarations: sharedConfig.declarations,
10+
imports: [
11+
BrowserModule,
12+
FormsModule,
13+
HttpModule,
14+
...sharedConfig.imports
15+
],
16+
providers: [
17+
{ provide: 'ORIGIN_URL', useValue: location.origin }
18+
]
19+
})
20+
export class AppModule {
21+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { NgModule } from '@angular/core';
2+
import { ServerModule } from '@angular/platform-server';
3+
import { sharedConfig } from './app.module.shared';
4+
5+
@NgModule({
6+
bootstrap: sharedConfig.bootstrap,
7+
declarations: sharedConfig.declarations,
8+
imports: [
9+
ServerModule,
10+
...sharedConfig.imports
11+
]
12+
})
13+
export class AppModule {
14+
}
Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import { NgModule } from '@angular/core';
22
import { RouterModule } from '@angular/router';
3-
import { UniversalModule } from 'angular2-universal';
3+
44
import { AppComponent } from './components/app/app.component'
55
import { NavMenuComponent } from './components/navmenu/navmenu.component';
66
import { HomeComponent } from './components/home/home.component';
77
import { FetchDataComponent } from './components/fetchdata/fetchdata.component';
88
import { CounterComponent } from './components/counter/counter.component';
99

10-
@NgModule({
10+
export const sharedConfig: NgModule = {
1111
bootstrap: [ AppComponent ],
1212
declarations: [
1313
AppComponent,
@@ -17,7 +17,6 @@ import { CounterComponent } from './components/counter/counter.component';
1717
HomeComponent
1818
],
1919
imports: [
20-
UniversalModule, // Must be first import. This automatically imports BrowserModule, HttpModule, and JsonpModule too.
2120
RouterModule.forRoot([
2221
{ path: '', redirectTo: 'home', pathMatch: 'full' },
2322
{ path: 'home', component: HomeComponent },
@@ -26,6 +25,4 @@ import { CounterComponent } from './components/counter/counter.component';
2625
{ path: '**', redirectTo: 'home' }
2726
])
2827
]
29-
})
30-
export class AppModule {
31-
}
28+
};

templates/Angular2Spa/ClientApp/app/components/fetchdata/fetchdata.component.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Component } from '@angular/core';
1+
import { Component, Inject } from '@angular/core';
22
import { Http } from '@angular/http';
33

44
@Component({
@@ -8,8 +8,8 @@ import { Http } from '@angular/http';
88
export class FetchDataComponent {
99
public forecasts: WeatherForecast[];
1010

11-
constructor(http: Http) {
12-
http.get('/api/SampleData/WeatherForecasts').subscribe(result => {
11+
constructor(http: Http, @Inject('ORIGIN_URL') originUrl: string) {
12+
http.get(originUrl + '/api/SampleData/WeatherForecasts').subscribe(result => {
1313
this.forecasts = result.json() as WeatherForecast[];
1414
});
1515
}
Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,22 @@
1-
import 'angular2-universal-polyfills/browser';
1+
import 'reflect-metadata';
2+
import 'zone.js';
23
import { enableProdMode } from '@angular/core';
3-
import { platformUniversalDynamic } from 'angular2-universal';
4-
import { AppModule } from './app/app.module';
5-
import 'bootstrap';
6-
const rootElemTagName = 'app'; // Update this if you change your root component selector
4+
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
5+
import { AppModule } from './app/app.module.client';
76

8-
// Enable either Hot Module Reloading or production mode
97
if (module['hot']) {
108
module['hot'].accept();
119
module['hot'].dispose(() => {
1210
// Before restarting the app, we create a new root element and dispose the old one
13-
const oldRootElem = document.querySelector(rootElemTagName);
14-
const newRootElem = document.createElement(rootElemTagName);
11+
const oldRootElem = document.querySelector('app');
12+
const newRootElem = document.createElement('app');
1513
oldRootElem.parentNode.insertBefore(newRootElem, oldRootElem);
16-
platform.destroy();
14+
modulePromise.then(appModule => appModule.destroy());
1715
});
1816
} else {
1917
enableProdMode();
2018
}
2119

22-
// Boot the application, either now or when the DOM content is loaded
23-
const platform = platformUniversalDynamic();
24-
const bootApplication = () => { platform.bootstrapModule(AppModule); };
25-
if (document.readyState === 'complete') {
26-
bootApplication();
27-
} else {
28-
document.addEventListener('DOMContentLoaded', bootApplication);
29-
}
20+
// Note: @ng-tools/webpack looks for the following expression when performing production
21+
// builds. Don't change how this line looks, otherwise you may break tree-shaking.
22+
const modulePromise = platformBrowserDynamic().bootstrapModule(AppModule);
Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,36 @@
1-
import 'angular2-universal-polyfills';
2-
import 'angular2-universal-patch';
1+
import 'reflect-metadata';
32
import 'zone.js';
3+
import 'rxjs/add/operator/first';
4+
import { enableProdMode, ApplicationRef, NgZone, ValueProvider } from '@angular/core';
5+
import { platformDynamicServer, PlatformState, INITIAL_CONFIG } from '@angular/platform-server';
46
import { createServerRenderer, RenderResult } from 'aspnet-prerendering';
5-
import { enableProdMode } from '@angular/core';
6-
import { platformNodeDynamic } from 'angular2-universal';
7-
import { AppModule } from './app/app.module';
7+
import { AppModule } from './app/app.module.server';
88

99
enableProdMode();
10-
const platform = platformNodeDynamic();
1110

1211
export default createServerRenderer(params => {
13-
return new Promise<RenderResult>((resolve, reject) => {
14-
const requestZone = Zone.current.fork({
15-
name: 'angular-universal request',
16-
properties: {
17-
baseUrl: '/',
18-
requestUrl: params.url,
19-
originUrl: params.origin,
20-
preboot: false,
21-
document: '<app></app>'
22-
},
23-
onHandleError: (parentZone, currentZone, targetZone, error) => {
24-
// If any error occurs while rendering the module, reject the whole operation
25-
reject(error);
26-
return true;
27-
}
28-
});
12+
const providers = [
13+
{ provide: INITIAL_CONFIG, useValue: { document: '<app></app>', url: params.url } },
14+
{ provide: 'ORIGIN_URL', useValue: params.origin }
15+
];
16+
17+
return platformDynamicServer(providers).bootstrapModule(AppModule).then(moduleRef => {
18+
const appRef = moduleRef.injector.get(ApplicationRef);
19+
const state = moduleRef.injector.get(PlatformState);
20+
const zone = moduleRef.injector.get(NgZone);
2921

30-
return requestZone.run<Promise<string>>(() => platform.serializeModule(AppModule)).then(html => {
31-
resolve({ html: html });
32-
}, reject);
22+
return new Promise<RenderResult>((resolve, reject) => {
23+
zone.onError.subscribe(errorInfo => reject(errorInfo));
24+
appRef.isStable.first(isStable => isStable).subscribe(() => {
25+
// Because 'onStable' fires before 'onError', we have to delay slightly before
26+
// completing the request in case there's an error to report
27+
setImmediate(() => {
28+
resolve({
29+
html: state.renderToString()
30+
});
31+
moduleRef.destroy();
32+
});
33+
});
34+
});
3335
});
3436
});

templates/Angular2Spa/ClientApp/test/boot-tests.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// Load required polyfills and testing libraries
2-
import 'angular2-universal-polyfills';
2+
import 'reflect-metadata';
3+
import 'zone.js';
34
import 'zone.js/dist/long-stack-trace-zone';
45
import 'zone.js/dist/proxy.js';
56
import 'zone.js/dist/sync-test';

templates/Angular2Spa/package.json

Lines changed: 49 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -5,58 +5,56 @@
55
"test": "karma start ClientApp/test/karma.conf.js"
66
},
77
"dependencies": {
8-
"@angular/common": "^2.4.5",
9-
"@angular/compiler": "^2.4.5",
10-
"@angular/core": "^2.4.5",
11-
"@angular/forms": "^2.4.5",
12-
"@angular/http": "^2.4.5",
13-
"@angular/platform-browser": "^2.4.5",
14-
"@angular/platform-browser-dynamic": "^2.4.5",
15-
"@angular/platform-server": "^2.4.5",
16-
"@angular/router": "^3.4.5",
17-
"@types/node": "^6.0.42",
18-
"angular2-platform-node": "~2.0.11",
19-
"angular2-template-loader": "^0.6.2",
20-
"angular2-universal": "^2.1.0-rc.1",
21-
"angular2-universal-patch": "^0.2.1",
22-
"angular2-universal-polyfills": "^2.1.0-rc.1",
23-
"aspnet-prerendering": "^2.0.0",
24-
"aspnet-webpack": "^1.0.17",
25-
"awesome-typescript-loader": "^3.0.0",
26-
"bootstrap": "^3.3.7",
27-
"css": "^2.2.1",
28-
"css-loader": "^0.25.0",
29-
"es6-shim": "^0.35.1",
30-
"event-source-polyfill": "^0.0.7",
31-
"expose-loader": "^0.7.1",
32-
"extract-text-webpack-plugin": "^2.0.0-rc",
33-
"file-loader": "^0.9.0",
34-
"html-loader": "^0.4.4",
35-
"isomorphic-fetch": "^2.2.1",
36-
"jquery": "^2.2.1",
37-
"json-loader": "^0.5.4",
38-
"preboot": "^4.5.2",
39-
"raw-loader": "^0.5.1",
40-
"rxjs": "^5.0.1",
41-
"style-loader": "^0.13.1",
42-
"to-string-loader": "^1.1.5",
43-
"typescript": "^2.2.1",
44-
"url-loader": "^0.5.7",
45-
"webpack": "^2.2.0",
46-
"webpack-hot-middleware": "^2.12.2",
47-
"webpack-merge": "^0.14.1",
48-
"zone.js": "^0.7.6"
8+
"@angular/animations": "4.1.2",
9+
"@angular/common": "4.1.2",
10+
"@angular/compiler": "4.1.2",
11+
"@angular/core": "4.1.2",
12+
"@angular/forms": "4.1.2",
13+
"@angular/http": "4.1.2",
14+
"@angular/platform-browser": "4.1.2",
15+
"@angular/platform-browser-dynamic": "4.1.2",
16+
"@angular/platform-server": "4.1.2",
17+
"@angular/router": "4.1.2",
18+
"@types/node": "7.0.18",
19+
"angular2-template-loader": "0.6.2",
20+
"aspnet-prerendering": "^2.0.5",
21+
"aspnet-webpack": "^1.0.29",
22+
"awesome-typescript-loader": "3.1.3",
23+
"bootstrap": "3.3.7",
24+
"css": "2.2.1",
25+
"css-loader": "0.28.1",
26+
"es6-shim": "0.35.3",
27+
"event-source-polyfill": "0.0.9",
28+
"expose-loader": "0.7.3",
29+
"extract-text-webpack-plugin": "2.1.0",
30+
"file-loader": "0.11.1",
31+
"html-loader": "0.4.5",
32+
"isomorphic-fetch": "2.2.1",
33+
"jquery": "3.2.1",
34+
"json-loader": "0.5.4",
35+
"preboot": "4.5.2",
36+
"raw-loader": "0.5.1",
37+
"reflect-metadata": "0.1.10",
38+
"rxjs": "5.4.0",
39+
"style-loader": "0.17.0",
40+
"to-string-loader": "1.1.5",
41+
"typescript": "2.3.2",
42+
"url-loader": "0.5.8",
43+
"webpack": "2.5.1",
44+
"webpack-hot-middleware": "2.18.0",
45+
"webpack-merge": "4.1.0",
46+
"zone.js": "0.8.10"
4947
},
5048
"devDependencies": {
51-
"@types/chai": "^3.4.34",
52-
"@types/jasmine": "^2.5.37",
53-
"chai": "^3.5.0",
54-
"jasmine-core": "^2.5.2",
55-
"karma": "^1.3.0",
56-
"karma-chai": "^0.1.0",
57-
"karma-chrome-launcher": "^2.0.0",
58-
"karma-cli": "^1.0.1",
59-
"karma-jasmine": "^1.0.2",
60-
"karma-webpack": "^1.8.0"
49+
"@types/chai": "3.5.2",
50+
"@types/jasmine": "2.5.47",
51+
"chai": "3.5.0",
52+
"jasmine-core": "2.6.1",
53+
"karma": "1.7.0",
54+
"karma-chai": "0.1.0",
55+
"karma-chrome-launcher": "2.1.1",
56+
"karma-cli": "1.0.1",
57+
"karma-jasmine": "1.1.0",
58+
"karma-webpack": "2.0.3"
6159
}
6260
}

templates/Angular2Spa/webpack.config.vendor.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,15 @@ module.exports = (env) => {
1616
},
1717
entry: {
1818
vendor: [
19+
'@angular/animations',
1920
'@angular/common',
2021
'@angular/compiler',
2122
'@angular/core',
23+
'@angular/forms',
2224
'@angular/http',
2325
'@angular/platform-browser',
2426
'@angular/platform-browser-dynamic',
2527
'@angular/router',
26-
'@angular/platform-server',
27-
'angular2-universal',
28-
'angular2-universal-polyfills',
2928
'bootstrap',
3029
'bootstrap/dist/css/bootstrap.css',
3130
'es6-shim',
@@ -43,6 +42,7 @@ module.exports = (env) => {
4342
plugins: [
4443
new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery' }), // Maps these identifiers to the jQuery package (because Bootstrap expects it to be a global variable)
4544
new webpack.ContextReplacementPlugin(/\@angular\b.*\b(bundles|linker)/, path.join(__dirname, './ClientApp')), // Workaround for https://github.com/angular/angular/issues/11580
45+
new webpack.ContextReplacementPlugin(/angular(\\|\/)core(\\|\/)@angular/, path.join(__dirname, './ClientApp')), // Workaround for https://github.com/angular/angular/issues/14898
4646
new webpack.IgnorePlugin(/^vertx$/) // Workaround for https://github.com/stefanpenner/es6-promise/issues/100
4747
]
4848
};

0 commit comments

Comments
 (0)