From 22758912a0b0ee1aec9a569700b0947c28c49c46 Mon Sep 17 00:00:00 2001 From: Kapunahele Wong Date: Mon, 11 Sep 2017 12:25:29 -0400 Subject: [PATCH] docs(aio): tech edits to upgrade-lazy (#18487) (#18487) PR Close #18487 PR Close #18487 --- aio/content/guide/upgrade-lite.md | 357 ------------------ aio/content/guide/upgrade-performance.md | 352 +++++++++++++++++ aio/content/navigation.json | 4 +- .../upgrade/src/static/downgrade_module.ts | 4 +- 4 files changed, 356 insertions(+), 361 deletions(-) delete mode 100644 aio/content/guide/upgrade-lite.md create mode 100644 aio/content/guide/upgrade-performance.md diff --git a/aio/content/guide/upgrade-lite.md b/aio/content/guide/upgrade-lite.md deleted file mode 100644 index 2ee360611e..0000000000 --- a/aio/content/guide/upgrade-lite.md +++ /dev/null @@ -1,357 +0,0 @@ -# Upgrading from AngularJS (in a more flexible way) - -
- - _Angular_ is the name for the Angular of today and tomorrow.
- _AngularJS_ is the name for all 1.x versions of Angular. - -
- -This guide describes some of the built-in tools for efficiently migrating AngularJS projects over -to the Angular platform, one piece at a time. It is very similar to the -[main upgrade guide](guide/upgrade) with the exception that this one uses the {@link downgradeModule -downgradeModule()} helper function instead of the {@link UpgradeModule UpgradeModule} class. This -affects how the application is bootstrapped and how change detection is propagated between the two -frameworks (more on that later). - - -## Preparation - -Before we start discussing how you can use `downgradeModule()` to create hybrid applications, there -are things that you can do to ease the upgrade process even before you begin upgrading. Although not -strictly necessary, preparation goes a long way! The steps are the same regardless how you upgrade, -so go ahead and read the [Preparation](guide/upgrade#preparation) section of the main upgrade guide. - - -## Upgrading with ngUpgrade - -With the ngUpgrade library in Angular you can upgrade an existing AngularJS application -incrementally, by building a hybrid application where you can run both frameworks side-by-side. In -these hybrid applications you can mix and match AngularJS and Angular components and services and -have them interoperate seamlessly. That means you don't have to do the upgrade work all at once, -since there is a natural coexistence between the two frameworks during the transition period. - - -### How ngUpgrade Works - -Regardless of whether you choose `downgradeModule()` or `UpgradeModule`, the basic principles of -upgrading, the mental model behind hybrid applications and how you use the {@link upgrade/static -upgrade/static} utilities remain the same. You can read about all that in the -[How ngUpgrade Works](guide/upgrade#how-ngupgrade-works) section of the main upgrade guide. - -
- - The [Change Detection](guide/upgrade#change-detection) sub-section only applies to applications - that use `UpgradeModule`. Change detection is handled differently with `downgradeModule()`.
- We still recommend reading the sub-section in order to better understand the differences and their - implications. - -
- - -#### Change Detection with `downgradeModule()` - -As mentioned before, one of the key differences between `downgradeModule()` and `UpgradeModule` has -to do with change detection and how it is propagated between the two frameworks. - -With `UpgradeModule`, the two change detection systems are tied together more tightly. Whenever -something happens in the AngularJS part of the application, change detection is automatically -triggered on the Angular part and vice versa. This is convenient as it ensures that no important -change is missed by either framework. Most of the time, though, these extra change detection runs -are unnecesary. - -`downgradeModule()`, on the other side, avoids explicitly triggering change detection, unless it -knows the other part of the application is interested in the changes. One way to know, for example, -is when a value is bound to the {@link Input input} of a downgraded component. If the component -defines an `Input`, chances are it needs to be change-detected when that value changes. Thus, -`downgradeComponent()` _will_ automatically trigger change detection on that component. - -In most cases, though, the changes made locally in a particular component are of no interest to the -rest of the application. For example, if the user clicks a button that submits a form the component -will usually handle the result of this action. That being said, there _are_ cases, where you want to -propagate changes to some other part of the application, that may be controlled by the other -framework. In such cases, you are responsible for notifying the interested parties, by manually -triggering change detection. - -If you want a particular piece of code to trigger change detection in the AngularJS part of the -application, you need to wrap it in -[scope.$apply(...)](https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$apply). Similarly, for -triggering change detection in Angular you would use {@link NgZone#run ngZone.run(...)}. - -In many cases, a few extra change detection runs may not matter much. On larger or -change-detection-heavy applications, though, they can have a noticeable impact. By giving you more -fine-grained control over the change detection propagation, `downgradeModule()` allows you to -achieve better performance for your hybrid applications. - - -### Using `downgradeModule()` - -Both AngularJS and Angular have their own concept of modules to help organize an application into -cohesive blocks of functionality. - -Their details are quite different in architecture and implementation. In AngularJS, you create a -module by specifying its name and dependencies with -[angular.module()](https://docs.angularjs.org/api/ng/function/angular.module). Then you can add -assets using its various methods. In Angular, you create a class adorned with an {@link NgModule -NgModule} decorator that describes assets in metadata. The differences blossom from there. - -In a hybrid application you run both frameworks at the same time. This means that you need at least -one module each from both AngularJS and Angular. - -For the most part, you specify the modules in the same way as you would for a regular application. -Then, you use the `upgrade/static` helpers to let the two frameworks know about assets they can use -from each other. This is known as "upgrading" and "downgrading" (more on how this is done later). - -
- - Definitions: - - - _Upgrading_: The act of making an AngularJS asset (e.g. component or service) available to the - Angular part of the application. - - _Downgrading_: The act of making an Angular asset (e.g. component or service) available to the - AngularJS part of the application. - -
- -An important part of inter-linking dependencies, is linking the two main modules together. This is -where `downgradeModule()` comes in. It is used to create an AngularJS module — one that you -can use as a dependency in your main AngularJS module — that will bootstrap your main Angular -module and kick off the Angular part of the hybrid application. In a sense, it takes an Angular -module and "downgrades" it to an AngularJS module. - -There are a few things to note, though: - -1. You don't pass the Angular module directly to `downgradeModule()`. All `downgradeModule()` needs - is a "recipe" (e.g. a factory function) for creating an instance for your module. - -2. The Angular module is not instantiated until it is actually needed. - -We will expand on these two points below. For now, let's see how we can use `downgradeModule()` to -link the two modules. - -```ts -// Import `downgradeModule()`. -import { downgradeModule } from '@angular/upgrade/static'; - -// Use it to "downgrade" the Angular module to an AngularJS module. -const downgradedModule = downgradeModule(MainAngularModuleFactory); - -// Use the downgraded module as a dependency to the main AngularJS module. -angular.module('mainAngularJsModule', [ - downgradedModule -]); -``` - - -#### Specifying a factory for the Angular module - -As mentioned before, `downgradeModule()` needs to know how to instantiate the Angular module. It -needs a "recipe". You define that recipe, by providing a factory function that can create an -instance of the Angular module. `downgradeModule()` accepts two types of factory functions: - -1. {@link NgModuleFactory NgModuleFactory} -2. (extraProviders: {@link StaticProvider StaticProvider}[]) => Promise<{@link NgModuleRef NgModuleRef}> - -If you pass an `NgModuleFactory`, it will be used to instantiate the module using -{@link platformBrowser platformBrowser}'s {@link PlatformRef#bootstrapModuleFactory -bootstrapModuleFactory()}. This is great, because it is compatible with Ahead-of-Time (AoT) -compilation. You can read more about AoT compilation and how to create an `NgModuleFactory` in the -[AoT Compilation](guide/aot-compiler) guide. - -Alternatively, you can pass a plain function, which is expected to return a promise resolving to an -{@link NgModuleRef NgModuleRef} (i.e. an instance of your Angular module). The function is called -with an array of extra {@link StaticProvider Providers} that are expected to be available on the returned -`NgModuleRef`'s {@link Injector Injector}. For example, if you are using {@link platformBrowser -platformBrowser} or {@link platformBrowserDynamic platformBrowserDynamic}, you can pass the -`extraProviders` array to them: - -```ts -const bootstrapFn = (extraProviders: StaticProvider[]) => { - const platformRef = platformBrowserDynamic(extraProviders); - return platformRef.bootstrapModule(MainAngularModule); -}; -// or -const bootstrapFn = (extraProviders: StaticProvider[]) => { - const platformRef = platformBrowser(extraProviders); - return platformRef.bootstrapModuleFactory(MainAngularModuleFactory); -}; -``` - -Using an `NgModuleFactory` requires less boilerplate and is a good default option as it supports -AoT out-of-the-box. Using a custom function requires slightly more code, but gives you greater -flexibility. - - -#### Instantiating the Angular module "on-demand" - -Another key difference between `downgradeModule()` and `UpgradeModule` is that the latter requires -you to instantiate both the AngularJS and Angular modules up-front. This means that you have to pay -the cost of instantiating the Angular part of the application, even if you don't use any Angular -assets until later. `downgradeModule()` is again less aggressive: It will only instantiate the -Angular part when it is required for the first time; i.e. as soon as a downgraded component needs to -be created. - -You could go a step further and not even download the code for the Angular part of the application -to the user's browser, until it is needed. This is especially useful, when you use Angular on parts -of the hybrid application that are not necessary for the initial rendering or are not often reached -by the user (or not reached by all types of users). - -A few examples: - -- You use Angular on specific routes only and you don't need it until/if such a route is visited by - the user. -- You use Angular for features that are only visible to specific types of users (e.g. logged-in - users or administrators or VIP members). You don't need to load Angular until a user is - authenticated. -- You use Angular for a feature that is not critical for the initial rendering of the application - and you can afford a small delay in favor of better initial load performance. - - -### Bootstrapping with `downgradeModule()` - -As you may have guessed, you don't need to change anything in the way you bootstrap your existing -AngularJS application. Unlike `UpgradeModule` — which requires some extra steps — -`downgradeModule()` is able to take care of bootstrapping the Angular module (as long as you provide -the recipe). - -In order to start using any `upgrade/static` APIs, you still need to load the Angular framework (as -you would in a normal Angular application). You can see how this can be done with SystemJS by -following the instructions in the [Setup](guide/setup) guide, selectively copying code from the -[QuickStart github repository](https://github.com/angular/quickstart). - -You also need to install the `@angular/upgrade` package via `npm install @angular/upgrade --save` -and add a mapping for the `@angular/upgrade/static` package: - - -'@angular/upgrade/static': 'npm:@angular/upgrade/bundles/upgrade-static.umd.js', - - -Next, create an `app.module.ts` file and add the following `NgModule` class: - - -import { NgModule } from '@angular/core'; -import { BrowserModule } from '@angular/platform-browser'; - -@NgModule({ - imports: [ - BrowserModule - ] -}) -export class MainAngularModule { - // Empty placeholder method to prevent the `Compiler` from complaining. - ngDoBootstrap() {} -} - - -This bare minimum `NgModule` imports `BrowserModule`, the module every Angular browser-based app -must have. It also defines an empty `ngDoBootstrap()` method, to prevent the {@link Compiler -Compiler} from complaining. This is necessary, because the module will not have a `bootstrap` -declaration on its `NgModule` decorator. - -
- - You do not add a `bootstrap` declaration to the `NgModule` decorator, since AngularJS will own the - root template of the application and ngUpgrade will be bootstrapping the necessary components. - -
- -You can now link the AngularJS and Angular modules together using `downgradeModule()`. - - -import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; -import { downgradeModule } from '@angular/upgrade/static'; - -const bootstrapFn = (extraProviders: StaticProvider[]) => { - const platformRef = platformBrowserDynamic(extraProviders); - return platformRef.bootstrapModule(MainAngularModule); -}; -const downgradedModule = downgradeModule(bootstrapFn); - -angular.module('mainAngularJsModule', [ - downgradedModule -]); - - -Congratulations! You are running a hybrid application! The existing AngularJS code works as before -_and_ you are ready to start adding Angular code. - - -### Using Components and Injectables - -The differences between `downgradeModule()` and `UpgradeModule` end here. The rest of the -`upgrade/static` APIs and concepts work in the exact same way for both types of hybrid applications. -Head over to the [main upgrade guide](guide/upgrade) to learn about: - -- [Using Angular Components from AngularJS Code](guide/upgrade#using-angular-components-from-angularjs-code) -- [Using AngularJS Component Directives from Angular Code](guide/upgrade#using-angularjs-component-directives-from-angular-code) -- [Projecting AngularJS Content into Angular Components](guide/upgrade#projecting-angularjs-content-into-angular-components) -- [Transcluding Angular Content into AngularJS Component Directives](guide/upgrade#transcluding-angular-content-into-angularjs-component-directives) -- [Making AngularJS Dependencies Injectable to Angular](guide/upgrade#making-angularjs-dependencies-injectable-to-angular) -- [Making Angular Dependencies Injectable to AngularJS](guide/upgrade#making-angular-dependencies-injectable-to-angularjs) - -
- - While it is possible to downgrade injectables, the downgraded injectables will _not_ be available - until the Angular module is instantiated too. In order to be safe, you need to ensure that the - downgraded injectables are not used anywhere _outside_ the part of the application that is - controlled by Angular. - - For example, it is _OK_ to use a downgraded service in an upgraded component that is only used - from Angular components, but it is _not OK_ to use it in an AngularJS component that may be used - independently of Angular. - -
- - -## Using Ahead-of-Time compilation with hybrid applications - -You can take advantage of Ahead-of-Time (AoT) compilation on hybrid applications just like on any -other Angular application. The setup for a hybrid application is mostly the same as described in the -[AoT Compilation](guide/aot-compiler) guide save for differences in `index.html` and `main-aot.ts`. - -The `index.html` will likely have script tags loading AngularJS files, so the `index.html` for AoT -must also load those files. An easy way to copy them is by adding each to the `copy-dist-files.js` -file. - -You will also need to pass the generated `MainAngularModuleFactory` to `downgradeModule()`, instead of -the custom bootstrap function: - - -import { downgradeModule } from '@angular/upgrade/static'; -import { MainAngularModuleNgFactory } from '../aot/app/app.module.ngfactory'; - -const downgradedModule = downgradeModule(MainAngularModuleNgFactory); - -angular.module('mainAngularJsModule', [ - downgradedModule -]); - - -And that is all you need to do to get the full benefit of AoT for Angular applications! - - -## Wrap up - -You have learned how to use the {@link upgrade/static upgrade/static} package to incrementally -upgrade existing AngularJS applications at your own pace and without impeding further development of -the application for the duration of the upgrade process. - -More specifically, you have seen how you can achieve better performance and greater flexibility in -your hybrid applications, by using {@link downgradeModule downgradeModule()} (instead of -{@link UpgradeModule UpgradeModule}). - -To summarize, the key differentiating factors of `downgradeModule()` are: - -1. It allows instantiating (or even loading) the Angular part lazily, which improves the initial - loading time (and is some cases may waive the cost of running a second framework altogether). -2. It improves performance by avoiding unnecessary change detection runs, instead putting more - responsibility on the developer. -3. It does not require you to change how you bootstrap your AngularJS app. - -Based on that, `downgradeModule()` is a good option for hybrid applications that want keep the -AngularJS and Angular parts less coupled. You can still mix and match components and services from -both frameworks, but you might need to manually propagate change detection. In return, -`downgradeModule()` offers more control and better performance characteristics. - -There is merit in both approaches, so you should always weight the pros and cons before deciding -which one better meets the upgrading needs of each project. diff --git a/aio/content/guide/upgrade-performance.md b/aio/content/guide/upgrade-performance.md new file mode 100644 index 0000000000..ddb11e9d20 --- /dev/null +++ b/aio/content/guide/upgrade-performance.md @@ -0,0 +1,352 @@ +# Upgrading for Performance + +
+ + _Angular_ is the name for the Angular of today and tomorrow.
+ _AngularJS_ is the name for all 1.x versions of Angular. + +
+ +This guide describes some of the built-in tools for efficiently migrating AngularJS projects over to +the Angular platform, one piece at a time. It is very similar to +[Upgrading from AngularJS](guide/upgrade) with the exception that this one uses the {@link +downgradeModule downgradeModule()} helper function instead of the {@link UpgradeModule +UpgradeModule} class. This affects how the app is bootstrapped and how change detection is +propagated between the two frameworks. It allows you to upgrade incrementally while improving the +speed of your hybrid apps and leveraging the latest of Angular in AngularJS apps early in the +process of upgrading. + + + +## Preparation + +Before discussing how you can use `downgradeModule()` to create hybrid apps, there are things that +you can do to ease the upgrade process even before you begin upgrading. Because the steps are the +same regardless of how you upgrade, refer to the [Preparation](guide/upgrade#preparation) section of +[Upgrading from AngularJS](guide/upgrade). + + +## Upgrading with `ngUpgrade` + +With the `ngUpgrade` library in Angular you can upgrade an existing AngularJS app incrementally by +building a hybrid app where you can run both frameworks side-by-side. In these hybrid apps you can +mix and match AngularJS and Angular components and services and have them interoperate seamlessly. +That means you don't have to do the upgrade work all at once as there is a natural coexistence +between the two frameworks during the transition period. + + +### How `ngUpgrade` Works + +Regardless of whether you choose `downgradeModule()` or `UpgradeModule`, the basic principles of +upgrading, the mental model behind hybrid apps, and how you use the {@link upgrade/static +upgrade/static} utilities remain the same. For more information, see the +[How `ngUpgrade` Works](guide/upgrade#how-ngupgrade-works) section of +[Upgrading from AngularJS](guide/upgrade). + +
+ + The [Change Detection](guide/upgrade#change-detection) section of + [Upgrading from AngularJS](guide/upgrade) only applies to apps that use `UpgradeModule`. Though + you handle change detection differently with `downgradeModule()`, which is the focus of this + guide, reading the [Change Detection](guide/upgrade#change-detection) section provides helpful + context for what follows. + +
+ + +#### Change Detection with `downgradeModule()` + +As mentioned before, one of the key differences between `downgradeModule()` and `UpgradeModule` has +to do with change detection and how it is propagated between the two frameworks. + +With `UpgradeModule`, the two change detection systems are tied together more tightly. Whenever +something happens in the AngularJS part of the app, change detection is automatically triggered on +the Angular part and vice versa. This is convenient as it ensures that neither framework misses an +important change. Most of the time, though, these extra change detection runs are unnecessary. + +`downgradeModule()`, on the other side, avoids explicitly triggering change detection unless it +knows the other part of the app is interested in the changes. For example, if a downgraded component +defines an `@Input()`, chances are that the app needs to be aware when that value changes. Thus, +`downgradeComponent()` automatically triggers change detection on that component. + +In most cases, though, the changes made locally in a particular component are of no interest to the +rest of the app. For example, if the user clicks a button that submits a form, the component usually +handles the result of this action. That being said, there _are_ cases where you want to propagate +changes to some other part of the app that may be controlled by the other framework. In such cases, +you are responsible for notifying the interested parties by manually triggering change detection. + +If you want a particular piece of code to trigger change detection in the AngularJS part of the app, +you need to wrap it in +[scope.$apply()](https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$apply). Similarly, for +triggering change detection in Angular you would use {@link NgZone#run ngZone.run()}. + +In many cases, a few extra change detection runs may not matter much. However, on larger or +change-detection-heavy apps they can have a noticeable impact. By giving you more fine-grained +control over the change detection propagation, `downgradeModule()` allows you to achieve better +performance for your hybrid apps. + + +## Using `downgradeModule()` + +Both AngularJS and Angular have their own concept of modules to help organize an app into cohesive +blocks of functionality. + +Their details are quite different in architecture and implementation. In AngularJS, you create a +module by specifying its name and dependencies with +[angular.module()](https://docs.angularjs.org/api/ng/function/angular.module). Then you can add +assets using its various methods. In Angular, you create a class adorned with an {@link NgModule +NgModule} decorator that describes assets in metadata. + +In a hybrid app you run both frameworks at the same time. This means that you need at least one +module each from both AngularJS and Angular. + +For the most part, you specify the modules in the same way you would for a regular app. Then, you +use the `upgrade/static` helpers to let the two frameworks know about assets they can use from each +other. This is known as "upgrading" and "downgrading". + +
+ + Definitions: + + - _Upgrading_: The act of making an AngularJS asset, such as a component or service, available to + the Angular part of the app. + - _Downgrading_: The act of making an Angular asset, such as a component or service, available to + the AngularJS part of the app. + +
+ +An important part of inter-linking dependencies is linking the two main modules together. This is +where `downgradeModule()` comes in. Use it to create an AngularJS module—one that you can use +as a dependency in your main AngularJS module—that will bootstrap your main Angular module and +kick off the Angular part of the hybrid app. In a sense, it "downgrades" an Angular module to an +AngularJS module. + +There are a few things to note, though: + +1. You don't pass the Angular module directly to `downgradeModule()`. All `downgradeModule()` needs + is a "recipe", for example, a factory function, to create an instance for your module. + +2. The Angular module is not instantiated until the app actually needs it. + +The following is an example of how you can use `downgradeModule()` to link the two modules. + +```ts +// Import `downgradeModule()`. +import { downgradeModule } from '@angular/upgrade/static'; + +// Use it to downgrade the Angular module to an AngularJS module. +const downgradedModule = downgradeModule(MainAngularModuleFactory); + +// Use the downgraded module as a dependency to the main AngularJS module. +angular.module('mainAngularJsModule', [ + downgradedModule +]); +``` + + +#### Specifying a factory for the Angular module + +As mentioned earlier, `downgradeModule()` needs to know how to instantiate the Angular module. It +needs a recipe. You define that recipe by providing a factory function that can create an instance +of the Angular module. `downgradeModule()` accepts two types of factory functions: + +1. `NgModuleFactory` +2. `(extraProviders: StaticProvider[]) => Promise` + +When you pass an `NgModuleFactory`, `downgradeModule()` uses it to instantiate the module using +{@link platformBrowser platformBrowser}'s {@link PlatformRef#bootstrapModuleFactory +bootstrapModuleFactory()}, which is compatible with ahead-of-time (AOT) compilation. AOT compilation +helps make your apps load faster. For more about AOT and how to create an `NgModuleFactory`, see the +[Ahead-of-Time Compilation](guide/aot-compiler) guide. + +Alternatively, you can pass a plain function, which is expected to return a promise resolving to an +{@link NgModuleRef NgModuleRef} (i.e. an instance of your Angular module). The function is called +with an array of extra {@link StaticProvider Providers} that are expected to be available on the +returned `NgModuleRef`'s {@link Injector Injector}. For example, if you are using {@link +platformBrowser platformBrowser} or {@link platformBrowserDynamic platformBrowserDynamic}, you can +pass the `extraProviders` array to them: + +```ts +const bootstrapFn = (extraProviders: StaticProvider[]) => { + const platformRef = platformBrowserDynamic(extraProviders); + return platformRef.bootstrapModule(MainAngularModule); +}; +// or +const bootstrapFn = (extraProviders: StaticProvider[]) => { + const platformRef = platformBrowser(extraProviders); + return platformRef.bootstrapModuleFactory(MainAngularModuleFactory); +}; +``` + +Using an `NgModuleFactory` requires less boilerplate and is a good default option as it supports AOT +out-of-the-box. Using a custom function requires slightly more code, but gives you greater +flexibility. + + +#### Instantiating the Angular module on-demand + +Another key difference between `downgradeModule()` and `UpgradeModule` is that the latter requires +you to instantiate both the AngularJS and Angular modules up-front. This means that you have to pay +the cost of instantiating the Angular part of the app, even if you don't use any Angular assets +until later. `downgradeModule()` is again less aggressive. It will only instantiate the Angular part +when it is required for the first time; that is, as soon as it needs to create a downgraded +component. + +You could go a step further and not even download the code for the Angular part of the app to the +user's browser until it is needed. This is especially useful when you use Angular on parts of the +hybrid app that are not necessary for the initial rendering or that the user doesn't reach. + + +A few examples are: + +- You use Angular on specific routes only and you don't need it until/if a user visits such a route. +- You use Angular for features that are only visible to specific types of users; for example, + logged-in users, administrators, or VIP members. You don't need to load Angular until a user is + authenticated. +- You use Angular for a feature that is not critical for the initial rendering of the app and you + can afford a small delay in favor of better initial load performance. + + +### Bootstrapping with `downgradeModule()` + +As you might have guessed, you don't need to change anything in the way you bootstrap your existing +AngularJS app. Unlike `UpgradeModule`—which requires some extra steps— +`downgradeModule()` is able to take care of bootstrapping the Angular module, as long as you provide +the recipe. + +In order to start using any `upgrade/static` APIs, you still need to load the Angular framework as +you would in a normal Angular app. You can see how this can be done with SystemJS by following the +instructions in the [Setup](guide/setup) guide, selectively copying code from the +[QuickStart github repository](https://github.com/angular/quickstart). + +You also need to install the `@angular/upgrade` package via `npm install @angular/upgrade --save` +and add a mapping for the `@angular/upgrade/static` package: + + +'@angular/upgrade/static': 'npm:@angular/upgrade/bundles/upgrade-static.umd.js', + + +Next, create an `app.module.ts` file and add the following `NgModule` class: + + +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; + +@NgModule({ + imports: [ + BrowserModule + ] +}) +export class MainAngularModule { + // Empty placeholder method to satisfy the `Compiler`. + ngDoBootstrap() {} +} + + +This bare minimum `NgModule` imports `BrowserModule`, the module every Angular browser-based app +must have. It also defines an empty `ngDoBootstrap()` method, to prevent the {@link Compiler +Compiler} from returning errors. This is necessary because the module will not have a `bootstrap` +declaration on its `NgModule` decorator. + +
+ + You do not add a `bootstrap` declaration to the `NgModule` decorator since AngularJS owns the root + template of the app and `ngUpgrade` bootstraps the necessary components. + +
+ +You can now link the AngularJS and Angular modules together using `downgradeModule()`. + + +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { downgradeModule } from '@angular/upgrade/static'; + +const bootstrapFn = (extraProviders: StaticProvider[]) => { + const platformRef = platformBrowserDynamic(extraProviders); + return platformRef.bootstrapModule(MainAngularModule); +}; +const downgradedModule = downgradeModule(bootstrapFn); + +angular.module('mainAngularJsModule', [ + downgradedModule +]); + + +The existing AngularJS code works as before _and_ you are ready to start adding Angular code. + + +### Using Components and Injectables + +The differences between `downgradeModule()` and `UpgradeModule` end here. The rest of the +`upgrade/static` APIs and concepts work in the exact same way for both types of hybrid apps. +See [Upgrading from AngularJS](guide/upgrade) to learn about: + +- [Using Angular Components from AngularJS Code](guide/upgrade#using-angular-components-from-angularjs-code). +- [Using AngularJS Component Directives from Angular Code](guide/upgrade#using-angularjs-component-directives-from-angular-code). +- [Projecting AngularJS Content into Angular Components](guide/upgrade#projecting-angularjs-content-into-angular-components). +- [Transcluding Angular Content into AngularJS Component Directives](guide/upgrade#transcluding-angular-content-into-angularjs-component-directives). +- [Making AngularJS Dependencies Injectable to Angular](guide/upgrade#making-angularjs-dependencies-injectable-to-angular). +- [Making Angular Dependencies Injectable to AngularJS](guide/upgrade#making-angular-dependencies-injectable-to-angularjs). + +
+ + While it is possible to downgrade injectables, downgraded injectables will not be available until + the Angular module is instantiated. In order to be safe, you need to ensure that the downgraded + injectables are not used anywhere _outside_ the part of the app that is controlled by Angular. + + For example, it is _OK_ to use a downgraded service in an upgraded component that is only used + from Angular components, but it is _not OK_ to use it in an AngularJS component that may be used + independently of Angular. + +
+ + +## Using ahead-of-time compilation with hybrid apps + +You can take advantage of ahead-of-time (AOT) compilation in hybrid apps just like in any other +Angular app. The setup for a hybrid app is mostly the same as described in the +[Ahead-of-Time Compilation](guide/aot-compiler) guide save for differences in `index.html` and +`main-aot.ts`. + +AOT needs to load any AngularJS files that are in the `