the state of kotlin js sebastian aigner
play

THE STATE OF KOTLIN/JS SEBASTIAN AIGNER @TrueSebi Copenhagen - PowerPoint PPT Presentation

THE STATE OF KOTLIN/JS SEBASTIAN AIGNER @TrueSebi Copenhagen Denmark About me Hi, Im Sebastian! Developer Advocate at JetBrains Focus on Kotlin and Fig. 1: me Education twitter.com/TrueSebi Kotlin & the Web


  1. THE STATE OF KOTLIN/JS SEBASTIAN AIGNER @TrueSebi Copenhagen Denmark

  2. About me • Hi, I‘m Sebastian! • Developer Advocate at JetBrains • Focus on Kotlin and Fig. 1: me Education twitter.com/TrueSebi • Kotlin & the Web github.com/SebastianAigner sebastian.aigner@jetbrains.com

  3. 1. SOME MOTIVATION Why is Kotlin/JS exciting? Who can benefit the most from K/JS?

  4. Why Kotlin/JS? • Use programming paradigms you’re familiar with! • Prototype quickly! • Explore the frontend world! • Unlock multiplatform benefits!

  5. Unlock the power of code sharing! • Benefits from multiplatform development – Code Sharing – Model Sharing – Knowledge sharing • Ecosystem sharing!

  6. Today’s menu • Functionality that is available now / soon™ • The next planned steps for the Kotlin/JS target • A long-term-ish outlook

  7. 2. WHERE WE ARE AT What is currently available and will be available shortly.

  8. Unified plugin experience ? Kotlin/Multiplatform Plugin K o t l i n F r o n t e n d P l u g i n kotlin2js Plugin kotlin.js Plugin Create-React-Kotlin-App IDEA JS

  9. Unified plugin experience ! Kotlin/Multiplatform Plugin kotlin.js Plugin kotlin2js Plugin Kotlin Frontend Plugin Will be deprecated

  10. Kotlin/Multiplatform Moving plugins kotlin.js Plugin From kotlin2js / frontend plugin to kotlin.js – Same features available – Ever-improving documentation From kotlin.js plugin to multiplatform – Minimal changes required – Future-proof DSL for JS target(s) already!

  11. plugins { kotlin ( "multiplatform" ) version "1.3.61" } Future-proof DSL group = "org.example" version = "1.0-SNAPSHOT" repositories { mavenCentral() } plugins { id( "org.jetbrains.kotlin.js" ) version "1.3.61" kotlin { } js { group = "org.example" browser { testTask { version = "1.0-SNAPSHOT" useKarma { useChromeHeadless() repositories { } mavenCentral() } } } dependencies { } sourceSets { implementation ( kotlin ( "stdlib-js" )) val jsMain by getting { } dependencies { implementation(kotlin( "stdlib-js" )) kotlin { target { } } browser { val commonMain by getting { testTask { useKarma { dependencies { implementation(kotlin( "stdlib-common" )) useChromeHeadless() } } } } val commonTest by getting { } } dependencies { implementation(kotlin( "test-common" )) } implementation(kotlin( "test-annotations-common" )) } } } }

  12. Start your new projects with the kotlin.js plugin …or do MPP!

  13. Embracing both worlds? >1M! package.json

  14. Configuring builds Webpack – without the hassle! • Sensible defaults • Gradle DSL • Full control • Fully managed

  15. Fully managed No manual environment management necessary • Plugin-managed yarn distribution • Auto-generated configuration files – package.json package.json – webpack.config.js

  16. package.json build.gradle.kts kotlin { { target .nodejs() "main" : "kotlin/playgroundkts.js" , sourceSets . main { "devDependencies" : {}, dependencies { "dependencies" : { implementation(kotlin( "stdlib-js" )) "kotlin" : "1.3.61" , implementation(npm( "uuid" , "3.3.3" )) "kotlin-test-js-runner" : "1.3.61" , implementation(npm( "chalk" )) "kotlin-test" : "1.3.61" , } "uuid" : "3.3.3" , } "chalk" : "*" } }, "peerDependencies" : {}, "optionalDependencies" : {}, "bundledDependencies" : [], "name" : "playgroundkts" , "version" : "1.0.0-SNAPSHOT" }

  17. Continuous Gradle Builds FS watcher Gradle Task Kotlin Compiler Webpack Dev Server Chrome Browser ./gradlew -. continous run

  18. From IntelliJ IDEA

  19. Source maps • Readable stack traces • Browser dev tools superpowers!

  20. Source maps

  21. Source maps

  22. Source maps

  23. Testing – Test Runners & Browsers kotlin . target .browser { testTask { useKarma { useIe() useFirefox() useChrome() useChromeHeadless() useOpera() } } }

  24. Testing – Gradle Test Reports

  25. Testing – Gradle Test Reports

  26. Interoperating with the platform

  27. Browser APIs • Generated from W3C standards • Statically typed by default, dynamic as fallback Official Docs!

  28. Example using browser API fun main() { val canvas = document .getElementById("myCanvas") as HTMLCanvasElement val ctx = canvas.getContext("2d") as CanvasRenderingContext2D with (ctx) { repeat (30) { beginPath() fillStyle = listOf ("red", "green", "blue"). random () rect( randomCoordinate (), randomCoordinate (), 20.0, 20.0) fill() closePath() } } } fun randomCoordinate() = Random.nextDouble(0.0, 200.0)

  29. Showing off 1 5 8 L i n e s o f K o t l i n / J S !

  30. A separated browser API • Currently: browser API as part of the standard library • In the future: separate artifact, … a separate release cycles n d f o r t h e N o d e . j s A P I t o o !

  31. N Libraries from Gradle o n e e d f o r N P M p u b l i s h e d l i b s ! Bring the Kotlin Ecosystem to JS! kx.serialization Coroutines Ktor Clients . . . implementation( "io.ktor:ktor-client-core:$ ktor_version " ) implementation( "io.ktor:ktor-client-js:$ ktor_version " ) plugins { //. . . id( "kotlinx-serialization" ) version "1.3.60" } implementation( "org.jetbrains.kotlinx:kotlinx-serialization-runtime-js:0.13.0" )

  32. JS Frameworks Bring the JS ecosystem to Kotlin!

  33. Packages from NPM sourceSets. main { dependencies { implementation(npm("react-minimal-pie-chart")) implementation(npm("react-spinkit")) } }

  34. Bridging the worlds Dynamic vs static typing @JsModule("react-spinkit") @JsNonModule external val Spinner : RClass<dynamic> Spinner { attrs.asDynamic().name = spinnerNames.random() attrs.asDynamic().color = colors.random() }

  35. The proper way @file:JsModule("react-minimal-pie-chart") @file:JsNonModule import react.RClass import react.RProps external interface PieChartProps: RProps { var data: Array<PiePoint> var lineWidth: Int var paddingAngle: Int var rounded: Boolean var label: Boolean var animate: Boolean var labelStyle: dynamic var labelPosition: Int } @JsName("default") external val PieChart : RClass<PieChartProps> class PiePoint(val title: String, val value: Int, val color: String)

  36. It can get confusing… RequireJS import AMD UMD @JsNonModule @JsModule

  37. Standardized type declarations • TypeScript declarations for TS packages • d.ts files for JS packages via DefinitelyTyped

  38. Automatic declaration generation • Convert TypeScript definitions to Kotlin automatically • Gradle integration (same dependency notation!) • Currently in experimental stage • Expect bugs, give feedback! P o w e r i n g B r o w s e r & N o d e !

  39. declare function leftPad ( implementation(npm( "left-pad" , "1.3.0" )) str: string | number , len: number , ch?: string | number warning workspace-aggregator ): string ; > kotlin-js-demo-1.3.50 > left-pad@1.3.0: use declare namespace leftPad { } String.prototype.padStart() export = leftPad ; //... all external, all @JsModule("left-pad") fun leftPad(str: String, len: Number, ch: String? = definedExternally ): String fun leftPad(str: String, len: Number, ch: Number? = definedExternally ): String fun leftPad(str: Number, len: Number, ch: String? = definedExternally ): String fun leftPad(str: Number, len: Number, ch: Number? = definedExternally ): String fun leftPad(str: String, len: Number): String fun leftPad(str: Number, len: Number): String E v e n w i println ( leftPad ( "Yay Kotlin!" , 50)) t h u n i o n t y p e s !

  40. 3. WHERE WE ARE GOING What changes await Kotlin/JS in the near future.

  41. Dukat keeps evolving • Support for more packages • Prioritized by the community

  42. High level: new IR backend • Kotlin I ntermediate R epresentation • Future compiler for JS (and other) targets • Will make your life better!

  43. Expect benefits

  44. Multi-platform compiler plugins • Write platform agnostic plugins • Consume platform agnostic plugins • Uses reliable public API

  45. Optimizations • More aggressive optimizations • Code size – Dead code eliminiation – No need to ship a full stdlib anymore!

  46. Some numbers: kotlinx.coroutines w/ IR Current Backend IR Backend 3.9 MiB 1.1 MiB After Compilation 713 KiB 430 KiB After JS DCE 329 KiB 184 KiB After Bundle 74 KiB 40 KiB After ZIP Code size for example project using coroutines Co IR IR Ba Backend, IR IR DCE, Go Google le Clo losure Comp mpile iler: 116 KiB , ed 30 KiB , zipped

  47. Incremental compilation • Compile at least as fast as with old BE • Compile only parts a ff ected by changes • Even faster page-reloads for continuous builds

Recommend


More recommend