Kotlin logo

Kotlin

A concise multiplatform language developed by JetBrains

Multiplatform

Web 版 Kotlin 的现在和未来

Read this post in other languages:

概览:我们始终致力于在 Web 开发版 Kotlin Multiplatform 中为 Kotlin 开发者提供强大的无缝支持。 为此,我们正在以下关键领域开展工作:

  • 改进 IDE 对 Web 目标的支持。
  • 将 Kotlin/Wasm 和 Web 版 Compose Multiplatform 提升到 Beta。
  • 为旧版浏览器中的 Compose Multiplatform 提供兼容模式。
  • 消除 Kotlin/JS 中互操作的大部分限制。
  • 针对 Kotlin/JS 中最新的 JavaScript 标准。

Kotlin Multiplatform (KMP) 旨在帮助开发者跨平台共享代码,显著减少开发时间和工作量。 Web 作为使用最广泛的客户端平台,在这个生态系统中扮演着至关重要的角色。

我们有一段时间没有发布更新,但这期间发生了很多事,现在我们准备分享最新进展。

当前格局:JavaScript 和 Wasm

Kotlin Multiplatform 是一种生产就绪技术,通过四个编译器后端以多个平台为目标:Kotlin/JVM、Kotlin/JS、Kotlin/Native 和 Kotlin/Wasm。

对于 Web,KMP 提供两种解决方案:编译到 JavaScript (Kotlin/JS) 和 WebAssembly (Kotlin/Wasm)。 我们将解释为什么这两种我们都有。

为什么有两个 Web 目标?

Kotlin Multiplatform 提供了一种独特的代码共享方式,并且以灵活性为基础构建。 根据项目需求,您可能需要:

  • 仅共享业务逻辑并保持原生 UI。
  • 在所有平台上共享业务逻辑和 UI。

这两种情况有不同的技术要求,JS 和 Wasm 目标分别为它们服务。

共享业务逻辑

如果目标是在 Web 上共享业务逻辑,则可能有一些要求,例如:

  • 为原生 UI 提供复杂的业务逻辑,主要基于 JS。
  • 仅加载特定网页所需的业务逻辑,减少网络负载。
  • 在 JavaScript 和 Kotlin 部分之间交互,无额外性能开销。

在这种情况下,Kotlin/JS 更合适,因为它提供了更好的互操作体验。

共享逻辑和 UI

如果您希望跨平台共享整个应用程序(包括 UI),就可以选择 Compose Multiplatform。 有了它,您对 Web 渲染和性能的要求自然会发生变化:

  • 您希望在每个平台(包括 Web)上一致渲染相同的 UI。
  • 流畅的动画和灵敏的过渡变得非常重要。

这就是 Kotlin/Wasm 的强项。 根据我们的基准测试,WebAssembly 在 UI 共享场景中表现更好(几乎快 3 倍)。

我们在详细的建议中说明了如何为应用程序选择目标。

有哪些更新即将推出?

在接下来的部分中,我们将介绍最重要的动态和计划,从 IDE 工具和互操作性改进到 Web 版 Compose Multiplatform 的演变。

我们来仔细研究这些领域。

IDE 对 Web 目标的更出色支持

为了进一步提供卓越的 Kotlin Multiplatform 开发者体验,我们积极致力于在 IntelliJ IDEA 和 Android Studio 中打造更出色的 KMP 支持。

这还包括改善 JavaScript 和 Wasm 目标的体验。 虽然这两个 IDE 都提供代码功能,但某些功能(例如 JavaScript 和 Wasm 目标的调试)目前仅在 IntelliJ IDEA 中可用。

我们通过以下步骤开始了这一旅程:

  • 添加向导用于创建以 Web 平台为目标的新 KMP 项目。
  • 集成平台调试器,以在两个 Web 目标上轻松调试 KMP 项目。
  • 为应用程序入口点和测试添加装订区域图标以便轻松运行,无需考虑应该使用哪个 Gradle 任务。

将我们的 Wasm 目标和 Web 版 Compose Multiplatform 提升到 Beta

我们知道,Web 对于许多 Compose Multiplatform 用户来说是一个重要的平台,我们致力于为以 Web 为目标的用户增强开发体验。

Web 版 Compose Multiplatform 中的持续改进

资产进入 Alpha 以来,Web 版 Compose Multiplatform 已获得重大更新,缩小了与其他平台的功能差距。 例如,文本输入处理得到显著改善,特别是在移动设备上。 我们接下来的重点是无障碍功能以及与原生 HTML 元素的互操作性。 

Kotlin/Wasm:现已登陆所有主流浏览器的现代版本

WebAssembly (Wasm) 也已经成熟。 截至 2024 年 12 月 11 日,包括 Safari 在内的所有主流浏览器都已支持 WebAssembly 垃圾回收 (WasmGC)。 这意味着 Kotlin/Wasm 应用程序现在可以在所有现代主流浏览器上运行。

改进 Wasm 开发体验

过去几年,改进 Wasm 目标的开发体验一直是我们的首要任务。 为此,我们: 

在接下来的几个月,我们将更加注重增强稳定性,使在 KMP 项目中以 Wasm 为目标尽可能顺利,并减少未来的破坏性更改。 

总的来说,我们的目标是使这两项技术功能齐全(尽可能接近),并在今年将它们提升到 Beta。

为 Compose Multiplatform 提供兼容模式

如前所述,当您想要一个具有多平台 UI 的应用程序时,我们建议以 Wasm 为目标。 不过,也有一些限制需要考虑。 Wasm 目标依赖于浏览器对 WasmGC 的支持,这可能导致以 Wasm 为目标的 Kotlin 应用程序与缺乏这种支持的旧版本浏览器不兼容 – 参阅此指南了解更多详细信息

为了解决这个问题,我们在 Compose Multiplatform 中引入了兼容模式。

  • 使用 CMP Gradle 插件中的特殊 DSL,您的应用程序将被编译为在现代浏览器中运行应用的 Wasm 版本,充分利用 Wasm 目标的性能。 对于旧版浏览器,JavaScript 版本将自动运行,防止黑屏并保持可用性。

注意:Compose Multiplatform 在渲染引擎端仍然依赖于 WebAssembly。 不过,这部分使用了自 2017 年以来所有主流浏览器中可用的 WebAssembly 功能。

消除 Kotlin/JS 中互操作的大部分限制

目前,Kotlin 与 JavaScript 互操作的方式基于实验性的 @JsExport 注解,该注解具有一些限制,在企业应用程序中使用起来具有挑战性。

我们正在努力消除这些限制,提供更加无缝的 JavaScript 互操作体验。 这项工作完成后,您就可以使用将稳定的 @JsExport 注解标记大多数 Kotlin 声明。

对于无法使用此注解标记声明的情况,例如当您不拥有所用库的源代码但仍想将一些声明导出到 JavaScript 时,多平台 Gradle 插件中会有一个 DSL,它有助于从这些库中导出所有需要的声明。

针对 Kotlin/JS 中最新的 JavaScript 标准

过去,唯一可用的 KMP JS 目标是 ES5,但现在它已经相当过时。 过去两年,我们一直致力于引入对使用现代 JavaScript 功能(如类、生成器和箭头函数)进行编译的实验性支持。

这项新支持在某些情况下减少了捆绑包的大小并提高了性能,因此我们希望将其稳定并添加更多现代功能,例如 BigInt 和动态导入。

我们希望仅以 JavaScript 规范的最新版本为目标,进一步缩减捆绑包的大小并提高性能。 如果您需要以旧版浏览器为目标,我们正在将 Babel 集成到我们的 Gradle 插件中。 它会降低生成的 JavaScript 以兼容旧版浏览器,因此您仍然拥有相同范围的平台支持。

Web 版 Kotlin 的未来

这并不是为 Kotlin 的 Web 目标规划的仅有改进。 多项重要计划已在进行中。

即将到来的是:

  • Wasm 目标中的多线程支持。 为了利用现代多核处理器并提供最佳性能,我们将为 Kotlin/Wasm 编译器制作多线程支持原型。 我们的目标是使 Web 上的多线程开发像在 JVM 上一样简单,将高性能 Web 应用程序开发提升到新水平。
  • Wasm 目标中的逐模块编译。 为了缩短开发往返时间和改进程序模块化,我们正在开发生成多个 WebAssembly 模块的功能。 这种方式通过允许仅重新编译更改的 Kotlin 模块补充了最近引入的增量编译。 它还支持按需加载程序部分,显著改进应用程序启动时间并减少网络负载。 此外,它还是支持以 Wasm 为目标的 Kotlin 应用程序中的插件系统的组成要素。
  • 现代 JavaScript 工具集成。 为了加快编译周期,我们希望在 Gradle 插件中添加一个 Webpack 集成的替代方案。 我们的目标是解耦 Webpack 集成,与任意现代 JavaScript 捆绑程序(如 esbuild、repack、Vite 或 bun)集成。
  • 从 TypeScript 类型自动生成 Kotlin 包装器。 为了消除编写 Kotlin 包装器以使用 JavaScript/TypeScript 库的障碍,我们回到了用于多平台 Gradle 插件的自动 external-declarations 生成器集成上。 对于项目中声明的每个 NPM 依赖项,您将自动获得可以立即使用的 Kotlin 声明,描述库中的可用 API。

总结

基于最近的调查、YouTrack 工单、问题以及来自各个渠道的建议,我们收集了大量宝贵的反馈,并为 Web 端的 Kotlin 制定了明确的方向。 这一切都要感谢大家的支持!

如需分享更多反馈或问题,请加入我们的 Slack 社区。 社区中有您可能感兴趣的各种主题的特定频道,例如 #webassembly、#compose-web、#javascript 和 #multiplatform。

我们感谢您的所有支持,我们将继续提供出色的跨平台 Kotlin 构建体验。

 

本博文英文原作者:

Zalim Bashorov

Zalim Bashorov

https://zal.im

Artem Kobzar

Artem Kobzar

image description

Discover more