Compose Multiplatform+Kotlin/Wasm实现在web端运行自己的老Demo

3,982 阅读5分钟

在前不久结束的KotlinConf 2024上,可以说是高能不断,不仅推出了kotlin2.0,以及谷歌正式支持Kmp,还有一个重磅消息就是Compose Multiplatform(后面统一都简称为CMP) for Web已经正式推出了Alpha版本

001.png

这就说明了我们已经可以将之前运行在Android或者Desktop上的代码移植到web端了,而在web上,就是使用了Kotlin/Wasm这个技术将Kotlin代码编译到Wasm格式,Wasm即WebAssembly,它不依赖任何平台,它会运行在自己的虚拟机上,这才确保了Kotlin代码可以在Web端运行

创建CMP+Kotlin/Wasm项目

虽然目前IDEA已经支持去创建一个KMP项目,但是针对首次接触KMP的人来说,使用这个地址 去创建一个KMP项目会更快而且更具有参考性,打开这个地址,我们给自己的项目启一个Peoject Name和Project ID

002.png

然后在下面的平台列表中,是要去选择这个项目需要支持的平台,我们这个项目只是一个Web端的Demo,所以只勾上Web选项就好

003.png

最后点击下载按钮,就会将这个支持web端的Kmp项目下载到本地,几十kb大小,很快就下好了,在本地将这个压缩包解压后,用IDEA打开,我们就会看到一个完整的KMP项目,不过首次打开的话需要下载一堆插件跟三方库,不过也很快的,也就等个半个多小时就下完了,先看项目结构

004.png

首先看gradle目录底下的libs.versions.toml文件,在这个文件里面可以看到使用的Compose以及Kotlin的版本

0031.png

无论是Compose还是Kotlin都是使用的最新版本,尤其是Kotlin这边,已经是用的新推出的2.0.0版本,然后是代码部分,主要的代码都放在了composeApp这个目录下面,其中commonMain目录存放的是公共的代码,也就是可以在任何平台上运行的,而wasmJsMain就是存放的只会在web端运行的代码,展开wasmJsMain目录,会看到已经有几个示例代码文件在里面

005.png

不过你会奇怪的发现,wasmJsMain里面相关Compose代码都是报红的,这个时候你不用去怀疑你的环境是否出了问题,因为wasmJsMain这个目录只负责将Kotlin代码编译成wasm格式,如果想要去写相关Compose代码,可以在commonMain模块底下进行,这个从composeApp底下的build.gradle.kts文件里面就能看出

006.png

我们看到相关的Compose的依赖都在commonMain底下,而wasmJsMain却没有任何依赖,所以这就是为啥在wasmJsMain底下的Compose代码会报红的原因,不过这些都不会妨碍我们去运行代码,运行代码可以打开gradle侧边栏,双击wasmJsBrowserRun选项,或者在终端执行以下命令

007.png

运行完之后就会在浏览器这边弹出个新页面,页面上展示的就是wasmJsMain底下App.kt的代码

008.png 009.gif

可以从网页元素tab看到,Compose的代码或者里面的那些组件,当被运行到网页里面去的时候,并不会转换成相关Dom元素,而是直接被绘制到了一个画布上面

010.png

运行老Demo

对CMP+Kotlin/Wasm稍微有所了解了之后,现在就看看能否运行之前写过的代码,我找了之前写过的一个彩虹loading,地址在这里commonMain底下新建了一个kotlin的目录,kotlin目录里面新建一个Test.kt的文件

011.png

然后将彩虹loading的代码都拷进去,当然我也可以在wasmJsMain里面做这些事情,但是这样做的话一些不支持的代码比如java代码就不会被编辑器发现,导致最终项目运行失败,不过好在彩虹loading的代码拷进去后并没有出现代码飘红的现象发生,最后将App.kt里面点击按钮后的逻辑换成展示我们的彩虹loading

012.png

运行后的结果如下

013.gif

很成功的将之前写过的demo无修改的一步移植到了web端上,这个就是wasm厉害的地方

总结

一次简单的CMP+Kotlin/Wasm尝试,让我们清楚Kotlin已经具备在web端运行代码的能力,不过相对于传统的web开发,使用Kotlin/Wasm开发web应用依然存在一些不足的地方,比如不支持热加载,每次必须重新运行,新的代码才会生效,又比如页面上只有一个Canvas,如果想要调整某个组件的视觉效果,我们就没法通过在元素内定位到该组件,然后调整它的css样式来查看具体效果,只能通过更改代码的方式来调整,不过话又说回来,这些其实有点钻牛角尖了,对于目前CMP来将,已经具备一套代码多端运行的能力,传统的在单个平台上调试代码的方式可能已经不适用于这样的跨平台开发,我们需要关注的仅仅是自己的代码公共逻辑是什么,以及如何去适配各个平台带来的差异性