跳至主要内容
版本:v8

构建选项

开发人员有两种选择来使用 Ionic 组件:独立或模块。本指南涵盖了这两种选项,以及每种方法的优缺点。

虽然独立方法更新,并使用更现代的 Angular API,但模块方法将继续在 Ionic 中得到支持。本网站上的大多数 Angular 示例都使用模块方法。

独立

信息

从 Ionic v7.5 开始支持 Ionic UI 组件作为 Angular 独立组件。

概述

开发人员可以使用 Ionic 组件作为独立组件,以利用 tree shaking 和更新的 Angular 功能。此选项涉及在要使用它们的 Angular 组件中导入特定的 Ionic 组件。即使开发人员的 Angular 应用程序基于 NgModule,他们也可以使用 Ionic 独立组件。

有关如何更新 Ionic 应用程序以使用 Ionic 独立组件的说明,请参阅 独立迁移指南

优点

  1. 启用 tree shaking,因此最终构建输出只包含运行应用程序所需的代码,从而减小了总体构建大小。
  2. 避免使用 NgModule,以简化开发体验并使代码更易于理解。
  3. 允许开发人员也使用更新的 Angular 功能,例如 ESBuild

缺点

  1. Ionic 组件需要导入到每个使用它们的 Angular 组件中,这可能很费时。

在基于独立的应用程序中使用

警告

所有 Ionic 导入都应从 @ionic/angular/standalone 子模块导入。这包括诸如组件、指令、提供程序和类型的导入。从 @ionic/angular 导入可能会拉入延迟加载的 Ionic 代码,这会干扰 tree shaking。

引导和配置

当 Angular 应用程序使用 provideIonicAngular 函数调用 bootstrapApplication 时,需要配置 Ionic Angular。开发人员可以将任何 IonicConfig 值作为对象传递到此函数中。请注意,即使没有传递自定义配置,也需要调用 provideIonicAngular

main.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 { 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 },
provideIonicAngular({ mode: 'ios' }),
provideRouter(routes),
],
});

组件

在下面的示例中,我们从 @ionic/angular/standalone 导入 IonContentIonButton,并将它们传递给 imports 以在组件模板中使用。如果没有导入这些组件并将其提供给 imports 数组,我们将得到编译器错误。

home.page.ts
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() {}
}

图标

需要在 Angular 组件中定义图标 SVG 数据,以便能够正确加载。开发人员可以使用 ionicons 中的 addIcons 函数将 SVG 数据映射到字符串名称。然后,开发人员可以使用 IonIcon 上的 name 属性使用其字符串名称引用图标。

我们建议在 Angular 组件 constructor 中调用 addIcons,这样只有在使用 Angular 组件时才会添加数据。

对于使用 Ionicons 7.2 或更新版本的开发人员,仅传递 SVG 数据会导致自动生成字符串名称。

home.page.ts
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 });
}
}

也可以在入口点(例如 app.component.ts)中注册图标,以避免多次调用 addIcons。开发人员应注意,初始应用程序块可能会增大,因为已注册的图标需要在应用程序启动时加载。但是,如果应用程序使用的图标很少,则这种影响可能很小。

app.component.ts
import { Component } from '@angular/core';
import { addIcons } from 'ionicons';
import { logoIonic } from 'ionicons/icons';

@Component({
selector: 'app-root',
templateUrl: 'app.component.html',
styleUrls: ['app.component.scss'],
standalone: true,
})
export class AppComponent {
constructor() {
/**
* Any icons you want to use in your application
* can be registered in app.component.ts and then
* referenced by name anywhere in your application.
*/
addIcons({ logoIonic });
}
}

在应用程序入口点注册的图标可以在应用程序中的任何位置按名称引用。

home.page.html
<!-- 
logoIonic was registered in app.component.ts instead of home.page.ts,
but it can still be used in home.page.html.
-->
<ion-icon name="logo-ionic"></ion-icon>

路由

希望在 Ionic 组件上使用 routerLinkrouterActionrouterDirection 的开发人员应导入 IonRouterLink 指令。希望在锚点 (<a>) 元素上使用这些路由功能的开发人员应改为导入 IonRouterLinkWithHref

home.page.ts
import { Component } from '@angular/core';
import { RouterLink } from '@angular/router';
import { IonButton, IonRouterLink } from '@ionic/angular/standalone';

@Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
standalone: true,
imports: [
IonButton,
RouterLink, // required to get base routerLink behavior for @angular/router
IonRouterLink, // use IonRouterLinkWithHref if you are using an <a> element instead
],
})
export class HomePage {}
home.page.html
<ion-button routerLink="/foo" routerDirection="root">Go to Foo Page</ion-button>

测试

Ionic Angular 的独立组件使用 ES 模块。因此,使用 Jest 的开发人员应确保将 ES 模块转换为 Jest 可以使用的格式。使用 Jest 的开发人员应在其 Jest 配置中添加以下内容


"transformIgnorePatterns": ["<rootDir>/node_modules/(?!(@ionic/angular|@ionic/core|ionicons|@stencil/core|@angular/*)/)"]

在基于 NgModule 的应用程序中使用

警告

所有 Ionic 导入都应从 @ionic/angular/standalone 子模块导入。这包括诸如组件、指令、提供程序和类型的导入。从 @ionic/angular 导入可能会拉入延迟加载的 Ionic 代码,这会干扰 tree shaking。

引导和配置

需要使用 provideIonicAngular 函数在 app.module.tsproviders 数组中配置 Ionic Angular。开发人员可以将任何 IonicConfig 值作为对象传递到此函数中。请注意,即使没有传递自定义配置,也需要调用 provideIonicAngular

app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouteReuseStrategy } from '@angular/router';

import { IonicRouteStrategy, provideIonicAngular } from '@ionic/angular/standalone';

import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';

@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, AppRoutingModule],
providers: [provideIonicAngular(), { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }],
bootstrap: [AppComponent],
})
export class AppModule {}

组件

在下面的示例中,我们从 @ionic/angular/standalone 导入 IonContentIonButton,并将它们传递给 Angular 组件 NgModule 中的 imports 数组以在组件模板中使用。如果没有导入这些组件并将其提供给 imports 数组,我们将得到编译器错误。

home.module.ts
import { NgModule } from '@angular/core';
import { IonButton, IonContent } from '@ionic/angular/standalone';
import { HomePage } from './home.page';

import { HomePageRoutingModule } from './home-routing.module';

@NgModule({
imports: [IonButton, IonContent, HomePageRoutingModule],
declarations: [HomePage],
})
export class HomePageModule {}

图标

需要在 Angular 组件中定义图标 SVG 数据,以便能够正确加载。开发人员可以使用 ionicons 中的 addIcons 函数将 SVG 数据映射到字符串名称。然后,开发人员可以使用 IonIcon 上的 name 属性使用其字符串名称引用图标。与其他 Ionic 组件一样,IonIcon 组件应在 app.module.ts 中添加。

我们建议在 Angular 组件 constructor 中调用 addIcons,这样只有在使用 Angular 组件时才会添加数据。

对于使用 Ionicons 7.2 或更新版本的开发人员,仅传递 SVG 数据会导致自动生成字符串名称。

home.page.ts
import { Component } from '@angular/core';
import { addIcons } from 'ionicons';
import { logoIonic } from 'ionicons/icons';

@Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
})
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 });
}
}

也可以在入口点(例如 app.component.ts)中注册图标,以避免多次调用 addIcons。开发人员应注意,初始应用程序块可能会增大,因为已注册的图标需要在应用程序启动时加载。但是,如果应用程序使用的图标很少,则这种影响可能很小。

app.component.ts
import { Component } from '@angular/core';
import { addIcons } from 'ionicons';
import { logoIonic } from 'ionicons/icons';

@Component({
selector: 'app-root',
templateUrl: 'app.component.html',
styleUrls: ['app.component.scss'],
})
export class AppComponent {
constructor() {
/**
* Any icons you want to use in your application
* can be registered in app.component.ts and then
* referenced by name anywhere in your application.
*/
addIcons({ logoIonic });
}
}

在应用程序入口点注册的图标可以在应用程序中的任何位置按名称引用。

home.page.html
<!-- 
logoIonic was registered in app.component.ts instead of home.page.ts,
but it can still be used in home.page.html.
-->
<ion-icon name="logo-ionic"></ion-icon>

路由

希望在 Ionic 组件上使用 routerLinkrouterActionrouterDirection 的开发人员应导入 IonRouterLink 指令。希望在锚点 (<a>) 元素上使用这些路由功能的开发人员应改为导入 IonRouterLinkWithHref

home.module.ts
import { NgModule } from '@angular/core';
import { RouterLink } from '@angular/router';
import { IonButton, IonRouterLink } from '@ionic/angular/standalone';
import { HomePage } from './home.page';

import { HomePageRoutingModule } from './home-routing.module';

@NgModule({
imports: [
IonButton,
RouterLink, // required to get base routerLink behavior for @angular/router
IonRouterLink, // use IonRouterLinkWithHref if you are using an <a> element instead
HomePageRoutingModule,
],
declarations: [HomePage],
})
export class HomePageModule {}
home.page.html
<ion-button routerLink="/foo" routerDirection="root">Go to Foo Page</ion-button>

测试

Ionic Angular 的独立组件使用 ES 模块。因此,使用 Jest 的开发人员应确保将 ES 模块转换为 Jest 可以使用的格式。使用 Jest 的开发人员应在其 Jest 配置中添加以下内容


"transformIgnorePatterns": ["<rootDir>/node_modules/(?!(@ionic/angular|@ionic/core|ionicons|@stencil/core|@angular/*)/)"]

模块

概述

开发人员还可以通过导入 IonicModule 并调用 app.module.ts 中的 imports 数组中的 IonicModule.forRoot() 来使用模块方法。这将注册一个 Ionic 版本,其中 Ionic 组件将在运行时延迟加载。

优点

  1. 由于组件是按需延迟加载的,因此开发人员无需花时间手动导入和注册每个 Ionic 组件。

缺点

  1. 延迟加载 Ionic 组件意味着编译器在构建时不知道需要哪些组件。这意味着最终的应用程序包可能比实际需要的大很多。
  2. 开发人员无法使用更新的 Angular 功能,例如 ESBuild

使用

在下面的示例中,我们使用 IonicModule 来创建 Ionic 的延迟加载版本。然后,我们可以引用任何 Ionic 组件,而无需显式导入它。

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 {}

从模块迁移到独立

提示

试试我们自动化的迁移到独立的工具!

有关如何开始的说明,请参阅 https://github.com/ionic-team/ionic-angular-standalone-codemods。与迁移工具相关的所有问题都应在链接的存储库中提交。

独立选项比模块选项更新,因此开发人员可能希望在应用程序开发过程中切换。本指南详细介绍了迁移所需的步骤。

迁移到 Ionic 独立组件必须一次性完成,不能逐步进行。模块和独立方法使用 Ionic 的两种不同的构建系统,不能同时使用。

鼓励开发人员尝试自动迁移实用程序,但他们也可以在需要手动迁移应用程序时按照以下步骤操作。

基于独立组件的应用程序

如果您的 Angular 应用程序已经使用独立架构,并且您也希望将 Ionic UI 组件用作独立组件,请按照以下步骤操作。

  1. 运行npm install @ionic/angular@latest以确保您正在运行最新版本的 Ionic。Ionic UI 独立组件在 Ionic v7.5 或更高版本中受支持。

  2. 运行npm install ionicons@latest以确保您正在运行最新版本的 Ionicons。Ionicons v7.2 带来了可用性改进,减少了使用独立组件图标所需的代码样板。

  3. main.ts中删除IonicModule调用,改用从@ionic/angular/standalone导入的provideIonicAngular。传递给IonicModule.forRoot的任何配置都可以作为对象传递给此新函数。

main.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();
}

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: 'ios' })),
+ provideIonicAngular({ mode: 'ios' }),
provideRouter(routes),
],
});
  1. 删除应用程序中其他位置发现的任何对IonicModule的引用。

  2. 将任何从@ionic/angular的现有导入更新为改为从@ionic/angular/standalone导入。

- import { Platform } from '@ionic/angular';
+ import { Platform } from '@ionic/angular/standalone';
  1. 为在 Angular 组件中使用 Ionic 组件的每个 Ionic 组件添加导入。确保将导入传递到 Angular 组件的imports数组中。
app.component.ts
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() {}
}
  1. 如果您使用的是 Ionicons,请使用addIcons定义在每个 Angular 组件中使用的图标 SVG 数据。这使您可以继续在组件模板中通过字符串名称引用图标。请注意,您需要对添加的任何其他图标执行此操作。
test.component.ts
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 });
}
}
  1. 如果存在,请从angular.json文件中删除以下代码。请注意,它可能出现多次。
angular.json
- {
- "glob": "**/*.svg",
- "input": "node_modules/ionicons/dist/ionicons/svg",
- "output": "./svg"
- }
  1. 如果您使用的是routerLinkrouterDirectionrouterAction,请确保为 Ionic 组件导入IonRouterLink指令或为<a>元素导入IonRouterLinkWithHref指令。
test.component.ts
import { Component } from '@angular/core';
- import { IonButton } from '@ionic/angular/standalone';
+ import { IonButton, IonRouterLink } from '@ionic/angular/standalone';

@Component({
selector: 'app-root',
templateUrl: 'app.component.html',
styleUrls: ['app.component.scss'],
standalone: true,
imports: [
IonButton,
+ IonRouterLink
],
})
export class TestComponent {}
  1. 如果您使用的是 VSCode,建议忽略@ionic/angular/common@ionic/angular模块说明符,以获取导入建议。
.vscode/settings.json
{
"typescript.preferences.autoImportFileExcludePatterns": ["@ionic/angular/common", "@ionic/angular"]
}

基于 NgModule 的应用程序

如果您的 Angular 应用程序仍在使用 NgModule 架构,但您现在希望采用 Ionic UI 组件作为独立组件,请按照以下步骤操作。

  1. 运行npm install @ionic/angular@latest以确保您正在运行最新版本的 Ionic。Ionic UI 独立组件在 Ionic v7.5 或更高版本中受支持。

  2. 运行npm install ionicons@latest以确保您正在运行最新版本的 Ionicons。Ionicons v7.2 带来了可用性改进,减少了使用独立组件图标所需的代码样板。

  3. app.module.ts中删除IonicModule调用,改用从@ionic/angular/standalone导入的provideIonicAngular。传递给IonicModule.forRoot的任何配置都可以作为对象传递给此新函数。

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({ mode: 'ios' }), AppRoutingModule],
+ 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],
})
export class AppModule {}
  1. 删除应用程序中其他位置发现的任何对IonicModule的引用。

  2. 将任何从@ionic/angular的现有导入更新为改为从@ionic/angular/standalone导入。

- import { Platform } from '@ionic/angular';
+ import { Platform } from '@ionic/angular/standalone';
  1. 在 Angular 组件中使用 Ionic 组件的 NgModule 中为每个 Ionic 组件添加导入。确保将组件传递到模块的imports数组中。
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 {}

例如,所有使用 Ionic 组件的模块都需要在它们自己的组件模块中导入 Ionic 组件。

home.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { HomePage } from './home.page';

import { HomePageRoutingModule } from './home-routing.module';

+ import { IonContent, IonHeader, IonTitle, IonToolbar } from '@ionic/angular/standalone';

@NgModule({
imports: [
CommonModule,
FormsModule,
HomePageRoutingModule,
+ IonContent,
+ IonHeader,
+ IonTitle,
+ IonToolbar
],
declarations: [HomePage]
})
export class HomePageModule {}
  1. 如果您使用的是 Ionicons,请使用addIcons定义在每个 Angular 组件中使用的图标 SVG 数据。这使您可以继续在组件模板中通过字符串名称引用图标。请注意,您需要对添加的任何其他图标执行此操作。IonIcon组件应仍然在 NgModule 中提供。
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 });
}
}
test.module.ts
import { NgModule } from '@angular/core';
import { TestComponent } from './test.component';
+ import { IonIcon } from '@ionic/angular/standalone';

@NgModule({
imports: [
+ IonIcon,
],
declarations: [TestComponent]
})
export class TestComponentModule {}
  1. 如果存在,请从angular.json文件中删除以下代码。请注意,它可能出现多次。
angular.json
- {
- "glob": "**/*.svg",
- "input": "node_modules/ionicons/dist/ionicons/svg",
- "output": "./svg"
- }
  1. 如果您使用的是routerLinkrouterDirectionrouterAction,请确保为 Ionic 组件导入IonRouterLink指令或为<a>元素导入IonRouterLinkWithHref指令。
test.module.ts
import { NgModule } from '@angular/core';
import { TestComponent } from './test.component';
- import { IonButton } from '@ionic/angular/standalone';
+ import { IonButton, IonRouterLink } from '@ionic/angular/standalone';

@NgModule({
imports: [
IonButton,
+ IonRouterLink,
],
declarations: [TestComponent]
})
  1. 如果您使用的是 VSCode,建议忽略@ionic/angular/common@ionic/angular模块说明符,以获取导入建议。
.vscode/settings.json
{
"typescript.preferences.autoImportFileExcludePatterns": ["@ionic/angular/common", "@ionic/angular"]
}