parent
b3d1761825
commit
363dfa5437
|
@ -0,0 +1,138 @@
|
|||
/**
|
||||
* @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
|
||||
*/
|
||||
|
||||
import {Component, ContentChild, Directive, Injectable, Injector, Input, NgModule, NgModuleFactory, NgModuleRef, OnDestroy, Optional, Pipe, PipeTransform, QueryList, SimpleChanges, TemplateRef, Type, ViewChild, ViewContainerRef} from '../../../src/core';
|
||||
import * as r3 from '../../../src/render3/index';
|
||||
|
||||
import {pending_pull_22005} from './small_app_spec';
|
||||
|
||||
const details_elided = {
|
||||
type: Object,
|
||||
} as any;
|
||||
export type $ComponentDef$ = any;
|
||||
|
||||
///////////
|
||||
// Lib A - Compiled pre-Ivy
|
||||
// "enableIvy": false
|
||||
//////////
|
||||
|
||||
// BEGIN FILE: node_modules/libA/module.ts (Compiled without Ivy)
|
||||
@Component({})
|
||||
export class LibAComponent {
|
||||
}
|
||||
|
||||
@NgModule({declarations: [LibAComponent], imports: []})
|
||||
export class LibAModule {
|
||||
}
|
||||
// END FILE: node_modules/libA/module.ts
|
||||
// BEGIN FILE: node_modules/libA/module.metadata.json
|
||||
// Abridged version of metadata
|
||||
const node_modules_libA_module_metadata = {
|
||||
'LibAModule': {
|
||||
refs: ['LibAComponent'],
|
||||
constructorDes: [],
|
||||
},
|
||||
'LibAComponent': {
|
||||
constructorDes: [],
|
||||
}
|
||||
};
|
||||
// END FILE: node_modules/libA/module.metadata.json
|
||||
|
||||
|
||||
///////////
|
||||
// Lib B - Compiled with Ivy
|
||||
// "enableIvy": true
|
||||
//////////
|
||||
|
||||
|
||||
// BEGIN FILE: node_modules/libB/module.ts (Compiled with Ivy)
|
||||
@Component({})
|
||||
export class LibBComponent {
|
||||
// COMPILER GENERATED
|
||||
static ngComponentDef: $ComponentDef$ = r3.defineComponent(details_elided);
|
||||
}
|
||||
|
||||
@NgModule({declarations: [LibAComponent], imports: []})
|
||||
export class LibBModule {
|
||||
// COMPILER GENERATED
|
||||
static ngInjectorDef = pending_pull_22005.defineInjector(details_elided);
|
||||
}
|
||||
// END FILE: node_modules/libB/module.ts
|
||||
// BEGIN FILE: node_modules/libB/module.metadata.json
|
||||
// Abridged version of metadata
|
||||
// Must still generate metadata in case it should be consumed with non-ivy application
|
||||
// Must mark the metadata with `hasNgDef: true` so that Ivy knows to ignore it.
|
||||
const node_modules_libB_module_metadata = {
|
||||
'LibBModule': {refs: ['LibBComponent'], constructorDes: [], hasNgDef: true},
|
||||
'LibBComponent': {constructorDes: [], hasNgDef: true}
|
||||
};
|
||||
// END FILE: node_modules/libA/module.metadata.json
|
||||
|
||||
|
||||
|
||||
///////////
|
||||
// Lib B - Compiled with Ivy
|
||||
// "enableIvy": true
|
||||
// "enableIvyBackPatch": true
|
||||
//////////
|
||||
|
||||
|
||||
// BEGIN FILE: src/app.ts (Compiled with Ivy)
|
||||
@Component({})
|
||||
export class AppComponent {
|
||||
// COMPILER GENERATED
|
||||
static ngComponentDef: $ComponentDef$ = r3.defineComponent(details_elided);
|
||||
}
|
||||
|
||||
@NgModule({declarations: [LibAComponent], imports: []})
|
||||
export class AppModule {
|
||||
// COMPILER GENERATED
|
||||
static ngInjectorDef = pending_pull_22005.defineInjector(details_elided);
|
||||
}
|
||||
// END FILE: src/app.ts
|
||||
|
||||
// BEGIN FILE: src/main.ts
|
||||
// platformBrowserDynamic().bootstrapModule(AppModule);
|
||||
// CLI rewrites it later to:
|
||||
// platformBrowser().bootstrapModuleFactory(AppModuleFactory);
|
||||
// END FILE: src/main.ts
|
||||
|
||||
// BEGIN FILE: src/app.ngfactory.ts
|
||||
function ngBackPatch_node_modules_libB_module() {
|
||||
ngBackPatch_node_modules_libB_module_LibAComponent();
|
||||
ngBackPatch_node_modules_libB_module_LibAModule();
|
||||
}
|
||||
|
||||
function ngBackPatch_node_modules_libB_module_LibAComponent() {
|
||||
(LibAComponent as any).ngComponentDef = r3.defineComponent(details_elided);
|
||||
}
|
||||
|
||||
function ngBackPatch_node_modules_libB_module_LibAModule() {
|
||||
(LibAModule as any).ngInjectorDef = pending_pull_22005.defineInjector(details_elided);
|
||||
}
|
||||
|
||||
export const AppModuleFactory: NgModuleFactory<AppModule>&{patchedDeps: boolean} = {
|
||||
moduleType: AppModule,
|
||||
patchedDeps: false,
|
||||
create(parentInjector: Injector | null): NgModuleRef<AppModule>{
|
||||
this.patchedDeps && ngBackPatch_node_modules_libB_module() && (this.patchedDeps = true);
|
||||
return details_elided;}
|
||||
};
|
||||
// BEGIN FILE: src/app.ngfactory.ts
|
||||
|
||||
|
||||
// ISSUE: I don't think this works. The issue is that multiple modules get flattened into single
|
||||
// module and hence we can't patch transitively.
|
||||
// ISSUE: can non-ivy @NgModule import Ivy @NgModule? I assume no, since the flattening of modules
|
||||
// happens during compilation.
|
||||
|
||||
// BEGIN FILE: src/main.ts
|
||||
// platformBrowserDynamic().bootstrapModule(AppModule);
|
||||
// CLI rewrites it to:
|
||||
// platformBrowser().bootstrapModuleFactory(AppModuleFactory);
|
||||
// END FILE: src/main.ts
|
|
@ -0,0 +1,78 @@
|
|||
/**
|
||||
* @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
|
||||
*/
|
||||
|
||||
import {Component, ContentChild, Directive, Injectable, Input, NgModule, OnDestroy, Optional, Pipe, PipeTransform, QueryList, SimpleChanges, TemplateRef, Type, ViewChild, ViewContainerRef} from '../../../src/core';
|
||||
import * as r3 from '../../../src/render3/index';
|
||||
import {pending_pull_22005} from './small_app_spec';
|
||||
|
||||
/**
|
||||
* GOALS:
|
||||
* - Patch types in tree shakable way
|
||||
* - Generate these types for files which have `metadata.json` (since those are the files which
|
||||
* have not been compiled with Ivy)
|
||||
* - Have build optimizer hoist the patch functions into corresponding types to allow tree-shaking.
|
||||
*/
|
||||
|
||||
// File: node_modules/some_library/path/public.ts
|
||||
// Implies metadata: node_modules/some_library/path/public.metadata.json
|
||||
// Assume: node_modules/some_library/index.js re-exports ./path/public.ts#ThirdPartyClass
|
||||
@Injectable()
|
||||
class ThirdPartyClass {
|
||||
}
|
||||
|
||||
|
||||
@Injectable()
|
||||
class CompiledWithIvy {
|
||||
// NORMATIVE
|
||||
static ngInjectableDef = pending_pull_22005.defineInjectable(
|
||||
{factory: function CompileWithIvy_Factory() { return new CompiledWithIvy(); }});
|
||||
// /NORMATIVE
|
||||
}
|
||||
|
||||
// import { CompiledWithIvy } from 'some_library';
|
||||
@NgModule({providers: [ThirdPartyClass, CompiledWithIvy]})
|
||||
class CompiledWithIvyModule {
|
||||
// NORMATIVE
|
||||
static ngInjectorDef = pending_pull_22005.defineInjector({
|
||||
providers: [ThirdPartyClass, CompiledWithIvy],
|
||||
factory: function CompiledWithIvyModule_Factory() { return new CompiledWithIvyModule(); }
|
||||
});
|
||||
// /NORMATIVE
|
||||
}
|
||||
|
||||
/**
|
||||
* Below is a function which should be generated right next to the `@NgModule` which
|
||||
* imports types which have `.metadata.json` files.
|
||||
*
|
||||
* # JIT Mode
|
||||
* - Because the `ngPatch_CompiledWithIvyModule` is invoked all parts get patched.
|
||||
*
|
||||
* # AOT Mode
|
||||
* - Build Optimizer detects `@__BUILD_OPTIMIZER_COLOCATE__` annotation and moves the
|
||||
* code from the current location to the destination.
|
||||
* - The resulting `ngPatch_CompiledWithIvyModule` becomes empty and eligible for tree-shaking.
|
||||
* - Uglify removes the `ngPatch_CompiledWithIvyModule` since it is empty.
|
||||
*
|
||||
* # AOT Closure Mode
|
||||
* - Option A: not supported. (Preferred option)
|
||||
* - Externally very few people use closure they will just have to wait until all of their
|
||||
* libraries are Ivy.
|
||||
* - Internally (g3) we build from source hence everyone switches to Ivy at the same time.
|
||||
* - Option B: Write a closure pass similar to Build Optimizer which would move the code.
|
||||
*/
|
||||
// NORMATIVE
|
||||
ngPatch_depsOf_CompiledWithIvyModule();
|
||||
function ngPatch_depsOf_CompiledWithIvyModule() {
|
||||
ngPatch_node_modules_some_library_path_public_CompileWithIvy();
|
||||
}
|
||||
function ngPatch_node_modules_some_library_path_public_CompileWithIvy() {
|
||||
/** @__BUILD_OPTIMIZER_COLOCATE__ */
|
||||
(ThirdPartyClass as any).ngInjectableDef = pending_pull_22005.defineInjectable(
|
||||
{factory: function CompileWithIvy_Factory() { return new ThirdPartyClass(); }});
|
||||
}
|
||||
// /NORMATIVE
|
Loading…
Reference in New Issue