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 时,建议参照以下过程:
- 使用
blank
启动器生成一个新项目(参考 创建应用)。 -
从
src/providers
复制所有 Angular services到src/app/services
。- Services 应该包括
@Injectable()
装饰器中的{ providedIn: 'root' }
。更多详情, 请参考 Angular provider docs.
- Services 应该包括
- 复制应用程序的其他根级别项目 (例如, pipes, components 等) 并保持目录结构从
src/components
变更为src/app/components
. - 从
src/app/app.scss
复制全局 Sass 样式到src/global.scss
-
复制应用程序的其余部分, 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 中,对导航和路由进行了重大更改。 NavController
和 ion-nav
现已弃用。 虽然他们仍然可以使用,但仅当用于应用程序没有使用延迟加载时。
代替 ion-nav
和 NavController
,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 的迁移工具 ,它可以检测问题,甚至可以自动修复其中的一些问题。