From 54245ca860202073a8eb355c7e43950d5237f06a Mon Sep 17 00:00:00 2001 From: Liam DeBeasi Date: Mon, 11 Sep 2023 15:21:47 -0400 Subject: [PATCH 01/18] add first pass of documentation --- docs/angular/build-options.md | 80 +++++++++++++++++++++++++++++++++++ sidebars.js | 1 + 2 files changed, 81 insertions(+) create mode 100644 docs/angular/build-options.md diff --git a/docs/angular/build-options.md b/docs/angular/build-options.md new file mode 100644 index 00000000000..8c70b62e6ab --- /dev/null +++ b/docs/angular/build-options.md @@ -0,0 +1,80 @@ +# Build Options + +Developers have two options for using Ionic components: Standalone or Modules. This guide covers both options as well as the benefits and downsides of each approach. Most of the Angular examples on this documentation website use the Modules approach for now. + +## Standalone + +### Overview + +Developers can use Ionic components as [Angular standalone components](https://angular.io/guide/standalone-components) which provides a simplified way to build Angular applications. This option involves importing specific Ionic components in the Angular components you want to use them in. + +In the example below, we are importing `IonContent` and `IonButton` from `@ionic/angular/standalone` and passed to `imports` for use in the component template. We would get a compiler error if these components were not imported and provided to the `imports` array. + +```typescript +import { Component } from '@angular/core'; +import { IonButton, IonContent } from '@ionic/angular/standalone'; + +@Component({ + selector: 'app-home', + templateUrl: 'home.page.html', + styleUrls: ['home.page.scss'], + standalone: true, + imports: [IonButton, IonContent], +}) +export class HomePage { + constructor() {} +} +``` + +### Benefits + +1. Enables treeshaking so the final build output only includes the code necessary to run your app which reduces overall build size. +2. Avoids the use of `NgModule`s to streamline the development experience and make your code easier to understand. +3. Allows developers to also use newer Angular features such as [ESBuild Support](https://angular.io/guide/esbuild). + +### Drawbacks + +1. Ionic components need to be imported into every Angular component they want to be used in which can be time consuming to set up. + +## Modules + +### Overview + +Developers can also use the Modules approach by importing `IonicModule` and calling `IonicModule.forRoot()` in the `imports` array in `app.module.ts`. This registers a version of Ionic where Ionic components will be lazily loaded as needed. + +In the example below, we are using `IonicModule` to create a lazily loaded version of Ionic. We can then reference any Ionic component without needing to explicitly import it. + +```typescript +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; + +import { IonicModule } from '@ionic/angular'; + +import { AppComponent } from './app.component'; + +@NgModule({ + declarations: [AppComponent], + imports: [BrowserModule, IonicModule.forRoot()], + bootstrap: [AppComponent], +}) +export class AppModule {} +``` + +### Benefits + +1. Since components are lazily loaded as needed, developers do not need to spend time manually importing and registering each Ionic component. + +### Drawbacks + +1. Lazily loading Ionic components means that the compiler does not know which components are needed at build time. This means your final application bundle may be much larger than it needs to be. +2. Developers are unable to use newer Angular features such as [ESBuild Support](https://angular.io/guide/esbuild). + +## Migrating from Modules to Standalone + +The Standalone option is newer than the Modules option, so developers may wish to switch during the development of their application. This guide details the steps needed to migrate as well as limitations to be aware of. + +### Steps to Migrate + +1. + +### Limitations diff --git a/sidebars.js b/sidebars.js index 76e4d28bc4c..3ecdcbaa36b 100644 --- a/sidebars.js +++ b/sidebars.js @@ -66,6 +66,7 @@ module.exports = { collapsed: false, items: [ 'angular/overview', + 'angular/build-options', { type: 'category', label: 'Build Your First App', From 6dfd58a5e5cd92e21fc4a804bc5e18cece217995 Mon Sep 17 00:00:00 2001 From: Liam DeBeasi Date: Mon, 11 Sep 2023 17:02:30 -0400 Subject: [PATCH 02/18] add migration guide --- docs/angular/build-options.md | 154 ++++++++++++++++++++++++++++++---- 1 file changed, 139 insertions(+), 15 deletions(-) diff --git a/docs/angular/build-options.md b/docs/angular/build-options.md index 8c70b62e6ab..ebc3f249c1a 100644 --- a/docs/angular/build-options.md +++ b/docs/angular/build-options.md @@ -2,12 +2,30 @@ Developers have two options for using Ionic components: Standalone or Modules. This guide covers both options as well as the benefits and downsides of each approach. Most of the Angular examples on this documentation website use the Modules approach for now. +While the Standalone approach is newer and makes use of more modern Angular APIs, the Modules approach will continue to be supported in Ionic. + ## Standalone ### Overview Developers can use Ionic components as [Angular standalone components](https://angular.io/guide/standalone-components) which provides a simplified way to build Angular applications. This option involves importing specific Ionic components in the Angular components you want to use them in. +**Benefits** + +1. Enables treeshaking so the final build output only includes the code necessary to run your app which reduces overall build size. +2. Avoids the use of `NgModule`s to streamline the development experience and make your code easier to understand. +3. Allows developers to also use newer Angular features such as [ESBuild Support](https://angular.io/guide/esbuild). + +**Drawbacks** + +1. Ionic components need to be imported into every Angular component they want to be used in which can be time consuming to set up. + +### Usage + +:::caution +All Ionic standalone imports should be imported from the `@ionic/angular/standalone` package. Importing from the `@ionic/angular` package may pull in lazy loaded Ionic code which can interfere with treeshaking. +::: + In the example below, we are importing `IonContent` and `IonButton` from `@ionic/angular/standalone` and passed to `imports` for use in the component template. We would get a compiler error if these components were not imported and provided to the `imports` array. ```typescript @@ -26,15 +44,30 @@ export class HomePage { } ``` -### Benefits +Ionic Angular needs to be configured when the Angular application calls `bootstrapApplication` using the `provideIonicAngular` function. Developers can pass any [IonicConfig](../developing/config#ionicconfig) values as an object in this function. Note that `provideIonicAngular` needs to be called even if no custom config is passed. -1. Enables treeshaking so the final build output only includes the code necessary to run your app which reduces overall build size. -2. Avoids the use of `NgModule`s to streamline the development experience and make your code easier to understand. -3. Allows developers to also use newer Angular features such as [ESBuild Support](https://angular.io/guide/esbuild). +```typescript +import { enableProdMode, importProvidersFrom } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { RouteReuseStrategy, provideRouter } from '@angular/router'; +import { provideIonicAngular, IonicRouteStrategy } from '@ionic/angular/standalone'; -### Drawbacks +import { routes } from './app/app.routes'; +import { AppComponent } from './app/app.component'; +import { environment } from './environments/environment'; -1. Ionic components need to be imported into every Angular component they want to be used in which can be time consuming to set up. +if (environment.production) { + enableProdMode(); +} + +bootstrapApplication(AppComponent, { + providers: [ + { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }, + provideIonicAngular({ mode: 'ios' }), + provideRouter(routes), + ], +}); +``` ## Modules @@ -42,6 +75,17 @@ export class HomePage { Developers can also use the Modules approach by importing `IonicModule` and calling `IonicModule.forRoot()` in the `imports` array in `app.module.ts`. This registers a version of Ionic where Ionic components will be lazily loaded as needed. +**Benefits** + +1. Since components are lazily loaded as needed, developers do not need to spend time manually importing and registering each Ionic component. + +**Drawbacks** + +1. Lazily loading Ionic components means that the compiler does not know which components are needed at build time. This means your final application bundle may be much larger than it needs to be. +2. Developers are unable to use newer Angular features such as [ESBuild Support](https://angular.io/guide/esbuild). + +### Usage + In the example below, we are using `IonicModule` to create a lazily loaded version of Ionic. We can then reference any Ionic component without needing to explicitly import it. ```typescript @@ -60,21 +104,101 @@ import { AppComponent } from './app.component'; export class AppModule {} ``` -### Benefits +## Migrating from Modules to Standalone -1. Since components are lazily loaded as needed, developers do not need to spend time manually importing and registering each Ionic component. +:::note +This migration guide assumes the Angular components in your application are already standalone components. +::: -### Drawbacks +The Standalone option is newer than the Modules option, so developers may wish to switch during the development of their application. This guide details the steps needed to migrate as well as limitations to be aware of. -1. Lazily loading Ionic components means that the compiler does not know which components are needed at build time. This means your final application bundle may be much larger than it needs to be. -2. Developers are unable to use newer Angular features such as [ESBuild Support](https://angular.io/guide/esbuild). +### Steps to Migrate -## Migrating from Modules to Standalone +1. Remove the `IonicModule` call in `main.ts` in favor of `provideIonicAngular` imported from `@ionic/angular/standalone`. Any config passed to `IonicModule.forRoot` can be passed as an object to this new function. -The Standalone option is newer than the Modules option, so developers may wish to switch during the development of their application. This guide details the steps needed to migrate as well as limitations to be aware of. +```diff +import { enableProdMode, importProvidersFrom } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { RouteReuseStrategy, provideRouter } from '@angular/router'; +- import { IonicModule, IonicRouteStrategy } from '@ionic/angular'; ++ import { provideIonicAngular, IonicRouteStrategy } from '@ionic/angular/standalone'; -### Steps to Migrate +import { routes } from './app/app.routes'; +import { AppComponent } from './app/app.component'; +import { environment } from './environments/environment'; + +if (environment.production) { + enableProdMode(); +} + +bootstrapApplication(AppComponent, { + providers: [ + { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }, +- importProvidersFrom(IonicModule.forRoot({ mode: 'md' })), ++ provideIonicAngular({ mode: 'md' }), + provideRouter(routes), + ], +}); +``` + +2. Remove any references to `IonicModule` found elsewhere in your application. + +3. Update any existing imports from `@ionic/angular` to import from `@ionic/angular/standalone` instead. -1. +```diff +- import { Platform } from '@ionic/angular'; ++ import { Platform } from '@ionic/angular/standalone'; +``` + +4. Add imports for each Ionic component in the Angular component where they are used. Be sure to pass the imports to the `imports` array on your Angular component. + + +```diff +import { Component } from '@angular/core'; ++ import { IonApp, IonRouterOutlet } from '@ionic/angular/standalone'; + +@Component({ + selector: 'app-root', + templateUrl: 'app.component.html', + styleUrls: ['app.component.scss'], + standalone: true, ++ imports: [IonApp, IonRouterOutlet], +}) +export class AppComponent { + constructor() {} +} +``` + +5. If you are using Ionicons, define the icon SVG data used in each Angular component using `addIcons`. This allows you to continue referencing icons by string name in your component template. Note that you will need to do this for any additional icons added. + +```diff +import { Component } from '@angular/core'; ++ import { IonIcon } from '@ionic/angular/standalone'; ++ import { addIcons } from 'ionicons'; ++ import { alarm, logoIonic } from 'ionicons/icons'; + +@Component({ + selector: 'app-root', + templateUrl: 'app.component.html', + styleUrls: ['app.component.scss'], + standalone: true, ++ imports: [IonIcon], +}) +export class TestComponent { + constructor() { + addIcons({ alarm, logoIonic }); + } +} +``` + +6. Remove the following code from your `angular.json` file is present. Note that it may appear multiple times in your `angular.json` file. + +```diff +- { +- "glob": "**/*.svg", +- "input": "node_modules/ionicons/dist/ionicons/svg", +- "output": "./svg" +- } +``` ### Limitations From 01d9b07085c21cb566f9c6a9f8bbdc38be627ecf Mon Sep 17 00:00:00 2001 From: Liam DeBeasi Date: Tue, 12 Sep 2023 10:35:17 -0400 Subject: [PATCH 03/18] add more docs --- docs/angular/build-options.md | 79 ++++++++++++++++++++++++++++------- 1 file changed, 65 insertions(+), 14 deletions(-) diff --git a/docs/angular/build-options.md b/docs/angular/build-options.md index ebc3f249c1a..44e031b1b38 100644 --- a/docs/angular/build-options.md +++ b/docs/angular/build-options.md @@ -1,24 +1,30 @@ # Build Options -Developers have two options for using Ionic components: Standalone or Modules. This guide covers both options as well as the benefits and downsides of each approach. Most of the Angular examples on this documentation website use the Modules approach for now. +Developers have two options for using Ionic components: Standalone or Modules. This guide covers both options as well as the benefits and downsides of each approach. -While the Standalone approach is newer and makes use of more modern Angular APIs, the Modules approach will continue to be supported in Ionic. +While the Standalone approach is newer and makes use of more modern Angular APIs, the Modules approach will continue to be supported in Ionic. Most of the Angular examples on this documentation website use the Modules approach. ## Standalone +:::info +Ionic UI components as Angular standalone components is supported starting in Ionic v7.5. + +Additionally, using Ionic components as standalone components is supported in Angular applications that already make use of the standalone component APIs. See [Standalone Migration](https://angular.io/guide/standalone-migration) for more information. +::: + ### Overview -Developers can use Ionic components as [Angular standalone components](https://angular.io/guide/standalone-components) which provides a simplified way to build Angular applications. This option involves importing specific Ionic components in the Angular components you want to use them in. +Developers with Angular applications that use [standalone components](https://angular.io/guide/standalone-components) can use Ionic components as standalone components which provides a simplified way to build Angular applications. This option involves importing specific Ionic components in the Angular components you want to use them in. **Benefits** 1. Enables treeshaking so the final build output only includes the code necessary to run your app which reduces overall build size. 2. Avoids the use of `NgModule`s to streamline the development experience and make your code easier to understand. -3. Allows developers to also use newer Angular features such as [ESBuild Support](https://angular.io/guide/esbuild). +3. Allows developers to also use newer Angular features such as [ESBuild](https://angular.io/guide/esbuild). **Drawbacks** -1. Ionic components need to be imported into every Angular component they want to be used in which can be time consuming to set up. +1. Ionic components need to be imported into every Angular component they are used in which can be time consuming to set up. ### Usage @@ -26,7 +32,9 @@ Developers can use Ionic components as [Angular standalone components](https://a All Ionic standalone imports should be imported from the `@ionic/angular/standalone` package. Importing from the `@ionic/angular` package may pull in lazy loaded Ionic code which can interfere with treeshaking. ::: -In the example below, we are importing `IonContent` and `IonButton` from `@ionic/angular/standalone` and passed to `imports` for use in the component template. We would get a compiler error if these components were not imported and provided to the `imports` array. +**Components** + +In the example below, we are importing `IonContent` and `IonButton` from `@ionic/angular/standalone` and passing them to `imports` for use in the component template. We would get a compiler error if these components were not imported and provided to the `imports` array. ```typescript import { Component } from '@angular/core'; @@ -44,6 +52,8 @@ export class HomePage { } ``` +**Bootstrapping and Configuration** + Ionic Angular needs to be configured when the Angular application calls `bootstrapApplication` using the `provideIonicAngular` function. Developers can pass any [IonicConfig](../developing/config#ionicconfig) values as an object in this function. Note that `provideIonicAngular` needs to be called even if no custom config is passed. ```typescript @@ -69,6 +79,40 @@ bootstrapApplication(AppComponent, { }); ``` +**Icons** + +The icon SVG data needs to be defined in the Angular component so it can be loaded correctly. Developers can use the `addIcons` function from `ionicons` to map the SVG data to a string name. Developers can then reference the icon by its string name using the `name` property on `IonIcon`. + +We recommend calling `addIcons` in the Angular component `constructor` so the data is only added if the Angular component is being used. + +For developers using Ionicons 7.2 or newer, passing only the SVG data will cause the string name to be automatically generated. + +```typescript +import { Component } from '@angular/core'; +import { IonIcon } from '@ionic/angular/standalone'; +import { addIcons } from 'ionicons'; +import { logoIonic } from 'ionicons/icons'; + +@Component({ + selector: 'app-home', + templateUrl: 'home.page.html', + styleUrls: ['home.page.scss'], + standalone: true, + imports: [IonIcon], +}) +export class HomePage { + constructor() { + /** + * On Ionicons 7.2+ this icon + * gets mapped to a "logo-ionic" key. + * Alternatively, developers can do: + * addIcons({ 'logo-ionic': logoIonic }); + */ + addIcons({ logoIonic }); + } +} +``` + ## Modules ### Overview @@ -82,7 +126,7 @@ Developers can also use the Modules approach by importing `IonicModule` and call **Drawbacks** 1. Lazily loading Ionic components means that the compiler does not know which components are needed at build time. This means your final application bundle may be much larger than it needs to be. -2. Developers are unable to use newer Angular features such as [ESBuild Support](https://angular.io/guide/esbuild). +2. Developers are unable to use newer Angular features such as [ESBuild](https://angular.io/guide/esbuild). ### Usage @@ -107,14 +151,18 @@ export class AppModule {} ## Migrating from Modules to Standalone :::note -This migration guide assumes the Angular components in your application are already standalone components. +This migration guide assumes the Angular components in your application are already standalone components. See [Migrating to Standalone](https://angular.io/guide/standalone-migration) if you are Angular application is not already using standalone components. ::: The Standalone option is newer than the Modules option, so developers may wish to switch during the development of their application. This guide details the steps needed to migrate as well as limitations to be aware of. ### Steps to Migrate -1. Remove the `IonicModule` call in `main.ts` in favor of `provideIonicAngular` imported from `@ionic/angular/standalone`. Any config passed to `IonicModule.forRoot` can be passed as an object to this new function. +1. Run `npm install @ionic/angular@latest` to ensure you are running the latest version of Ionic. Ionic UI Standalone Components is supported in Ionic v7.5 or newer. + +2. Run `npm install ionicons@latest` to ensure you are running the latest version of Ionicons. Ionicons v7.2 brings usability improvements that reduce the code boilerplate needed to use icons with standalone components. + +3. Remove the `IonicModule` call in `main.ts` in favor of `provideIonicAngular` imported from `@ionic/angular/standalone`. Any config passed to `IonicModule.forRoot` can be passed as an object to this new function. ```diff import { enableProdMode, importProvidersFrom } from '@angular/core'; @@ -141,16 +189,16 @@ bootstrapApplication(AppComponent, { }); ``` -2. Remove any references to `IonicModule` found elsewhere in your application. +4. Remove any references to `IonicModule` found elsewhere in your application. -3. Update any existing imports from `@ionic/angular` to import from `@ionic/angular/standalone` instead. +5. Update any existing imports from `@ionic/angular` to import from `@ionic/angular/standalone` instead. ```diff - import { Platform } from '@ionic/angular'; + import { Platform } from '@ionic/angular/standalone'; ``` -4. Add imports for each Ionic component in the Angular component where they are used. Be sure to pass the imports to the `imports` array on your Angular component. +6. Add imports for each Ionic component in the Angular component where they are used. Be sure to pass the imports to the `imports` array on your Angular component. ```diff @@ -169,7 +217,7 @@ export class AppComponent { } ``` -5. If you are using Ionicons, define the icon SVG data used in each Angular component using `addIcons`. This allows you to continue referencing icons by string name in your component template. Note that you will need to do this for any additional icons added. +7. If you are using Ionicons, define the icon SVG data used in each Angular component using `addIcons`. This allows you to continue referencing icons by string name in your component template. Note that you will need to do this for any additional icons added. ```diff import { Component } from '@angular/core'; @@ -191,7 +239,7 @@ export class TestComponent { } ``` -6. Remove the following code from your `angular.json` file is present. Note that it may appear multiple times in your `angular.json` file. +8. Remove the following code from your `angular.json` file is present. Note that it may appear multiple times in your `angular.json` file. ```diff - { @@ -202,3 +250,6 @@ export class TestComponent { ``` ### Limitations + +1. Your application must already make use of standalone APIs. Using Ionic UI components as standalone components in an application that uses `NgModule` is not supported. +2. Migrating to Ionic standalone components must be done all at the same time and cannot be done gradually. The Modules and Standalone approaches use two different build systems of Ionic that cannot be used at the same time. From c6fff5d607ffd0c5289c957e23aedbcc13d04780 Mon Sep 17 00:00:00 2001 From: Liam DeBeasi Date: Tue, 12 Sep 2023 10:41:08 -0400 Subject: [PATCH 04/18] fix typo --- docs/angular/build-options.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/angular/build-options.md b/docs/angular/build-options.md index 44e031b1b38..4c44cadfd15 100644 --- a/docs/angular/build-options.md +++ b/docs/angular/build-options.md @@ -239,7 +239,7 @@ export class TestComponent { } ``` -8. Remove the following code from your `angular.json` file is present. Note that it may appear multiple times in your `angular.json` file. +8. Remove the following code from your `angular.json` file if present. Note that it may appear multiple times in your `angular.json` file. ```diff - { From ce25c970db567c9334b0c14e5baa108f7cad9d3d Mon Sep 17 00:00:00 2001 From: Liam DeBeasi Date: Tue, 12 Sep 2023 12:18:39 -0400 Subject: [PATCH 05/18] lint --- docs/angular/build-options.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/angular/build-options.md b/docs/angular/build-options.md index 4c44cadfd15..5635a5cf808 100644 --- a/docs/angular/build-options.md +++ b/docs/angular/build-options.md @@ -160,7 +160,7 @@ The Standalone option is newer than the Modules option, so developers may wish t 1. Run `npm install @ionic/angular@latest` to ensure you are running the latest version of Ionic. Ionic UI Standalone Components is supported in Ionic v7.5 or newer. -2. Run `npm install ionicons@latest` to ensure you are running the latest version of Ionicons. Ionicons v7.2 brings usability improvements that reduce the code boilerplate needed to use icons with standalone components. +2. Run `npm install ionicons@latest` to ensure you are running the latest version of Ionicons. Ionicons v7.2 brings usability improvements that reduce the code boilerplate needed to use icons with standalone components. 3. Remove the `IonicModule` call in `main.ts` in favor of `provideIonicAngular` imported from `@ionic/angular/standalone`. Any config passed to `IonicModule.forRoot` can be passed as an object to this new function. @@ -200,7 +200,6 @@ bootstrapApplication(AppComponent, { 6. Add imports for each Ionic component in the Angular component where they are used. Be sure to pass the imports to the `imports` array on your Angular component. - ```diff import { Component } from '@angular/core'; + import { IonApp, IonRouterOutlet } from '@ionic/angular/standalone'; From def6799feabd7c7e6aefeff0bd9fd66f611c93d5 Mon Sep 17 00:00:00 2001 From: Liam DeBeasi Date: Tue, 12 Sep 2023 12:37:14 -0400 Subject: [PATCH 06/18] fix typos --- docs/angular/build-options.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/docs/angular/build-options.md b/docs/angular/build-options.md index 5635a5cf808..54534b46e5f 100644 --- a/docs/angular/build-options.md +++ b/docs/angular/build-options.md @@ -8,13 +8,11 @@ While the Standalone approach is newer and makes use of more modern Angular APIs :::info Ionic UI components as Angular standalone components is supported starting in Ionic v7.5. - -Additionally, using Ionic components as standalone components is supported in Angular applications that already make use of the standalone component APIs. See [Standalone Migration](https://angular.io/guide/standalone-migration) for more information. ::: ### Overview -Developers with Angular applications that use [standalone components](https://angular.io/guide/standalone-components) can use Ionic components as standalone components which provides a simplified way to build Angular applications. This option involves importing specific Ionic components in the Angular components you want to use them in. +Developers with Angular applications that use [standalone components](https://angular.io/guide/standalone-components) can also use Ionic components as standalone components to provide a simplified way to build Angular applications. This option involves importing specific Ionic components in the Angular components you want to use them in. **Benefits** @@ -29,7 +27,7 @@ Developers with Angular applications that use [standalone components](https://an ### Usage :::caution -All Ionic standalone imports should be imported from the `@ionic/angular/standalone` package. Importing from the `@ionic/angular` package may pull in lazy loaded Ionic code which can interfere with treeshaking. +All Ionic imports should be imported from the `@ionic/angular/standalone` submodule. This includes imports such as components, directives, providers, and types. Importing from `@ionic/angular` may pull in lazy loaded Ionic code which can interfere with treeshaking. ::: **Components** @@ -151,7 +149,7 @@ export class AppModule {} ## Migrating from Modules to Standalone :::note -This migration guide assumes the Angular components in your application are already standalone components. See [Migrating to Standalone](https://angular.io/guide/standalone-migration) if you are Angular application is not already using standalone components. +This migration guide assumes the Angular components in your application are already standalone components. See [Migrating to Standalone](https://angular.io/guide/standalone-migration) if your Angular application is not already using standalone components. ::: The Standalone option is newer than the Modules option, so developers may wish to switch during the development of their application. This guide details the steps needed to migrate as well as limitations to be aware of. @@ -238,7 +236,7 @@ export class TestComponent { } ``` -8. Remove the following code from your `angular.json` file if present. Note that it may appear multiple times in your `angular.json` file. +8. Remove the following code from your `angular.json` file if present. Note that it may appear multiple times. ```diff - { From cb052c1fd7ac48e4963fa4f0435867eb8682aadf Mon Sep 17 00:00:00 2001 From: Liam DeBeasi Date: Wed, 13 Sep 2023 10:31:58 -0400 Subject: [PATCH 07/18] call out migration guide higher up in doc --- docs/angular/build-options.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/angular/build-options.md b/docs/angular/build-options.md index 54534b46e5f..daec4d11108 100644 --- a/docs/angular/build-options.md +++ b/docs/angular/build-options.md @@ -14,6 +14,8 @@ Ionic UI components as Angular standalone components is supported starting in Io Developers with Angular applications that use [standalone components](https://angular.io/guide/standalone-components) can also use Ionic components as standalone components to provide a simplified way to build Angular applications. This option involves importing specific Ionic components in the Angular components you want to use them in. +See the [Standalone Migration Guide](#migrating-from-modules-to-standalone) for instructions on how to update your Ionic app to make use of Ionic standalone components. + **Benefits** 1. Enables treeshaking so the final build output only includes the code necessary to run your app which reduces overall build size. From 640789b333e62e40fd07c690be8e1fc1200131c4 Mon Sep 17 00:00:00 2001 From: Liam DeBeasi Date: Wed, 13 Sep 2023 10:35:09 -0400 Subject: [PATCH 08/18] add note to resources on modules vs standalone --- docs/angular/overview.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/angular/overview.md b/docs/angular/overview.md index 10bae7ff7b0..4b1182bb76a 100644 --- a/docs/angular/overview.md +++ b/docs/angular/overview.md @@ -39,4 +39,8 @@ With Ionic 4+, the official Angular stack for building an app and routing are us

Learn about using Ionic lifecycle events in class components and with hooks

+ +

Learn about using Modules or Standalone Components in Ionic.

+
+ From be2918d1072aa4291a9a3162bcc2b6ba14379ba4 Mon Sep 17 00:00:00 2001 From: Liam DeBeasi Date: Wed, 13 Sep 2023 14:17:57 -0400 Subject: [PATCH 09/18] add guide for NgModules --- docs/angular/build-options.md | 141 ++++++++++++++++++++++++++++++---- 1 file changed, 128 insertions(+), 13 deletions(-) diff --git a/docs/angular/build-options.md b/docs/angular/build-options.md index daec4d11108..7da46275f15 100644 --- a/docs/angular/build-options.md +++ b/docs/angular/build-options.md @@ -150,13 +150,13 @@ export class AppModule {} ## Migrating from Modules to Standalone -:::note -This migration guide assumes the Angular components in your application are already standalone components. See [Migrating to Standalone](https://angular.io/guide/standalone-migration) if your Angular application is not already using standalone components. -::: +The Standalone option is newer than the Modules option, so developers may wish to switch during the development of their application. This guide details the steps needed to migrate. + +Note that migrating to Ionic standalone components must be done all at the same time and cannot be done gradually. The Modules and Standalone approaches use two different build systems of Ionic that cannot be used at the same time. -The Standalone option is newer than the Modules option, so developers may wish to switch during the development of their application. This guide details the steps needed to migrate as well as limitations to be aware of. +### Using Ionic Standalone Components in Standalone-based Applications -### Steps to Migrate +Follow these steps if your Angular application is already using the standalone architecture, and you want to use Ionic UI components as standalone components too. 1. Run `npm install @ionic/angular@latest` to ensure you are running the latest version of Ionic. Ionic UI Standalone Components is supported in Ionic v7.5 or newer. @@ -164,7 +164,7 @@ The Standalone option is newer than the Modules option, so developers may wish t 3. Remove the `IonicModule` call in `main.ts` in favor of `provideIonicAngular` imported from `@ionic/angular/standalone`. Any config passed to `IonicModule.forRoot` can be passed as an object to this new function. -```diff +```diff title="main.ts" import { enableProdMode, importProvidersFrom } from '@angular/core'; import { bootstrapApplication } from '@angular/platform-browser'; import { RouteReuseStrategy, provideRouter } from '@angular/router'; @@ -200,7 +200,7 @@ bootstrapApplication(AppComponent, { 6. Add imports for each Ionic component in the Angular component where they are used. Be sure to pass the imports to the `imports` array on your Angular component. -```diff +```diff title="app.component.ts" import { Component } from '@angular/core'; + import { IonApp, IonRouterOutlet } from '@ionic/angular/standalone'; @@ -218,7 +218,7 @@ export class AppComponent { 7. If you are using Ionicons, define the icon SVG data used in each Angular component using `addIcons`. This allows you to continue referencing icons by string name in your component template. Note that you will need to do this for any additional icons added. -```diff +```diff title="test.component.ts" import { Component } from '@angular/core'; + import { IonIcon } from '@ionic/angular/standalone'; + import { addIcons } from 'ionicons'; @@ -233,14 +233,14 @@ import { Component } from '@angular/core'; }) export class TestComponent { constructor() { - addIcons({ alarm, logoIonic }); ++ addIcons({ alarm, logoIonic }); } } ``` 8. Remove the following code from your `angular.json` file if present. Note that it may appear multiple times. -```diff +```diff title="angular.json" - { - "glob": "**/*.svg", - "input": "node_modules/ionicons/dist/ionicons/svg", @@ -248,7 +248,122 @@ export class TestComponent { - } ``` -### Limitations +### Using Ionic Standalone Components in NgModule-based Applications + +Follow these steps if your Angular application is still using the NgModule architecture, but you want to adopt Ionic UI components as standalone components now. + +1. Run `npm install @ionic/angular@latest` to ensure you are running the latest version of Ionic. Ionic UI Standalone Components is supported in Ionic v7.5 or newer. + +2. Run `npm install ionicons@latest` to ensure you are running the latest version of Ionicons. Ionicons v7.2 brings usability improvements that reduce the code boilerplate needed to use icons with standalone components. + +3. Remove the `IonicModule` call in `app.module.ts` in favor of `provideIonicAngular` imported from `@ionic/angular/standalone`. Any config passed to `IonicModule.forRoot` can be passed as an object to this new function. + +```diff title="app.module.ts" +import { enableProdMode, importProvidersFrom } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { RouteReuseStrategy, provideRouter } from '@angular/router'; +- import { IonicModule, IonicRouteStrategy } from '@ionic/angular'; ++ import { provideIonicAngular, IonicRouteStrategy } from '@ionic/angular/standalone'; + +import { routes } from './app/app.routes'; +import { AppComponent } from './app/app.component'; +import { environment } from './environments/environment'; + +if (environment.production) { + enableProdMode(); +} + +@NgModule({ + declarations: [AppComponent], +- imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule], ++ imports: [BrowserModule, AppRoutingModule], + providers: [ + { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }, ++ provideIonicAngular({ mode: 'ios' }), + ], + bootstrap: [AppComponent], +}) +export class AppModule {} +``` + +4. Remove any references to `IonicModule` found elsewhere in your application. + +5. Update any existing imports from `@ionic/angular` to import from `@ionic/angular/standalone` instead. + +```diff +- import { Platform } from '@ionic/angular'; ++ import { Platform } from '@ionic/angular/standalone'; +``` + +6. Add imports for each Ionic component in the NgModule for the Angular component where they are used. Be sure to pass the components to the `imports` array on the module. + +```diff title="app.module.ts" +import { enableProdMode, importProvidersFrom } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { RouteReuseStrategy, provideRouter } from '@angular/router'; +- import { provideIonicAngular, IonicRouteStrategy } from '@ionic/angular/standalone'; ++ import { provideIonicAngular, IonicRouteStrategy, IonApp, IonRouterOutlet } from '@ionic/angular/standalone'; + +import { routes } from './app/app.routes'; +import { AppComponent } from './app/app.component'; +import { environment } from './environments/environment'; + +if (environment.production) { + enableProdMode(); +} + +@NgModule({ + declarations: [AppComponent], +- imports: [BrowserModule, AppRoutingModule], ++ imports: [BrowserModule, AppRoutingModule, IonApp, IonRouterOutlet], + providers: [ + { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }, + provideIonicAngular({ mode: 'ios' }) + ], + bootstrap: [AppComponent], +}) +export class AppModule {} +``` + +7. If you are using Ionicons, define the icon SVG data used in each Angular component using `addIcons`. This allows you to continue referencing icons by string name in your component template. Note that you will need to do this for any additional icons added. The `IonIcon` component should still be provided in the NgModule. + +```diff title="test.component.ts" +import { Component } from '@angular/core'; ++ import { addIcons } from 'ionicons'; ++ import { alarm, logoIonic } from 'ionicons/icons'; + +@Component({ + selector: 'app-root', + templateUrl: 'app.component.html', + styleUrls: ['app.component.scss'], +}) +export class TestComponent { + constructor() { + addIcons({ alarm, logoIonic }); + } +} +``` + +```diff title="test.module.ts" +import { NgModule } from '@angular/core'; +import { TestComponent } from './test.component'; ++ import { IonIcon } from '@ionic/angular/standalone'; -1. Your application must already make use of standalone APIs. Using Ionic UI components as standalone components in an application that uses `NgModule` is not supported. -2. Migrating to Ionic standalone components must be done all at the same time and cannot be done gradually. The Modules and Standalone approaches use two different build systems of Ionic that cannot be used at the same time. +@NgModule({ + imports: [ ++ IonIcon, + ], + declarations: [TestComponent] +}) +export class TestComponentModule {} +``` + +8. Remove the following code from your `angular.json` file if present. Note that it may appear multiple times. + +```diff title="angular.json" +- { +- "glob": "**/*.svg", +- "input": "node_modules/ionicons/dist/ionicons/svg", +- "output": "./svg" +- } +``` From c678963349d5ba95d452890f22cb133ad2f43d38 Mon Sep 17 00:00:00 2001 From: Liam DeBeasi Date: Wed, 13 Sep 2023 14:33:38 -0400 Subject: [PATCH 10/18] lint --- docs/angular/build-options.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/angular/build-options.md b/docs/angular/build-options.md index 7da46275f15..2d2dc475ba9 100644 --- a/docs/angular/build-options.md +++ b/docs/angular/build-options.md @@ -278,7 +278,7 @@ if (environment.production) { - imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule], + imports: [BrowserModule, AppRoutingModule], providers: [ - { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }, + { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }, + provideIonicAngular({ mode: 'ios' }), ], bootstrap: [AppComponent], @@ -317,7 +317,7 @@ if (environment.production) { - imports: [BrowserModule, AppRoutingModule], + imports: [BrowserModule, AppRoutingModule, IonApp, IonRouterOutlet], providers: [ - { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }, + { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }, provideIonicAngular({ mode: 'ios' }) ], bootstrap: [AppComponent], From 786b1b3e856f9151c35310c5d230082f75a1a818 Mon Sep 17 00:00:00 2001 From: Liam DeBeasi Date: Fri, 15 Sep 2023 15:09:51 -0400 Subject: [PATCH 11/18] Update docs/angular/build-options.md Co-authored-by: Sean Perkins <13732623+sean-perkins@users.noreply.github.com> --- docs/angular/build-options.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/angular/build-options.md b/docs/angular/build-options.md index 2d2dc475ba9..0ce05b7dc72 100644 --- a/docs/angular/build-options.md +++ b/docs/angular/build-options.md @@ -152,7 +152,7 @@ export class AppModule {} The Standalone option is newer than the Modules option, so developers may wish to switch during the development of their application. This guide details the steps needed to migrate. -Note that migrating to Ionic standalone components must be done all at the same time and cannot be done gradually. The Modules and Standalone approaches use two different build systems of Ionic that cannot be used at the same time. +Migrating to Ionic standalone components must be done all at the same time and cannot be done gradually. The Modules and Standalone approaches use two different build systems of Ionic that cannot be used at the same time. ### Using Ionic Standalone Components in Standalone-based Applications From 92e6d45ffc4c5f674597e5c10584a93e86d8655b Mon Sep 17 00:00:00 2001 From: Liam DeBeasi Date: Fri, 15 Sep 2023 15:10:12 -0400 Subject: [PATCH 12/18] Update docs/angular/build-options.md Co-authored-by: Sean Perkins <13732623+sean-perkins@users.noreply.github.com> --- docs/angular/build-options.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/angular/build-options.md b/docs/angular/build-options.md index 0ce05b7dc72..a533d1e2bb8 100644 --- a/docs/angular/build-options.md +++ b/docs/angular/build-options.md @@ -117,7 +117,7 @@ export class HomePage { ### Overview -Developers can also use the Modules approach by importing `IonicModule` and calling `IonicModule.forRoot()` in the `imports` array in `app.module.ts`. This registers a version of Ionic where Ionic components will be lazily loaded as needed. +Developers can also use the Modules approach by importing `IonicModule` and calling `IonicModule.forRoot()` in the `imports` array in `app.module.ts`. This registers a version of Ionic where Ionic components will be lazily loaded at runtime. **Benefits** From fb4a04d410b057cf388c4e50164e14f983e3f1a5 Mon Sep 17 00:00:00 2001 From: Liam DeBeasi Date: Fri, 15 Sep 2023 15:14:08 -0400 Subject: [PATCH 13/18] clarify standalone --- docs/angular/build-options.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/angular/build-options.md b/docs/angular/build-options.md index a533d1e2bb8..53b0246af8f 100644 --- a/docs/angular/build-options.md +++ b/docs/angular/build-options.md @@ -12,7 +12,7 @@ Ionic UI components as Angular standalone components is supported starting in Io ### Overview -Developers with Angular applications that use [standalone components](https://angular.io/guide/standalone-components) can also use Ionic components as standalone components to provide a simplified way to build Angular applications. This option involves importing specific Ionic components in the Angular components you want to use them in. +Developers can use Ionic components as standalone components to take advantage of treeshaking and newer Angular features. This option involves importing specific Ionic components in the Angular components you want to use them in. Developers can use Ionic standalone components even if their Angular application is NgModule-based. See the [Standalone Migration Guide](#migrating-from-modules-to-standalone) for instructions on how to update your Ionic app to make use of Ionic standalone components. From 64e7ef5bf525e15ea636230a3dcd2da8a9e1bcfa Mon Sep 17 00:00:00 2001 From: Liam DeBeasi Date: Mon, 18 Sep 2023 15:15:53 -0400 Subject: [PATCH 14/18] clarify config example --- docs/angular/build-options.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/angular/build-options.md b/docs/angular/build-options.md index 53b0246af8f..799a51aeb87 100644 --- a/docs/angular/build-options.md +++ b/docs/angular/build-options.md @@ -182,6 +182,12 @@ if (environment.production) { bootstrapApplication(AppComponent, { providers: [ { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }, + /** + * The custom config serves as an example + * of how to pass a config to provideIonicAngular. + * You do not need to set "mode: 'ios'" to + * use Ionic standalone components. + */ - importProvidersFrom(IonicModule.forRoot({ mode: 'md' })), + provideIonicAngular({ mode: 'md' }), provideRouter(routes), @@ -279,6 +285,12 @@ if (environment.production) { + imports: [BrowserModule, AppRoutingModule], providers: [ { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }, + /** + * The custom config serves as an example + * of how to pass a config to provideIonicAngular. + * You do not need to set "mode: 'ios'" to + * use Ionic standalone components. + */ + provideIonicAngular({ mode: 'ios' }), ], bootstrap: [AppComponent], From 9c5e120a5023311914c41545b78f8750da6d910a Mon Sep 17 00:00:00 2001 From: Liam DeBeasi Date: Mon, 18 Sep 2023 15:15:59 -0400 Subject: [PATCH 15/18] add missing config --- docs/angular/build-options.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/angular/build-options.md b/docs/angular/build-options.md index 799a51aeb87..f48650905da 100644 --- a/docs/angular/build-options.md +++ b/docs/angular/build-options.md @@ -281,7 +281,7 @@ if (environment.production) { @NgModule({ declarations: [AppComponent], -- imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule], +- imports: [BrowserModule, IonicModule.forRoot({ mode: 'ios' }), AppRoutingModule], + imports: [BrowserModule, AppRoutingModule], providers: [ { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }, From 55e53db77a8bf55257be4375601bd7c40946f9ab Mon Sep 17 00:00:00 2001 From: Liam DeBeasi Date: Mon, 18 Sep 2023 15:17:18 -0400 Subject: [PATCH 16/18] shorten titles --- docs/angular/build-options.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/angular/build-options.md b/docs/angular/build-options.md index f48650905da..841e873efc1 100644 --- a/docs/angular/build-options.md +++ b/docs/angular/build-options.md @@ -154,7 +154,7 @@ The Standalone option is newer than the Modules option, so developers may wish t Migrating to Ionic standalone components must be done all at the same time and cannot be done gradually. The Modules and Standalone approaches use two different build systems of Ionic that cannot be used at the same time. -### Using Ionic Standalone Components in Standalone-based Applications +### Standalone-based Applications Follow these steps if your Angular application is already using the standalone architecture, and you want to use Ionic UI components as standalone components too. @@ -254,7 +254,7 @@ export class TestComponent { - } ``` -### Using Ionic Standalone Components in NgModule-based Applications +### NgModule-based Applications Follow these steps if your Angular application is still using the NgModule architecture, but you want to adopt Ionic UI components as standalone components now. From 75405a9ac17f0b14985e48f5ed534da707e988b4 Mon Sep 17 00:00:00 2001 From: Liam DeBeasi Date: Mon, 18 Sep 2023 15:18:52 -0400 Subject: [PATCH 17/18] move bootstrapping above components --- docs/angular/build-options.md | 40 +++++++++++++++++------------------ 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/docs/angular/build-options.md b/docs/angular/build-options.md index 841e873efc1..16ef41e92d3 100644 --- a/docs/angular/build-options.md +++ b/docs/angular/build-options.md @@ -32,26 +32,6 @@ See the [Standalone Migration Guide](#migrating-from-modules-to-standalone) for All Ionic imports should be imported from the `@ionic/angular/standalone` submodule. This includes imports such as components, directives, providers, and types. Importing from `@ionic/angular` may pull in lazy loaded Ionic code which can interfere with treeshaking. ::: -**Components** - -In the example below, we are importing `IonContent` and `IonButton` from `@ionic/angular/standalone` and passing them to `imports` for use in the component template. We would get a compiler error if these components were not imported and provided to the `imports` array. - -```typescript -import { Component } from '@angular/core'; -import { IonButton, IonContent } from '@ionic/angular/standalone'; - -@Component({ - selector: 'app-home', - templateUrl: 'home.page.html', - styleUrls: ['home.page.scss'], - standalone: true, - imports: [IonButton, IonContent], -}) -export class HomePage { - constructor() {} -} -``` - **Bootstrapping and Configuration** Ionic Angular needs to be configured when the Angular application calls `bootstrapApplication` using the `provideIonicAngular` function. Developers can pass any [IonicConfig](../developing/config#ionicconfig) values as an object in this function. Note that `provideIonicAngular` needs to be called even if no custom config is passed. @@ -79,6 +59,26 @@ bootstrapApplication(AppComponent, { }); ``` +**Components** + +In the example below, we are importing `IonContent` and `IonButton` from `@ionic/angular/standalone` and passing them to `imports` for use in the component template. We would get a compiler error if these components were not imported and provided to the `imports` array. + +```typescript +import { Component } from '@angular/core'; +import { IonButton, IonContent } from '@ionic/angular/standalone'; + +@Component({ + selector: 'app-home', + templateUrl: 'home.page.html', + styleUrls: ['home.page.scss'], + standalone: true, + imports: [IonButton, IonContent], +}) +export class HomePage { + constructor() {} +} +``` + **Icons** The icon SVG data needs to be defined in the Angular component so it can be loaded correctly. Developers can use the `addIcons` function from `ionicons` to map the SVG data to a string name. Developers can then reference the icon by its string name using the `name` property on `IonIcon`. From ad5647284f5f357b0ec1adfc78dc114ed328b829 Mon Sep 17 00:00:00 2001 From: Liam DeBeasi Date: Mon, 18 Sep 2023 16:45:36 -0400 Subject: [PATCH 18/18] update mode --- docs/angular/build-options.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/angular/build-options.md b/docs/angular/build-options.md index 16ef41e92d3..ba05435cdfb 100644 --- a/docs/angular/build-options.md +++ b/docs/angular/build-options.md @@ -188,8 +188,8 @@ bootstrapApplication(AppComponent, { * You do not need to set "mode: 'ios'" to * use Ionic standalone components. */ -- importProvidersFrom(IonicModule.forRoot({ mode: 'md' })), -+ provideIonicAngular({ mode: 'md' }), +- importProvidersFrom(IonicModule.forRoot({ mode: 'ios' })), ++ provideIonicAngular({ mode: 'ios' }), provideRouter(routes), ], });