From 07e35f7040f1aeb52e3736c1b65f62c0ac4dfd71 Mon Sep 17 00:00:00 2001 From: FrozenPandaz Date: Fri, 3 Mar 2017 00:11:27 -0500 Subject: [PATCH 1/7] feat(@ngtools/webpack): replace server bootstrap code --- packages/@ngtools/webpack/src/loader.ts | 28 +++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/packages/@ngtools/webpack/src/loader.ts b/packages/@ngtools/webpack/src/loader.ts index 97bd6b1feda4..e12bf8460407 100644 --- a/packages/@ngtools/webpack/src/loader.ts +++ b/packages/@ngtools/webpack/src/loader.ts @@ -7,6 +7,16 @@ import {LoaderContext, ModuleReason} from './webpack'; const loaderUtils = require('loader-utils'); const NormalModule = require('webpack/lib/NormalModule'); +// This is a map of changes which need to be made +const changeMap: {[key: string]: string} = { + platformBrowserDynamic: 'platformBrowser', + platformDynamicServer: 'platformServer' +}; + +const importLocations: { [key: string]: string } = { + platformBrowser: '@angular/platform-browser', + platformServer: '@angular/platform-server' +}; function _getContentOfKeyLiteral(_source: ts.SourceFile, node: ts.Node): string { if (!node) { @@ -205,9 +215,10 @@ function _replaceBootstrap(plugin: AotPlugin, refactor: TypeScriptFileRefactor) = refactor.findAstNodes(access, ts.SyntaxKind.CallExpression, true) as ts.CallExpression[]; return previous.concat(expressions); }, []) + .filter((call: ts.CallExpression) => call.expression.kind == ts.SyntaxKind.Identifier) .filter((call: ts.CallExpression) => { - return call.expression.kind == ts.SyntaxKind.Identifier - && (call.expression as ts.Identifier).text == 'platformBrowserDynamic'; + // Find if the expression matches one of the replacement targets + return !!changeMap[(call.expression as ts.Identifier).text]; }); if (calls.length == 0) { @@ -222,7 +233,10 @@ function _replaceBootstrap(plugin: AotPlugin, refactor: TypeScriptFileRefactor) refactor.replaceNode(call.arguments[0], entryModule.className + 'NgFactory'); }); - calls.forEach(call => refactor.replaceNode(call.expression, 'platformBrowser')); + calls.forEach(call => { + // Replace with mapped replacement + refactor.replaceNode(call.expression, changeMap[(call.expression as ts.Identifier).text]); + }); bootstraps .forEach((bs: ts.PropertyAccessExpression) => { @@ -230,8 +244,14 @@ function _replaceBootstrap(plugin: AotPlugin, refactor: TypeScriptFileRefactor) refactor.replaceNode(bs.name, 'bootstrapModuleFactory'); }); - refactor.insertImport('platformBrowser', '@angular/platform-browser'); refactor.insertImport(entryModule.className + 'NgFactory', ngFactoryPath); + + // We need to import the additional imports which are used + Object.keys(importLocations) + .filter(imp => refactor.sourceMatch(new RegExp(imp))) + .forEach(imp => { + refactor.insertImport(imp, importLocations[imp]); + }); } export function removeModuleIdOnlyForTesting(refactor: TypeScriptFileRefactor) { From 55f64fe08554f347ff9d308153134eb6ae770387 Mon Sep 17 00:00:00 2001 From: FrozenPandaz Date: Sat, 4 Mar 2017 14:26:04 -0500 Subject: [PATCH 2/7] refactor(@ngtools/webpack): merge platform maps to one --- packages/@ngtools/webpack/src/loader.ts | 36 ++++++++++++++----------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/packages/@ngtools/webpack/src/loader.ts b/packages/@ngtools/webpack/src/loader.ts index e12bf8460407..5dd0c0f7ab4d 100644 --- a/packages/@ngtools/webpack/src/loader.ts +++ b/packages/@ngtools/webpack/src/loader.ts @@ -4,18 +4,24 @@ import {AotPlugin} from './plugin'; import {TypeScriptFileRefactor} from './refactor'; import {LoaderContext, ModuleReason} from './webpack'; +interface Platform { + name: string; + importLocation: string; +} + const loaderUtils = require('loader-utils'); const NormalModule = require('webpack/lib/NormalModule'); // This is a map of changes which need to be made -const changeMap: {[key: string]: string} = { - platformBrowserDynamic: 'platformBrowser', - platformDynamicServer: 'platformServer' -}; - -const importLocations: { [key: string]: string } = { - platformBrowser: '@angular/platform-browser', - platformServer: '@angular/platform-server' +const changeMap: {[key: string]: Platform} = { + platformBrowserDynamic: { + name: 'platformBrowser', + importLocation: '@angular/platform-browser' + }, + platformDynamicServer: { + name: 'platformServer', + importLocation: '@angular/platform-server' + } }; function _getContentOfKeyLiteral(_source: ts.SourceFile, node: ts.Node): string { @@ -234,8 +240,13 @@ function _replaceBootstrap(plugin: AotPlugin, refactor: TypeScriptFileRefactor) }); calls.forEach(call => { + const platform = changeMap[(call.expression as ts.Identifier).text]; + // Replace with mapped replacement - refactor.replaceNode(call.expression, changeMap[(call.expression as ts.Identifier).text]); + refactor.replaceNode(call.expression, platform.name); + + // Add the appropriate import + refactor.insertImport(platform.name, platform.importLocation); }); bootstraps @@ -245,13 +256,6 @@ function _replaceBootstrap(plugin: AotPlugin, refactor: TypeScriptFileRefactor) }); refactor.insertImport(entryModule.className + 'NgFactory', ngFactoryPath); - - // We need to import the additional imports which are used - Object.keys(importLocations) - .filter(imp => refactor.sourceMatch(new RegExp(imp))) - .forEach(imp => { - refactor.insertImport(imp, importLocations[imp]); - }); } export function removeModuleIdOnlyForTesting(refactor: TypeScriptFileRefactor) { From 413aed25fa68a43aa5152452c005246da55049e6 Mon Sep 17 00:00:00 2001 From: FrozenPandaz Date: Wed, 8 Mar 2017 23:17:57 -0500 Subject: [PATCH 3/7] test(@ngtools/webpack): add tests for webpack for platform-server --- .../test-server-app/app/app.component.html | 5 ++++ .../test-server-app/app/app.component.scss | 3 ++ .../test-server-app/app/app.component.ts | 15 ++++++++++ .../webpack/test-server-app/app/app.module.ts | 27 +++++++++++++++++ .../app/feature/feature.module.ts | 20 +++++++++++++ .../app/feature/lazy-feature.module.ts | 23 ++++++++++++++ .../webpack/test-server-app/app/injectable.ts | 8 +++++ .../test-server-app/app/lazy.module.ts | 26 ++++++++++++++++ .../webpack/test-server-app/app/main.ts | 5 ++++ .../assets/webpack/test-server-app/index.html | 12 ++++++++ .../webpack/test-server-app/package.json | 27 +++++++++++++++++ .../webpack/test-server-app/tsconfig.json | 24 +++++++++++++++ .../webpack/test-server-app/webpack.config.js | 30 +++++++++++++++++++ tests/e2e/tests/packages/webpack/server.ts | 22 ++++++++++++++ 14 files changed, 247 insertions(+) create mode 100644 tests/e2e/assets/webpack/test-server-app/app/app.component.html create mode 100644 tests/e2e/assets/webpack/test-server-app/app/app.component.scss create mode 100644 tests/e2e/assets/webpack/test-server-app/app/app.component.ts create mode 100644 tests/e2e/assets/webpack/test-server-app/app/app.module.ts create mode 100644 tests/e2e/assets/webpack/test-server-app/app/feature/feature.module.ts create mode 100644 tests/e2e/assets/webpack/test-server-app/app/feature/lazy-feature.module.ts create mode 100644 tests/e2e/assets/webpack/test-server-app/app/injectable.ts create mode 100644 tests/e2e/assets/webpack/test-server-app/app/lazy.module.ts create mode 100644 tests/e2e/assets/webpack/test-server-app/app/main.ts create mode 100644 tests/e2e/assets/webpack/test-server-app/index.html create mode 100644 tests/e2e/assets/webpack/test-server-app/package.json create mode 100644 tests/e2e/assets/webpack/test-server-app/tsconfig.json create mode 100644 tests/e2e/assets/webpack/test-server-app/webpack.config.js create mode 100644 tests/e2e/tests/packages/webpack/server.ts diff --git a/tests/e2e/assets/webpack/test-server-app/app/app.component.html b/tests/e2e/assets/webpack/test-server-app/app/app.component.html new file mode 100644 index 000000000000..5a532db9308f --- /dev/null +++ b/tests/e2e/assets/webpack/test-server-app/app/app.component.html @@ -0,0 +1,5 @@ +
+

hello world

+ lazy + +
diff --git a/tests/e2e/assets/webpack/test-server-app/app/app.component.scss b/tests/e2e/assets/webpack/test-server-app/app/app.component.scss new file mode 100644 index 000000000000..5cde7b922336 --- /dev/null +++ b/tests/e2e/assets/webpack/test-server-app/app/app.component.scss @@ -0,0 +1,3 @@ +:host { + background-color: blue; +} diff --git a/tests/e2e/assets/webpack/test-server-app/app/app.component.ts b/tests/e2e/assets/webpack/test-server-app/app/app.component.ts new file mode 100644 index 000000000000..82a4059565d3 --- /dev/null +++ b/tests/e2e/assets/webpack/test-server-app/app/app.component.ts @@ -0,0 +1,15 @@ +import {Component, ViewEncapsulation} from '@angular/core'; +import {MyInjectable} from './injectable'; + + +@Component({ + selector: 'app-root', + templateUrl: './app.component.html', + styleUrls: ['./app.component.scss'], + encapsulation: ViewEncapsulation.None +}) +export class AppComponent { + constructor(public inj: MyInjectable) { + console.log(inj); + } +} diff --git a/tests/e2e/assets/webpack/test-server-app/app/app.module.ts b/tests/e2e/assets/webpack/test-server-app/app/app.module.ts new file mode 100644 index 000000000000..6f8407fdfd29 --- /dev/null +++ b/tests/e2e/assets/webpack/test-server-app/app/app.module.ts @@ -0,0 +1,27 @@ +import { NgModule, Component } from '@angular/core'; +import { ServerModule } from '@angular/platform-server'; +import { RouterModule } from '@angular/router'; +import { AppComponent } from './app.component'; + +@Component({ + selector: 'home-view', + template: 'home!' +}) +export class HomeView {} + + +@NgModule({ + declarations: [ + AppComponent, + HomeView + ], + imports: [ + ServerModule, + RouterModule.forRoot([ + {path: 'lazy', loadChildren: './lazy.module#LazyModule'}, + {path: '', component: HomeView} + ]) + ], + bootstrap: [AppComponent] +}) +export class AppModule { } diff --git a/tests/e2e/assets/webpack/test-server-app/app/feature/feature.module.ts b/tests/e2e/assets/webpack/test-server-app/app/feature/feature.module.ts new file mode 100644 index 000000000000..f464ca028b05 --- /dev/null +++ b/tests/e2e/assets/webpack/test-server-app/app/feature/feature.module.ts @@ -0,0 +1,20 @@ +import {NgModule, Component} from '@angular/core'; +import {RouterModule} from '@angular/router'; + +@Component({ + selector: 'feature-component', + template: 'foo.html' +}) +export class FeatureComponent {} + +@NgModule({ + declarations: [ + FeatureComponent + ], + imports: [ + RouterModule.forChild([ + { path: '', component: FeatureComponent} + ]) + ] +}) +export class FeatureModule {} diff --git a/tests/e2e/assets/webpack/test-server-app/app/feature/lazy-feature.module.ts b/tests/e2e/assets/webpack/test-server-app/app/feature/lazy-feature.module.ts new file mode 100644 index 000000000000..8fafca158b24 --- /dev/null +++ b/tests/e2e/assets/webpack/test-server-app/app/feature/lazy-feature.module.ts @@ -0,0 +1,23 @@ +import {NgModule, Component} from '@angular/core'; +import {RouterModule} from '@angular/router'; +import {HttpModule, Http} from '@angular/http'; + +@Component({ + selector: 'lazy-feature-comp', + template: 'lazy feature!' +}) +export class LazyFeatureComponent {} + +@NgModule({ + imports: [ + RouterModule.forChild([ + {path: '', component: LazyFeatureComponent, pathMatch: 'full'}, + {path: 'feature', loadChildren: './feature.module#FeatureModule'} + ]), + HttpModule + ], + declarations: [LazyFeatureComponent] +}) +export class LazyFeatureModule { + constructor(http: Http) {} +} diff --git a/tests/e2e/assets/webpack/test-server-app/app/injectable.ts b/tests/e2e/assets/webpack/test-server-app/app/injectable.ts new file mode 100644 index 000000000000..04d8486586c4 --- /dev/null +++ b/tests/e2e/assets/webpack/test-server-app/app/injectable.ts @@ -0,0 +1,8 @@ +import {Injectable, Inject, ViewContainerRef} from '@angular/core'; +import {DOCUMENT} from '@angular/platform-browser'; + + +@Injectable() +export class MyInjectable { + constructor(public viewContainer: ViewContainerRef, @Inject(DOCUMENT) public doc) {} +} diff --git a/tests/e2e/assets/webpack/test-server-app/app/lazy.module.ts b/tests/e2e/assets/webpack/test-server-app/app/lazy.module.ts new file mode 100644 index 000000000000..96da4de7515b --- /dev/null +++ b/tests/e2e/assets/webpack/test-server-app/app/lazy.module.ts @@ -0,0 +1,26 @@ +import {NgModule, Component} from '@angular/core'; +import {RouterModule} from '@angular/router'; +import {HttpModule, Http} from '@angular/http'; + +@Component({ + selector: 'lazy-comp', + template: 'lazy!' +}) +export class LazyComponent {} + +@NgModule({ + imports: [ + RouterModule.forChild([ + {path: '', component: LazyComponent, pathMatch: 'full'}, + {path: 'feature', loadChildren: './feature/feature.module#FeatureModule'}, + {path: 'lazy-feature', loadChildren: './feature/lazy-feature.module#LazyFeatureModule'} + ]), + HttpModule + ], + declarations: [LazyComponent] +}) +export class LazyModule { + constructor(http: Http) {} +} + +export class SecondModule {} diff --git a/tests/e2e/assets/webpack/test-server-app/app/main.ts b/tests/e2e/assets/webpack/test-server-app/app/main.ts new file mode 100644 index 000000000000..a86acffcd839 --- /dev/null +++ b/tests/e2e/assets/webpack/test-server-app/app/main.ts @@ -0,0 +1,5 @@ +import 'core-js/es7/reflect'; +import {platformDynamicServer} from '@angular/platform-dynamic-server'; +import {AppModule} from './app.module'; + +platformDynamicServer().bootstrapModule(AppModule); diff --git a/tests/e2e/assets/webpack/test-server-app/index.html b/tests/e2e/assets/webpack/test-server-app/index.html new file mode 100644 index 000000000000..89fb0893c35d --- /dev/null +++ b/tests/e2e/assets/webpack/test-server-app/index.html @@ -0,0 +1,12 @@ + + + + Document + + + + + + + + diff --git a/tests/e2e/assets/webpack/test-server-app/package.json b/tests/e2e/assets/webpack/test-server-app/package.json new file mode 100644 index 000000000000..79973a6ee08a --- /dev/null +++ b/tests/e2e/assets/webpack/test-server-app/package.json @@ -0,0 +1,27 @@ +{ + "name": "test", + "license": "MIT", + "dependencies": { + "@angular/common": "^4.0.0-rc.2", + "@angular/compiler": "^4.0.0-rc.2", + "@angular/compiler-cli": "^4.0.0-rc.2", + "@angular/core": "^4.0.0-rc.2", + "@angular/http": "^4.0.0-rc.2", + "@angular/platform-browser": "^4.0.0-rc.2", + "@angular/platform-browser-dynamic": "^4.0.0-rc.2", + "@angular/platform-server": "^4.0.0-rc.2", + "@angular/router": "^4.0.0-rc.2", + "@ngtools/webpack": "0.0.0", + "core-js": "^2.4.1", + "rxjs": "^5.2.0", + "zone.js": "^0.7.7" + }, + "devDependencies": { + "node-sass": "^4.5.0", + "performance-now": "^0.2.0", + "raw-loader": "^0.5.1", + "sass-loader": "^6.0.3", + "typescript": "^2.2.1", + "webpack": "2.2.1" + } +} diff --git a/tests/e2e/assets/webpack/test-server-app/tsconfig.json b/tests/e2e/assets/webpack/test-server-app/tsconfig.json new file mode 100644 index 000000000000..cee38681d901 --- /dev/null +++ b/tests/e2e/assets/webpack/test-server-app/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "baseUrl": "", + "module": "es2015", + "moduleResolution": "node", + "target": "es5", + "noImplicitAny": false, + "sourceMap": true, + "mapRoot": "", + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "lib": [ + "es2016", + "dom" + ], + "outDir": "lib", + "skipLibCheck": true, + "rootDir": "." + }, + "angularCompilerOptions": { + "genDir": "./app/ngfactory", + "entryModule": "app/app.module#AppModule" + } +} diff --git a/tests/e2e/assets/webpack/test-server-app/webpack.config.js b/tests/e2e/assets/webpack/test-server-app/webpack.config.js new file mode 100644 index 000000000000..8694fa6a6900 --- /dev/null +++ b/tests/e2e/assets/webpack/test-server-app/webpack.config.js @@ -0,0 +1,30 @@ +const ngToolsWebpack = require('@ngtools/webpack'); + +module.exports = { + resolve: { + extensions: ['.ts', '.js'] + }, + target: 'web', + entry: './app/main.ts', + output: { + path: './dist', + publicPath: 'dist/', + filename: 'app.main.js' + }, + plugins: [ + new ngToolsWebpack.AotPlugin({ + tsConfigPath: './tsconfig.json' + }) + ], + module: { + loaders: [ + { test: /\.scss$/, loaders: ['raw-loader', 'sass-loader'] }, + { test: /\.css$/, loader: 'raw-loader' }, + { test: /\.html$/, loader: 'raw-loader' }, + { test: /\.ts$/, loader: '@ngtools/webpack' } + ] + }, + devServer: { + historyApiFallback: true + } +}; diff --git a/tests/e2e/tests/packages/webpack/server.ts b/tests/e2e/tests/packages/webpack/server.ts new file mode 100644 index 000000000000..38c844efa847 --- /dev/null +++ b/tests/e2e/tests/packages/webpack/server.ts @@ -0,0 +1,22 @@ +import {normalize} from 'path'; +import {createProjectFromAsset} from '../../../utils/assets'; +import {exec} from '../../../utils/process'; +import {expectFileSizeToBeUnder, expectFileToMatch} from '../../../utils/fs'; + + +export default function(skipCleaning: () => void) { + return Promise.resolve() + .then(() => createProjectFromAsset('webpack/test-server-app')) + .then(() => exec(normalize('node_modules/.bin/webpack'), '-p')) + .then(() => expectFileSizeToBeUnder('dist/app.main.js', 420000)) + .then(() => expectFileSizeToBeUnder('dist/0.app.main.js', 10000)) + .then(() => expectFileToMatch('dist/app.main.js', + new RegExp('.bootstrapModuleFactory')) + .then(() => expectFileToMatch('dist/app.main.js', + new RegExp('MyInjectable.ctorParameters = .*' + + 'type: .*ViewContainerRef.*' + + 'type: undefined, decorators.*Inject.*args: .*DOCUMENT.*')) + .then(() => expectFileToMatch('dist/app.main.js', + new RegExp('AppComponent.ctorParameters = .*MyInjectable')) + .then(() => skipCleaning()); +} From 0de9c82bcff89be4803ef4c3aa0b0450b995e83a Mon Sep 17 00:00:00 2001 From: FrozenPandaz Date: Thu, 9 Mar 2017 11:26:15 -0500 Subject: [PATCH 4/7] test(@ngtools/webpack): import platform server from correct place --- tests/e2e/assets/webpack/test-server-app/app/main.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/assets/webpack/test-server-app/app/main.ts b/tests/e2e/assets/webpack/test-server-app/app/main.ts index a86acffcd839..9aae9848fbcc 100644 --- a/tests/e2e/assets/webpack/test-server-app/app/main.ts +++ b/tests/e2e/assets/webpack/test-server-app/app/main.ts @@ -1,5 +1,5 @@ import 'core-js/es7/reflect'; -import {platformDynamicServer} from '@angular/platform-dynamic-server'; +import {platformDynamicServer} from '@angular/platform-server'; import {AppModule} from './app.module'; platformDynamicServer().bootstrapModule(AppModule); From cc94ae0e0a6aeb74cf47ffebe96cd58a3d42978f Mon Sep 17 00:00:00 2001 From: FrozenPandaz Date: Sat, 11 Mar 2017 16:16:28 -0500 Subject: [PATCH 5/7] test(@ngtools/webpack): remove bundle size tests --- tests/e2e/tests/packages/webpack/server.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/e2e/tests/packages/webpack/server.ts b/tests/e2e/tests/packages/webpack/server.ts index 38c844efa847..4b1248464a72 100644 --- a/tests/e2e/tests/packages/webpack/server.ts +++ b/tests/e2e/tests/packages/webpack/server.ts @@ -1,15 +1,13 @@ import {normalize} from 'path'; import {createProjectFromAsset} from '../../../utils/assets'; import {exec} from '../../../utils/process'; -import {expectFileSizeToBeUnder, expectFileToMatch} from '../../../utils/fs'; +import {expectFileToMatch} from '../../../utils/fs'; export default function(skipCleaning: () => void) { return Promise.resolve() .then(() => createProjectFromAsset('webpack/test-server-app')) .then(() => exec(normalize('node_modules/.bin/webpack'), '-p')) - .then(() => expectFileSizeToBeUnder('dist/app.main.js', 420000)) - .then(() => expectFileSizeToBeUnder('dist/0.app.main.js', 10000)) .then(() => expectFileToMatch('dist/app.main.js', new RegExp('.bootstrapModuleFactory')) .then(() => expectFileToMatch('dist/app.main.js', From 08dbdb250570608621be52c2819df3eb96fd777c Mon Sep 17 00:00:00 2001 From: FrozenPandaz Date: Sat, 11 Mar 2017 17:28:47 -0500 Subject: [PATCH 6/7] test(@ngtools/webpack): remove -p flag from server test --- tests/e2e/tests/packages/webpack/server.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/tests/packages/webpack/server.ts b/tests/e2e/tests/packages/webpack/server.ts index 4b1248464a72..1ccc7b73fba4 100644 --- a/tests/e2e/tests/packages/webpack/server.ts +++ b/tests/e2e/tests/packages/webpack/server.ts @@ -7,7 +7,7 @@ import {expectFileToMatch} from '../../../utils/fs'; export default function(skipCleaning: () => void) { return Promise.resolve() .then(() => createProjectFromAsset('webpack/test-server-app')) - .then(() => exec(normalize('node_modules/.bin/webpack'), '-p')) + .then(() => exec(normalize('node_modules/.bin/webpack'))) .then(() => expectFileToMatch('dist/app.main.js', new RegExp('.bootstrapModuleFactory')) .then(() => expectFileToMatch('dist/app.main.js', From 31774d7e971d981246ca813cb0b18ee4b35338de Mon Sep 17 00:00:00 2001 From: FrozenPandaz Date: Thu, 4 May 2017 01:19:22 -0400 Subject: [PATCH 7/7] test(@ngtools/webpack): update to ng4.0.0 --- .../webpack/test-server-app/package.json | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/tests/e2e/assets/webpack/test-server-app/package.json b/tests/e2e/assets/webpack/test-server-app/package.json index 79973a6ee08a..664d1312ce8b 100644 --- a/tests/e2e/assets/webpack/test-server-app/package.json +++ b/tests/e2e/assets/webpack/test-server-app/package.json @@ -2,26 +2,27 @@ "name": "test", "license": "MIT", "dependencies": { - "@angular/common": "^4.0.0-rc.2", - "@angular/compiler": "^4.0.0-rc.2", - "@angular/compiler-cli": "^4.0.0-rc.2", - "@angular/core": "^4.0.0-rc.2", - "@angular/http": "^4.0.0-rc.2", - "@angular/platform-browser": "^4.0.0-rc.2", - "@angular/platform-browser-dynamic": "^4.0.0-rc.2", - "@angular/platform-server": "^4.0.0-rc.2", - "@angular/router": "^4.0.0-rc.2", + "@angular/animations": "^4.0.0", + "@angular/common": "^4.0.0", + "@angular/compiler": "^4.0.0", + "@angular/compiler-cli": "^4.0.0", + "@angular/core": "^4.0.0", + "@angular/http": "^4.0.0", + "@angular/platform-browser": "^4.0.0", + "@angular/platform-browser-dynamic": "^4.0.0", + "@angular/platform-server": "^4.0.0", + "@angular/router": "^4.0.0", "@ngtools/webpack": "0.0.0", "core-js": "^2.4.1", - "rxjs": "^5.2.0", - "zone.js": "^0.7.7" + "rxjs": "^5.3.1", + "zone.js": "^0.8.10" }, "devDependencies": { "node-sass": "^4.5.0", "performance-now": "^0.2.0", "raw-loader": "^0.5.1", "sass-loader": "^6.0.3", - "typescript": "^2.2.1", + "typescript": "^2.3.2", "webpack": "2.2.1" } }