feat(platform-server): support @angular/http from @angular/platform-server
This change installs HttpModule with ServerModule, and overrides bindings to service Http requests made from the server with the 'xhr2' NPM package. Outgoing requests are wrapped in a Zone macro-task, so they will be tracked within the Angular zone and cause the isStable API to show 'false' until they return. This is essential for Universal support of server-side HTTP.
This commit is contained in:
parent
30380d010b
commit
9559d3e949
2
build.sh
2
build.sh
@ -10,11 +10,11 @@ PACKAGES=(core
|
|||||||
forms
|
forms
|
||||||
platform-browser
|
platform-browser
|
||||||
platform-browser-dynamic
|
platform-browser-dynamic
|
||||||
|
http
|
||||||
platform-server
|
platform-server
|
||||||
platform-webworker
|
platform-webworker
|
||||||
platform-webworker-dynamic
|
platform-webworker-dynamic
|
||||||
animation
|
animation
|
||||||
http
|
|
||||||
upgrade
|
upgrade
|
||||||
router
|
router
|
||||||
compiler-cli
|
compiler-cli
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
"@angular/core": ["../../../dist/packages-dist/core"],
|
"@angular/core": ["../../../dist/packages-dist/core"],
|
||||||
"@angular/common": ["../../../dist/packages-dist/common"],
|
"@angular/common": ["../../../dist/packages-dist/common"],
|
||||||
"@angular/compiler": ["../../../dist/packages-dist/compiler"],
|
"@angular/compiler": ["../../../dist/packages-dist/compiler"],
|
||||||
|
"@angular/http": ["../../../dist/packages-dist/http"],
|
||||||
"@angular/platform-server": ["../../../dist/packages-dist/platform-server"],
|
"@angular/platform-server": ["../../../dist/packages-dist/platform-server"],
|
||||||
"@angular/platform-browser": ["../../../dist/packages-dist/platform-browser"],
|
"@angular/platform-browser": ["../../../dist/packages-dist/platform-browser"],
|
||||||
"@angular/tsc-wrapped": ["../../../dist/tools/@angular/tsc-wrapped"]
|
"@angular/tsc-wrapped": ["../../../dist/tools/@angular/tsc-wrapped"]
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
"@angular/compiler": ["../../../dist/packages-dist/compiler"],
|
"@angular/compiler": ["../../../dist/packages-dist/compiler"],
|
||||||
"@angular/compiler/*": ["../../../dist/packages-dist/compiler/*"],
|
"@angular/compiler/*": ["../../../dist/packages-dist/compiler/*"],
|
||||||
"@angular/compiler-cli": ["../../../dist/packages-dist/compiler-cli"],
|
"@angular/compiler-cli": ["../../../dist/packages-dist/compiler-cli"],
|
||||||
|
"@angular/http": ["../../../dist/packages-dist/http"],
|
||||||
"@angular/platform-server": ["../../../dist/packages-dist/platform-server"],
|
"@angular/platform-server": ["../../../dist/packages-dist/platform-server"],
|
||||||
"@angular/platform-browser": ["../../../dist/packages-dist/platform-browser"],
|
"@angular/platform-browser": ["../../../dist/packages-dist/platform-browser"],
|
||||||
"@angular/tsc-wrapped": ["../../../dist/tools/@angular/tsc-wrapped"],
|
"@angular/tsc-wrapped": ["../../../dist/tools/@angular/tsc-wrapped"],
|
||||||
|
@ -14,7 +14,8 @@
|
|||||||
"@angular/platform-browser": "0.0.0-PLACEHOLDER"
|
"@angular/platform-browser": "0.0.0-PLACEHOLDER"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"parse5": "^2.2.1"
|
"parse5": "^2.2.1",
|
||||||
|
"xhr2": "^0.1.4"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
127
modules/@angular/platform-server/src/http.ts
Normal file
127
modules/@angular/platform-server/src/http.ts
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright Google Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by an MIT-style license that can be
|
||||||
|
* found in the LICENSE file at https://angular.io/license
|
||||||
|
*/
|
||||||
|
|
||||||
|
const xhr2: any = require('xhr2');
|
||||||
|
|
||||||
|
import {Injectable, Provider} from '@angular/core';
|
||||||
|
import {BrowserXhr, Connection, ConnectionBackend, Http, ReadyState, Request, RequestOptions, Response, XHRBackend, XSRFStrategy} from '@angular/http';
|
||||||
|
|
||||||
|
import {Observable} from 'rxjs/Observable';
|
||||||
|
import {Observer} from 'rxjs/Observer';
|
||||||
|
import {Subscription} from 'rxjs/Subscription';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class ServerXhr implements BrowserXhr {
|
||||||
|
build(): XMLHttpRequest { return new xhr2.XMLHttpRequest(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class ServerXsrfStrategy implements XSRFStrategy {
|
||||||
|
configureRequest(req: Request): void {}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ZoneMacroTaskConnection implements Connection {
|
||||||
|
response: Observable<Response>;
|
||||||
|
lastConnection: Connection;
|
||||||
|
|
||||||
|
constructor(public request: Request, backend: XHRBackend) {
|
||||||
|
this.response = new Observable((observer: Observer<Response>) => {
|
||||||
|
let task: Task = null;
|
||||||
|
let scheduled: boolean = false;
|
||||||
|
let sub: Subscription = null;
|
||||||
|
let savedResult: any = null;
|
||||||
|
let savedError: any = null;
|
||||||
|
|
||||||
|
const scheduleTask = (_task: Task) => {
|
||||||
|
task = _task;
|
||||||
|
scheduled = true;
|
||||||
|
|
||||||
|
this.lastConnection = backend.createConnection(request);
|
||||||
|
sub = (this.lastConnection.response as Observable<Response>)
|
||||||
|
.subscribe(
|
||||||
|
res => savedResult = res,
|
||||||
|
err => {
|
||||||
|
if (!scheduled) {
|
||||||
|
throw new Error('invoke twice');
|
||||||
|
}
|
||||||
|
savedError = err;
|
||||||
|
scheduled = false;
|
||||||
|
task.invoke();
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
if (!scheduled) {
|
||||||
|
throw new Error('invoke twice');
|
||||||
|
}
|
||||||
|
scheduled = false;
|
||||||
|
task.invoke();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const cancelTask = (_task: Task) => {
|
||||||
|
if (!scheduled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
scheduled = false;
|
||||||
|
if (sub) {
|
||||||
|
sub.unsubscribe();
|
||||||
|
sub = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onComplete = () => {
|
||||||
|
if (savedError !== null) {
|
||||||
|
observer.error(savedError);
|
||||||
|
} else {
|
||||||
|
observer.next(savedResult);
|
||||||
|
observer.complete();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// MockBackend is currently synchronous, which means that if scheduleTask is by
|
||||||
|
// scheduleMacroTask, the request will hit MockBackend and the response will be
|
||||||
|
// sent, causing task.invoke() to be called.
|
||||||
|
const _task = Zone.current.scheduleMacroTask(
|
||||||
|
'ZoneMacroTaskConnection.subscribe', onComplete, {}, () => null, cancelTask);
|
||||||
|
scheduleTask(_task);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
if (scheduled && task) {
|
||||||
|
task.zone.cancelTask(task);
|
||||||
|
scheduled = false;
|
||||||
|
}
|
||||||
|
if (sub) {
|
||||||
|
sub.unsubscribe();
|
||||||
|
sub = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
get readyState(): ReadyState {
|
||||||
|
return !!this.lastConnection ? this.lastConnection.readyState : ReadyState.Unsent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ZoneMacroTaskBackend implements ConnectionBackend {
|
||||||
|
constructor(private backend: XHRBackend) {}
|
||||||
|
|
||||||
|
createConnection(request: any): ZoneMacroTaskConnection {
|
||||||
|
return new ZoneMacroTaskConnection(request, this.backend);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function httpFactory(xhrBackend: XHRBackend, options: RequestOptions) {
|
||||||
|
const macroBackend = new ZoneMacroTaskBackend(xhrBackend);
|
||||||
|
return new Http(macroBackend, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SERVER_HTTP_PROVIDERS: Provider[] = [
|
||||||
|
{provide: Http, useFactory: httpFactory, deps: [XHRBackend, RequestOptions]},
|
||||||
|
{provide: BrowserXhr, useClass: ServerXhr},
|
||||||
|
{provide: XSRFStrategy, useClass: ServerXsrfStrategy},
|
||||||
|
];
|
@ -8,8 +8,11 @@
|
|||||||
|
|
||||||
import {PlatformLocation} from '@angular/common';
|
import {PlatformLocation} from '@angular/common';
|
||||||
import {platformCoreDynamic} from '@angular/compiler';
|
import {platformCoreDynamic} from '@angular/compiler';
|
||||||
import {APP_BOOTSTRAP_LISTENER, InjectionToken, Injector, NgModule, PLATFORM_INITIALIZER, PlatformRef, Provider, RENDERER_V2_DIRECT, RendererV2, RootRenderer, createPlatformFactory, isDevMode, platformCore} from '@angular/core';
|
import {APP_BOOTSTRAP_LISTENER, Injectable, InjectionToken, Injector, NgModule, PLATFORM_INITIALIZER, PlatformRef, Provider, RENDERER_V2_DIRECT, RendererV2, RootRenderer, createPlatformFactory, isDevMode, platformCore} from '@angular/core';
|
||||||
|
import {HttpModule} from '@angular/http';
|
||||||
import {BrowserModule, DOCUMENT} from '@angular/platform-browser';
|
import {BrowserModule, DOCUMENT} from '@angular/platform-browser';
|
||||||
|
|
||||||
|
import {SERVER_HTTP_PROVIDERS} from './http';
|
||||||
import {ServerPlatformLocation} from './location';
|
import {ServerPlatformLocation} from './location';
|
||||||
import {Parse5DomAdapter, parseDocument} from './parse5_adapter';
|
import {Parse5DomAdapter, parseDocument} from './parse5_adapter';
|
||||||
import {PlatformState} from './platform_state';
|
import {PlatformState} from './platform_state';
|
||||||
@ -86,9 +89,8 @@ export const INITIAL_CONFIG = new InjectionToken<PlatformConfig>('Server.INITIAL
|
|||||||
*/
|
*/
|
||||||
@NgModule({
|
@NgModule({
|
||||||
exports: [BrowserModule],
|
exports: [BrowserModule],
|
||||||
providers: [
|
imports: [HttpModule],
|
||||||
SERVER_RENDER_PROVIDERS,
|
providers: [SERVER_RENDER_PROVIDERS, SERVER_HTTP_PROVIDERS],
|
||||||
]
|
|
||||||
})
|
})
|
||||||
export class ServerModule {
|
export class ServerModule {
|
||||||
}
|
}
|
||||||
|
@ -7,11 +7,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {PlatformLocation} from '@angular/common';
|
import {PlatformLocation} from '@angular/common';
|
||||||
import {ApplicationRef, CompilerFactory, Component, NgModule, NgModuleRef, PlatformRef, destroyPlatform, getPlatform} from '@angular/core';
|
import {ApplicationRef, CompilerFactory, Component, NgModule, NgModuleRef, NgZone, PlatformRef, destroyPlatform, getPlatform} from '@angular/core';
|
||||||
import {async, inject} from '@angular/core/testing';
|
import {async, inject} from '@angular/core/testing';
|
||||||
|
import {Http, HttpModule, Response, ResponseOptions, XHRBackend} from '@angular/http';
|
||||||
|
import {MockBackend, MockConnection} from '@angular/http/testing';
|
||||||
import {DOCUMENT} from '@angular/platform-browser';
|
import {DOCUMENT} from '@angular/platform-browser';
|
||||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||||
import {INITIAL_CONFIG, PlatformState, ServerModule, platformDynamicServer, renderModule, renderModuleFactory} from '@angular/platform-server';
|
import {INITIAL_CONFIG, PlatformState, ServerModule, platformDynamicServer, renderModule, renderModuleFactory} from '@angular/platform-server';
|
||||||
|
|
||||||
import {Subscription} from 'rxjs/Subscription';
|
import {Subscription} from 'rxjs/Subscription';
|
||||||
import {filter} from 'rxjs/operator/filter';
|
import {filter} from 'rxjs/operator/filter';
|
||||||
import {first} from 'rxjs/operator/first';
|
import {first} from 'rxjs/operator/first';
|
||||||
@ -21,7 +24,15 @@ import {toPromise} from 'rxjs/operator/toPromise';
|
|||||||
class MyServerApp {
|
class MyServerApp {
|
||||||
}
|
}
|
||||||
|
|
||||||
@NgModule({declarations: [MyServerApp], imports: [ServerModule], bootstrap: [MyServerApp]})
|
@NgModule({
|
||||||
|
bootstrap: [MyServerApp],
|
||||||
|
declarations: [MyServerApp],
|
||||||
|
imports: [ServerModule],
|
||||||
|
providers: [
|
||||||
|
MockBackend,
|
||||||
|
{provide: XHRBackend, useExisting: MockBackend},
|
||||||
|
]
|
||||||
|
})
|
||||||
class ExampleModule {
|
class ExampleModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,6 +66,30 @@ class MyStylesApp {
|
|||||||
class ExampleStylesModule {
|
class ExampleStylesModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
bootstrap: [MyServerApp],
|
||||||
|
declarations: [MyServerApp],
|
||||||
|
imports: [HttpModule, ServerModule],
|
||||||
|
providers: [
|
||||||
|
MockBackend,
|
||||||
|
{provide: XHRBackend, useExisting: MockBackend},
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class HttpBeforeExampleModule {
|
||||||
|
}
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
bootstrap: [MyServerApp],
|
||||||
|
declarations: [MyServerApp],
|
||||||
|
imports: [ServerModule, HttpModule],
|
||||||
|
providers: [
|
||||||
|
MockBackend,
|
||||||
|
{provide: XHRBackend, useExisting: MockBackend},
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class HttpAfterExampleModule {
|
||||||
|
}
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
if (getDOM().supportsDOMEvents()) return; // NODE only
|
if (getDOM().supportsDOMEvents()) return; // NODE only
|
||||||
|
|
||||||
@ -196,5 +231,86 @@ export function main() {
|
|||||||
});
|
});
|
||||||
})));
|
})));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('http', () => {
|
||||||
|
it('can inject Http', async(() => {
|
||||||
|
const platform = platformDynamicServer(
|
||||||
|
[{provide: INITIAL_CONFIG, useValue: {document: '<app></app>'}}]);
|
||||||
|
platform.bootstrapModule(ExampleModule).then(ref => {
|
||||||
|
expect(ref.injector.get(Http) instanceof Http).toBeTruthy();
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
it('can make Http requests', async(() => {
|
||||||
|
const platform = platformDynamicServer(
|
||||||
|
[{provide: INITIAL_CONFIG, useValue: {document: '<app></app>'}}]);
|
||||||
|
platform.bootstrapModule(ExampleModule).then(ref => {
|
||||||
|
const mock = ref.injector.get(MockBackend);
|
||||||
|
const http = ref.injector.get(Http);
|
||||||
|
ref.injector.get(NgZone).run(() => {
|
||||||
|
NgZone.assertInAngularZone();
|
||||||
|
mock.connections.subscribe((mc: MockConnection) => {
|
||||||
|
NgZone.assertInAngularZone();
|
||||||
|
expect(mc.request.url).toBe('/testing');
|
||||||
|
mc.mockRespond(new Response(new ResponseOptions({body: 'success!', status: 200})));
|
||||||
|
});
|
||||||
|
http.get('/testing').subscribe(resp => {
|
||||||
|
NgZone.assertInAngularZone();
|
||||||
|
expect(resp.text()).toBe('success!');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
it('requests are macrotasks', async(() => {
|
||||||
|
const platform = platformDynamicServer(
|
||||||
|
[{provide: INITIAL_CONFIG, useValue: {document: '<app></app>'}}]);
|
||||||
|
platform.bootstrapModule(ExampleModule).then(ref => {
|
||||||
|
const mock = ref.injector.get(MockBackend);
|
||||||
|
const http = ref.injector.get(Http);
|
||||||
|
expect(ref.injector.get(NgZone).hasPendingMacrotasks).toBeFalsy();
|
||||||
|
ref.injector.get(NgZone).run(() => {
|
||||||
|
NgZone.assertInAngularZone();
|
||||||
|
mock.connections.subscribe((mc: MockConnection) => {
|
||||||
|
expect(ref.injector.get(NgZone).hasPendingMacrotasks).toBeTruthy();
|
||||||
|
mc.mockRespond(new Response(new ResponseOptions({body: 'success!', status: 200})));
|
||||||
|
});
|
||||||
|
http.get('/testing').subscribe(resp => { expect(resp.text()).toBe('success!'); });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
it('works when HttpModule is included before ServerModule', async(() => {
|
||||||
|
const platform = platformDynamicServer(
|
||||||
|
[{provide: INITIAL_CONFIG, useValue: {document: '<app></app>'}}]);
|
||||||
|
platform.bootstrapModule(HttpBeforeExampleModule).then(ref => {
|
||||||
|
const mock = ref.injector.get(MockBackend);
|
||||||
|
const http = ref.injector.get(Http);
|
||||||
|
expect(ref.injector.get(NgZone).hasPendingMacrotasks).toBeFalsy();
|
||||||
|
ref.injector.get(NgZone).run(() => {
|
||||||
|
NgZone.assertInAngularZone();
|
||||||
|
mock.connections.subscribe((mc: MockConnection) => {
|
||||||
|
expect(ref.injector.get(NgZone).hasPendingMacrotasks).toBeTruthy();
|
||||||
|
mc.mockRespond(new Response(new ResponseOptions({body: 'success!', status: 200})));
|
||||||
|
});
|
||||||
|
http.get('/testing').subscribe(resp => { expect(resp.text()).toBe('success!'); });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
it('works when HttpModule is included after ServerModule', async(() => {
|
||||||
|
const platform = platformDynamicServer(
|
||||||
|
[{provide: INITIAL_CONFIG, useValue: {document: '<app></app>'}}]);
|
||||||
|
platform.bootstrapModule(HttpAfterExampleModule).then(ref => {
|
||||||
|
const mock = ref.injector.get(MockBackend);
|
||||||
|
const http = ref.injector.get(Http);
|
||||||
|
expect(ref.injector.get(NgZone).hasPendingMacrotasks).toBeFalsy();
|
||||||
|
ref.injector.get(NgZone).run(() => {
|
||||||
|
NgZone.assertInAngularZone();
|
||||||
|
mock.connections.subscribe((mc: MockConnection) => {
|
||||||
|
expect(ref.injector.get(NgZone).hasPendingMacrotasks).toBeTruthy();
|
||||||
|
mc.mockRespond(new Response(new ResponseOptions({body: 'success!', status: 200})));
|
||||||
|
});
|
||||||
|
http.get('/testing').subscribe(resp => { expect(resp.text()).toBe('success!'); });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
"@angular/core": ["../../../dist/packages-dist/core"],
|
"@angular/core": ["../../../dist/packages-dist/core"],
|
||||||
"@angular/common": ["../../../dist/packages-dist/common"],
|
"@angular/common": ["../../../dist/packages-dist/common"],
|
||||||
"@angular/compiler": ["../../../dist/packages-dist/compiler"],
|
"@angular/compiler": ["../../../dist/packages-dist/compiler"],
|
||||||
|
"@angular/http": ["../../../dist/packages-dist/http"],
|
||||||
"@angular/platform-browser": ["../../../dist/packages-dist/platform-browser"],
|
"@angular/platform-browser": ["../../../dist/packages-dist/platform-browser"],
|
||||||
"@angular/platform-browser-dynamic": ["../../../dist/packages-dist/platform-browser-dynamic"]
|
"@angular/platform-browser-dynamic": ["../../../dist/packages-dist/platform-browser-dynamic"]
|
||||||
},
|
},
|
||||||
|
@ -6713,6 +6713,10 @@
|
|||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"xhr2": {
|
||||||
|
"version": "0.1.4",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"xml2js": {
|
"xml2js": {
|
||||||
"version": "0.4.15",
|
"version": "0.4.15",
|
||||||
"dev": true
|
"dev": true
|
||||||
|
6
npm-shrinkwrap.json
generated
6
npm-shrinkwrap.json
generated
@ -9817,6 +9817,12 @@
|
|||||||
"resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-2.0.0.tgz",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"xhr2": {
|
||||||
|
"version": "0.1.4",
|
||||||
|
"from": "xhr2@>=0.1.4 <0.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/xhr2/-/xhr2-0.1.4.tgz",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"xml2js": {
|
"xml2js": {
|
||||||
"version": "0.4.15",
|
"version": "0.4.15",
|
||||||
"from": "xml2js@>=0.4.4 <0.5.0",
|
"from": "xml2js@>=0.4.4 <0.5.0",
|
||||||
|
@ -94,6 +94,7 @@
|
|||||||
"universal-analytics": "^0.3.9",
|
"universal-analytics": "^0.3.9",
|
||||||
"vrsource-tslint-rules": "^4.0.0",
|
"vrsource-tslint-rules": "^4.0.0",
|
||||||
"webpack": "^1.12.6",
|
"webpack": "^1.12.6",
|
||||||
|
"xhr2": "^0.1.4",
|
||||||
"yargs": "^3.31.0",
|
"yargs": "^3.31.0",
|
||||||
"yarn": "^0.19.1"
|
"yarn": "^0.19.1"
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ set -ex -o pipefail
|
|||||||
|
|
||||||
# These ones can be `npm link`ed for fast development
|
# These ones can be `npm link`ed for fast development
|
||||||
LINKABLE_PKGS=(
|
LINKABLE_PKGS=(
|
||||||
$(pwd)/dist/packages-dist/{common,forms,core,compiler,compiler-cli,platform-{browser,server},platform-browser-dynamic,router}
|
$(pwd)/dist/packages-dist/{common,forms,core,compiler,compiler-cli,platform-{browser,server},platform-browser-dynamic,router,http}
|
||||||
$(pwd)/dist/tools/@angular/tsc-wrapped
|
$(pwd)/dist/tools/@angular/tsc-wrapped
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ System.config({
|
|||||||
'rxjs': 'node_modules/rxjs',
|
'rxjs': 'node_modules/rxjs',
|
||||||
'parse5': 'dist/all/empty.js',
|
'parse5': 'dist/all/empty.js',
|
||||||
'url': 'dist/all/empty.js',
|
'url': 'dist/all/empty.js',
|
||||||
|
'xhr2': 'dist/all/empty.js',
|
||||||
'@angular/platform-server/src/parse5_adapter': 'dist/all/empty.js',
|
'@angular/platform-server/src/parse5_adapter': 'dist/all/empty.js',
|
||||||
'angular2/*': 'dist/all/angular2/*.js',
|
'angular2/*': 'dist/all/angular2/*.js',
|
||||||
'angular2/src/alt_router/router_testing_providers':
|
'angular2/src/alt_router/router_testing_providers':
|
||||||
|
Loading…
x
Reference in New Issue
Block a user