6

Ionic 3 升级 Ionic 4 迁移指南

前言

Ionic 4 包含现代 Web API,如Custom Elements,CSS Variables和Shadow DOM。它完全与开发框架无关,作为 Web 开发人员的UI库,无论他们决定使用什么前端工具或代码框架。

在Vue,React或根本没有框架中使用Ionic也是如此。 就像Ionic Angular一样,我们的目标是使用传统标准在最流行的框架中轻松采用Ionic。使用Vue开发Ionic应用参考这里

Ionic Framework 4使用标准 Web API 从头开始重建,每个组件都打包为符合标准的 Web 组件。 通过单独依赖浏览器 API 支持并保持每个组件的公共 API 稳定,这使框架的核心保持友好。

与此相反,依赖于特定框架的客户端运行时和组件模型,这些模型可能会随着时间的推移而发生变化(需要进行代价高昂的重写和API更改)。 Ionic 4的目的是为了避免可怕的“框架流失”,因此我们可以花更多的时间专注于我们最擅长的事情:为Web开发人员创建出色的UI组件。 简而言之,我们永远不想再次重写Ionic的组件。

v4中最大的变化之一是Ionic为每个组件使用Web组件。我们甚至构建了一个名为Stencil的工具来帮助我们更轻松地完成这项工作并开源!

除了避免框架流失外,Web Components还将更多工作推向浏览器并需要更少的代码,从而为负载和启动时间带来关键性能改进,这对于构建高性能Progressive Web Apps至关重要,这是项目向前发展的重点。

对于那些刚接触Web Components的人来说,该术语指的是一系列Web API,它们在现代移动和桌面浏览器上得到广泛支持,例如Custom Elements和Shadow DOM。虽然Web Components已经被炒作了几年,但我们认为浏览器和开发人员的支持终于达到了临界质量,使它们为黄金时段做好了准备。但我们并不是唯一的 - 许多传统框架和UI库也开始采用它们(例如:Angular Elements)。

由于您可能已经对浏览器支持感到疑惑:Ionic无缝地填充了极少数本身不支持Web组件的浏览器。至关重要的是,polyfill只会根据功能检测下载到需要它们的客户端,因此绝大多数用户甚至不需要请求其中任何一个。令人惊讶的是,移动设备对Web组件API提供了更广泛的支持,使得polyfill更加不必要。

当Ionic 2发布时,Angular CLI,构建工具和 Router 出现了大量的流失性和不确定性。因此,Ionic必须构建自己的许多工具版本。快进到今天,Angular通过一些出色的工具填补了这些空白,现在是Ionic利用它,并遵循Angular社区中设定的标准的时候了。

从Ionic 4开始,我们很高兴完全接受Angular CLI和 Router !这些更新允许我们用官方的,维护良好的Angular工具替换ionic-app-scripts和Ionic的 Router 。

这意味着Angular开发人员现在可以直接将Angular CLI用于Ionic应用程序,并随时了解Angular继续取得的令人敬畏的进展。我们还想确保Ionic Angular为Framework使用了defacto标准 Router ,因此Angular开发人员可以再次使用他们熟悉的API。我们将能够更深入地了解我们的文档和即将发布的博客文章。

虽然这对现有的Ionic Angular开发人员来说是一个改变,但是对于该项目来说这是一个长期的胜利,因为Ionic可以更多地关注组件,而不是更多的不必要的复杂工具,以及Ionic Angular开发人员的胜利,现在可以使用一流的Angular工具和惯例。

概述

将现有应用程序从 Ionic 3 迁移到 4 时,建议参照以下过程:

  1. 使用 blank 启动器生成一个新项目(参考 创建应用)。
  2. src/providers 复制所有 Angular services到 src/app/services

    • Services 应该包括 @Injectable() 装饰器中的 { providedIn: 'root' } 。更多详情, 请参考 Angular provider docs.
  3. 复制应用程序的其他根级别项目 (例如, pipes, components 等) 并保持目录结构从 src/components 变更为 src/app/components.
  4. src/app/app.scss 复制全局 Sass 样式到 src/global.scss
  5. 复制应用程序的其余部分, page 到 page 或者 feature 到 feature, 注意以下几点:

    • 默认情况下,Emulated Shadow DOM处 于启用状态
    • Page/component 的 Sass 不应再包含在 page/component 标记中,而应使用 Angular @Component 装饰器 的 styleUrls 选项
    • RxJS 已从 v5 更新为 v6 (参考 RxJS变更)
    • 某些生命周期 hooks 应该被 Angular 的 hooks 取代 (参考 生命周期事件)
    • 可能需要更改某些标记 (有迁移工具可用, 参考 标记变更)

在许多情况下,使用 Ionic CLI 生成新对象然后复制代码也可以很好地工作。 例如:ionic g service weather 将创建一个 Weather 服务和测试 shell。 然后可以根据需要对旧代码中的代码进行微小修改。 这有助于确保遵循正确的结构。 这也会为单元测试生成 shell。

项目结构

Ionic 3 应用程序和 Ionic 4 应用程序之间的主要变化之一是项目整体的布局和结构。 在第3版中,Ionic 应用程序有一个自定义约定,用于如何设置应用程序以及该文件夹结构应该是什么样子。 在 v4 中,已更改为遵循每个受支持框架的建议的设置。

例如,如果某个应用程序正在使用 Angular,那么该项目结构将与 Angular CLI 应用程序完全相同。 这种变化虽然需要一点适应过程,但有助于保持常见模式和文档的一致性。

上面的比较是 v4 应用程序项目结构的一个示例。 对于有 Angular 项目经验的开发人员来说,这应该让人感到非常熟悉。

有一个 src/ 目录作为应用程序的主页。 这包括 index.html,所有资产,环境变量和任何特定于应用程序的配置文件。

在迁移应用程序以利用此新布局时,建议使用 CLI 创建新 "base" 项目。 然后,使用新项目布局,逐个迁移应用程序的功能。Pages/components/等,应该移到 src/app/ 文件夹中。

包名变更

V4 版本的另一个变化是 Ionic 的实际包名。 对于 v4,包名称现为 @ionic/angular。 迁移应用程序时,将 imports 从 ionic-angular 更新为 @ionic/angular

RxJS变更

由于从 RxJS v5 更改为 v6,因此需要进行一些次要的 RxJS 更改。 有关详细信息,请参阅 RxJS 迁移指南

生命周期事件

一些 Ionic 生命周期事件等同于 Angular 生命周期 hooks。 例如,ionViewDidLoad() 扮演与 Angular OnInit 生命周期 hook(ngOnInit())相同的角色。 在这种情况下,请使用 Angular 生命周期 hooks。

叠加组件

在 ionic 的早期版本中,同步创建了诸如 Loading,Toast 或 Alert 之类的叠加组件。 在 Ionic v4 中,这些组件都是异步创建的。 因此,API 现在基于 promise。

// v3
showAlert() {
  const alert = this.alertCtrl.create({
    message: "Hello There",
    subHeader: "I'm a subheader"
  });

  alert.present();
}

In v4, promises are used:

showAlert() {
  this.alertCtrl.create({
    message: "Hello There",
    subHeader: "I'm a subheader"
  }).then(alert => alert.present());
}

// 或使用 async/await

async showAlert() {
  const alert = await this.alertCtrl.create({
    message: "Hello There",
    subHeader: "I'm a subheader"
  });

  await alert.present();
}

导航

在 v4 中,对导航和路由进行了重大更改。 NavControllerion-nav 现已弃用。 虽然他们仍然可以使用,但仅当用于应用程序没有使用延迟加载时。

代替 ion-navNavController,Ionic 建议使用官方 Angular Router 进行路由。 Angular 团队在其文档网站上有一个 优秀指南,详细介绍了 Router。

一个关键的区别是,Ionic 应用程序不使用 router-outlet 组件,而是使用 ion-router-outlet。 该组件具有与标准 Angular router-outlet 相同的功能,但是包含 transitions。

延迟加载

另一个变化是在 v4 应用程序中如何进行延迟加载。

在v3中,延迟加载是这样完成的:

// home.page.ts
@IonicPage({
  segment: 'home'
})
@Component({ ... })
export class HomePage {}

// home.module.ts
@NgModule({
  declarations: [HomePage],
  imports: [IonicPageModule.forChild(HomePage)]
})
export class HomePageModule {}

但是,在 v4 中,延迟加载是通过 Angular Router 的 loadChildren 方法完成的:

// home.module.ts
@NgModule({
  imports: [
    IonicModule,
    RouterModule.forChild([{ path: '', component: HomePage }])
  ],
  declarations: [HomePage]
})
export class HomePageModule {}

// app.module.ts
@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    IonicModule.forRoot(),
    RouterModule.forRoot([
      { path: 'home', loadChildren: './pages/home/home.module#HomePageModule' },
      { path: '', redirectTo: 'home', pathMatch: 'full' }
    ])
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

标记变更

由于 v4 已移至 Custom Elements,因此每个组件的标记都发生了重大变化。 这些更改都是按照 Custom Elements 规范进行的,并已记录在 Github 上专门的文件中

为帮助完成这些标记更改,我们发布了基于 TSLint 的迁移工具 ,它可以检测问题,甚至可以自动修复其中的一些问题。


DemoPark
1.1k 声望177 粉丝

Just Full Stack Developer