perf: latest tsickle to tree shake: abstract class methods & interfaces (#18236)

In previous version of tsickle abstract class methods were materialized.
The change resulted in 6Kb savings in angular.io bundle.

This change also required the removal of `@private` and `@return` type
annotation as it is explicitly dissalowed by tsickle.

NOTE: removed casts in front of `makeDecorator` due to:
https://github.com/angular/devkit/issues/45

```
 14938 Jul 19 13:16 0.b19e913fbdd6507d346b.chunk.js
  1535 Jul 19 13:16 inline.d8e019ea3cfdd86c2bd0.bundle.js
589178 Jul 19 13:16 main.54c97bcb6f254776b678.bundle.js
 34333 Jul 19 13:16 polyfills.4a3c9ca9481d53803157.bundle.js

 14938 Jul 18 16:55 0.b19e913fbdd6507d346b.chunk.js
  1535 Jul 18 16:55 inline.0c83abb44fad9a2768a7.bundle.js
582786 Jul 18 16:55 main.ea290db71b051813e156.bundle.js
 34333 Jul 18 16:55 polyfills.4a3c9ca9481d53803157.bundle.js

main savings: 589178 - 582786 = 6,392
```

PR Close #18236
This commit is contained in:
Miško Hevery 2017-07-19 14:01:28 -07:00 committed by Miško Hevery
parent 7ae7573bc8
commit b7a6f52d59
21 changed files with 40 additions and 55 deletions

View File

@ -42,7 +42,7 @@ jobs:
key: angular-{{ .Branch }}-{{ checksum "npm-shrinkwrap.json" }}
- run: bazel run @io_bazel_rules_typescript_node//:bin/npm install
- run: bazel build ...
- run: bazel build packages/...
- save_cache:
key: angular-{{ .Branch }}-{{ checksum "npm-shrinkwrap.json" }}
paths:

View File

@ -1,6 +1,6 @@
{
"name": "angular-srcs",
"version": "4.3.0-beta.1",
"version": "4.3.0",
"dependencies": {
"@types/angularjs": {
"version": "1.5.13-alpha"
@ -4818,7 +4818,7 @@
}
},
"tsickle": {
"version": "0.21.6"
"version": "0.23.4"
},
"tslib": {
"version": "1.7.1"
@ -4878,7 +4878,7 @@
"version": "0.0.6"
},
"typescript": {
"version": "2.3.2"
"version": "2.3.4"
},
"ua-parser-js": {
"version": "0.7.10"

8
npm-shrinkwrap.json generated
View File

@ -1,6 +1,6 @@
{
"name": "angular-srcs",
"version": "4.3.0-beta.1",
"version": "4.3.0",
"dependencies": {
"@types/angularjs": {
"version": "1.5.13-alpha",
@ -7696,9 +7696,9 @@
}
},
"tsickle": {
"version": "0.21.6",
"from": "tsickle@0.21.6",
"resolved": "https://registry.npmjs.org/tsickle/-/tsickle-0.21.6.tgz"
"version": "0.23.4",
"from": "tsickle@0.23.4",
"resolved": "https://registry.npmjs.org/tsickle/-/tsickle-0.23.4.tgz"
},
"tslib": {
"version": "1.7.1",

View File

@ -92,10 +92,10 @@
"source-map-support": "^0.4.2",
"systemjs": "0.18.10",
"ts-api-guardian": "^0.2.2",
"tsickle": "^0.21.1",
"tsickle": "^0.23.4",
"tslint": "^4.1.1",
"tslint-eslint-rules": "^3.1.0",
"typescript": "^2.3.2",
"typescript": "^2.3.4",
"universal-analytics": "^0.3.9",
"vrsource-tslint-rules": "^4.0.0",
"webpack": "^1.12.6",

View File

@ -81,12 +81,10 @@ class CustomLoaderModuleResolutionHostAdapter extends ModuleResolutionHostAdapte
/**
* @internal
* @private
*/
export class NgTools_InternalApi_NG_2 {
/**
* @internal
* @private
*/
static codeGen(options: NgTools_InternalApi_NG2_CodeGen_Options): Promise<any> {
const hostContext: CompilerHostContext =
@ -114,7 +112,6 @@ export class NgTools_InternalApi_NG_2 {
/**
* @internal
* @private
*/
static listLazyRoutes(options: NgTools_InternalApi_NG2_ListLazyRoutes_Options):
NgTools_InternalApi_NG_2_LazyRouteMap {
@ -144,7 +141,6 @@ export class NgTools_InternalApi_NG_2 {
/**
* @internal
* @private
*/
static extractI18n(options: NgTools_InternalApi_NG2_ExtractI18n_Options): Promise<any> {
const hostContext: CompilerHostContext =

View File

@ -49,11 +49,6 @@ export class RouteDef {
}
/**
*
* @returns {LazyRouteMap}
* @private
*/
export function listLazyRoutesOfModule(
entryModule: string, host: AotCompilerHost, reflector: StaticReflector): LazyRouteMap {
const entryRouteDef = RouteDef.fromString(entryModule);
@ -111,7 +106,6 @@ function _resolveModule(modulePath: string, containingFile: string, host: AotCom
/**
* Throw an exception if a route is in a route map, but does not point to the same module.
* @private
*/
function _assertRoute(map: LazyRouteMap, route: LazyRoute) {
const r = route.routeDef.toString();
@ -173,7 +167,6 @@ function _extractLazyRoutesFromStaticModule(
/**
* Get the NgModule Metadata of a symbol.
* @private
*/
function _getNgModuleMetadata(staticSymbol: StaticSymbol, reflector: StaticReflector): NgModule {
const ngModules = reflector.annotations(staticSymbol).filter((s: any) => s instanceof NgModule);
@ -204,7 +197,6 @@ function _collectRoutes(
/**
* Return the loadChildren values of a list of Route.
* @private
*/
function _collectLoadChildren(routes: Route[]): string[] {
return routes.reduce((m, r) => {

View File

@ -231,7 +231,6 @@ class _Scanner {
* @param two second symbol (part of the operator when the second code point matches)
* @param threeCode code point for the third symbol
* @param three third symbol (part of the operator when provided and matches source expression)
* @returns {Token}
*/
scanComplexOperator(
start: number, one: string, twoCode: number, two: string, threeCode?: number,

View File

@ -150,7 +150,7 @@ class _Tokenizer {
}
/**
* @returns {boolean} whether an ICU token has been created
* @returns whether an ICU token has been created
* @internal
*/
private _tokenizeExpansionForm(): boolean {

View File

@ -401,7 +401,6 @@ export class BindingParser {
* @param propName the name of the property / attribute
* @param sourceSpan
* @param isAttr true when binding to an attribute
* @private
*/
private _validatePropertyOrAttributeName(
propName: string, sourceSpan: ParseSourceSpan, isAttr: boolean): void {

View File

@ -202,7 +202,6 @@ function _buildFromEncodedParts(
* $6 = <undefined> query without ?
* $7 = Related fragment without #
* </pre>
* @type {!RegExp}
* @internal
*/
const _splitRe = new RegExp(

View File

@ -151,7 +151,7 @@ export interface Injectable {}
* @stable
* @Annotation
*/
export const Injectable: InjectableDecorator = <InjectableDecorator>makeDecorator('Injectable');
export const Injectable: InjectableDecorator = makeDecorator('Injectable');
/**
* Type of the Self decorator / constructor function.

View File

@ -201,8 +201,7 @@ export type ContentChildren = Query;
* @stable
* @Annotation
*/
export const ContentChildren: ContentChildrenDecorator =
<ContentChildrenDecorator>makePropDecorator(
export const ContentChildren: ContentChildrenDecorator = makePropDecorator(
'ContentChildren',
(selector?: any, data: any = {}) =>
({selector, first: false, isViewQuery: false, descendants: false, ...data}),

View File

@ -400,7 +400,7 @@ export interface Directive {
* @Annotation
*/
export const Directive: DirectiveDecorator =
<DirectiveDecorator>makeDecorator('Directive', (dir: Directive = {}) => dir);
makeDecorator('Directive', (dir: Directive = {}) => dir);
/**
* Type of the Component decorator / constructor function.
@ -683,7 +683,7 @@ export interface Component extends Directive {
* @stable
* @Annotation
*/
export const Component: ComponentDecorator = <ComponentDecorator>makeDecorator(
export const Component: ComponentDecorator = makeDecorator(
'Component', (c: Component = {}) => ({changeDetection: ChangeDetectionStrategy.Default, ...c}),
Directive);
@ -724,8 +724,7 @@ export interface Pipe {
* @stable
* @Annotation
*/
export const Pipe: PipeDecorator =
<PipeDecorator>makeDecorator('Pipe', (p: Pipe) => ({pure: true, ...p}));
export const Pipe: PipeDecorator = makeDecorator('Pipe', (p: Pipe) => ({pure: true, ...p}));
/**

View File

@ -191,4 +191,4 @@ export interface NgModule {
* @Annotation
*/
export const NgModule: NgModuleDecorator =
<NgModuleDecorator>makeDecorator('NgModule', (ngModule: NgModule) => ngModule);
makeDecorator('NgModule', (ngModule: NgModule) => ngModule);

View File

@ -263,7 +263,8 @@ export function Class(clsDef: ClassDefinition): Type<any> {
*/
export function makeDecorator(
name: string, props?: (...args: any[]) => any, parentClass?: any,
chainFn?: (fn: Function) => void): (...args: any[]) => (cls: any) => any {
chainFn?: (fn: Function) => void):
{new (...args: any[]): any; (...args: any[]): any; (...args: any[]): (cls: any) => any;} {
const metaCtor = makeMetadataCtor(props);
function DecoratorFactory(objOrType: any): (cls: any) => any {
@ -298,7 +299,7 @@ export function makeDecorator(
DecoratorFactory.prototype.toString = () => `@${name}`;
(<any>DecoratorFactory).annotationCls = DecoratorFactory;
return DecoratorFactory;
return DecoratorFactory as any;
}
function makeMetadataCtor(props?: (...args: any[]) => any): any {

View File

@ -47,6 +47,14 @@ export function main() {
class SomeService extends Base {}
// Move back into the it which needs it after https://github.com/angular/tsickle/issues/547 is
// fixed.
@Component({template: '<div someDir>{{1 | somePipe}}</div>'})
class TestComp3 {
constructor(service: SomeService) {}
}
function resetTestEnvironmentWithSummaries(summaries?: () => any[]) {
const {platform, ngModule} = getTestBed();
TestBed.resetTestEnvironment();
@ -150,15 +158,10 @@ export function main() {
});
it('should use NgModule metadata from summaries', () => {
@Component({template: '<div someDir>{{1 | somePipe}}</div>'})
class TestComp {
constructor(service: SomeService) {}
}
TestBed
.configureTestingModule(
{providers: [SomeDep], declarations: [TestComp], imports: [SomeModule]})
.createComponent(TestComp);
{providers: [SomeDep], declarations: [TestComp3], imports: [SomeModule]})
.createComponent(TestComp3);
expectInstanceCreated(SomeModule);
expectInstanceCreated(SomeDirective);

View File

@ -43,7 +43,7 @@ let _inFakeAsyncCall = false;
* {@example testing/ts/fake_async.ts region='basic'}
*
* @param fn
* @returns {Function} The function wrapped to be executed in the fakeAsync zone
* @returns The function wrapped to be executed in the fakeAsync zone
*
* @experimental
*/
@ -121,7 +121,7 @@ export function tick(millis: number = 0): void {
* of time that would have been elapsed.
*
* @param maxTurns
* @returns {number} The simulated time elapsed, in millis.
* @returns The simulated time elapsed, in millis.
*
* @experimental
*/

View File

@ -27,7 +27,6 @@ export class Title {
constructor(@Inject(DOCUMENT) private _doc: any) {}
/**
* Get the title of the current HTML document.
* @returns {string}
*/
getTitle(): string { return getDOM().getTitle(this._doc); }

View File

@ -215,7 +215,6 @@ const NON_ALPHANUMERIC_REGEXP = /([^\#-~ |!])/g;
* resulting string can be safely inserted into attribute or
* element text.
* @param value
* @returns {string} escaped text
*/
function encodeEntities(value: string) {
return value.replace(/&/g, '&amp;')

View File

@ -327,7 +327,7 @@ describe('tsc-wrapped', () => {
main(basePath, {basePath})
.then(() => {
const out = readOut('js.map');
expect(out).toContain('"sources":["other_test.ts"]');
expect(out).toContain('"sources":["other_test.ts","../test.ts"]');
done();
})
.catch(e => done.fail(e));
@ -361,7 +361,7 @@ describe('tsc-wrapped', () => {
main(basePath, {basePath})
.then(() => {
const out = readOut('js.map');
expect(out).toContain('"sources":["other_test.ts"]');
expect(out).toContain('"sources":["other_test.ts","../test.ts"]');
done();
})
.catch(e => done.fail(e));

View File

@ -2,4 +2,4 @@
set -u -e -o pipefail
bazel build ...
bazel build packages/...