Skip to content

Commit d5db097

Browse files
Merge pull request JetBrains#121 from JetBrains/compose-1.6.10-release
feat: Compose for web in alpha
2 parents 0ffde43 + c079842 commit d5db097

14 files changed

+148
-20
lines changed
Loading
Loading
21.7 KB
Loading
Loading
Loading
37.7 KB
Loading
Loading
Loading

topics/compose-onboard/compose-multiplatform-create-first-app.md

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ To begin, create a sample project. This is best achieved with the Kotlin Multipl
1919

2020
1. Open the [Kotlin Multiplatform wizard](https://kmp.jetbrains.com).
2121
2. On the **New project** tab, change the project name to "ComposeDemo" and the project ID to "kmp.project.demo".
22-
3. Select the **Android** and **Desktop** options.
22+
3. Select the **Android**, **Desktop**, and **Web** options.
2323
4. If you're using a Mac, select **iOS** as well. Make sure that the **Share UI** option is selected.
2424
5. Click the **Download** button and unpack the resulting archive.
2525

@@ -42,25 +42,27 @@ To begin, create a sample project. This is best achieved with the Kotlin Multipl
4242

4343
The project contains two modules:
4444

45-
* _composeApp_ is a Kotlin module that contains the logic shared among the Android, desktop, and iOS applications – the code
45+
* _composeApp_ is a Kotlin module that contains the logic shared among the Android, desktop, iOS, and web applications – the code
4646
you use for all the platforms. It uses [Gradle](https://kotlinlang.org/docs/gradle.html) as the build system that helps
4747
you automate your build process.
4848
* _iosApp_ is an Xcode project that builds into an iOS application. It depends on and uses the shared module as an iOS
4949
framework.
5050

5151
![Compose Multiplatform project structure](compose-project-structure.png){width=350}
5252

53-
The **composeApp** module consists of four source sets: `androidMain`, `commonMain`, `desktopMain`, and `iosMain`.
53+
The **composeApp** module consists of the following source sets: `androidMain`, `commonMain`, `desktopMain`, `iosMain`, and `wasmJsMain`.
5454
A _source set_ is a Gradle concept for a number of files logically grouped together, where each group has its own
5555
dependencies. In Kotlin Multiplatform, different source sets can target different platforms.
5656

5757
The `commonMain` source set uses the common Kotlin code, and platform source sets use Kotlin code specific to each
58-
target. Kotlin/JVM is used for `androidMain` and `desktopMain`. Kotlin/Native is used for `iosMain`.
58+
target. Kotlin/JVM is used for `androidMain` and `desktopMain`. Kotlin/Native is used for `iosMain`. On the other hand, Kotlin/Wasm is
59+
used for `wasmJsMain`.
5960

6061
When the shared module is built into an Android library, common Kotlin code gets treated as Kotlin/JVM. When it is built
61-
into an iOS framework, common Kotlin code gets treated as Kotlin/Native:
62+
into an iOS framework, common Kotlin code gets treated as Kotlin/Native. When the shared module is built into a web app, common
63+
Kotlin code gets treated as Kotlin/Wasm.
6264

63-
![Common Kotlin, Kotlin/JVM, and Kotlin/Native](modules-structure.png){width=700}
65+
![Common Kotlin, Kotlin/JVM, and Kotlin/Native](module-structure.png){width=700}
6466

6567
In general, write your implementation as common code whenever possible instead of duplicating functionality
6668
in platform-specific source sets.
@@ -74,7 +76,7 @@ Let's run the application and then examine the code in depth.
7476

7577
## Run your application
7678

77-
You can run the application on Android, iOS, and desktop. You don't have to run the applications in any particular
79+
You can run the application on Android, iOS, desktop, and web. You don't have to run the applications in any particular
7880
order, so start with whichever platform you are most familiar with.
7981

8082
> You don't need to use the Gradle build task. In a multiplatform application, this will build debug and release versions
@@ -203,7 +205,7 @@ in Android Studio and select your device in the **Execution target** list. Run t
203205

204206
You can create a run configuration for running the desktop application as follows:
205207

206-
1. Select the **Run | Edit Configurations** menu item.
208+
1. Select **Run | Edit Configurations** from the main menu.
207209
2. Click the plus button and choose **Gradle** from the dropdown list.
208210
3. In the **Tasks and arguments** field, paste this command:
209211
```shell
@@ -215,6 +217,36 @@ Now, you can use this configuration to run the desktop app:
215217

216218
![Run the Compose Multiplatform app on desktop](compose-run-desktop-temp.png){width=350}
217219

220+
### Run your web application
221+
222+
Create a run configuration to run the web application:
223+
224+
1. Select **Run | Edit Configurations** from the main menu.
225+
2. Click the plus button and choose **Gradle** from the dropdown list.
226+
3. In the **Tasks and arguments** field, paste this command:
227+
228+
```shell
229+
wasmJsBrowserRun -t --quiet
230+
```
231+
232+
4. Click **OK**.
233+
234+
Now, you can use this configuration to run the web app:
235+
236+
![Run the Compose Multiplatform app on desktop](compose-run-web.png){width=350}
237+
238+
The web application opens automatically in your browser. Alternatively, you can type the following URL in your browser when the run is finished:
239+
240+
```shell
241+
http://localhost:8080/
242+
```
243+
> The port number can vary because the 8080 port may be unavailable. You can find the actual port number in the
244+
> Gradle build console.
245+
>
246+
{type="tip"}
247+
248+
![Compose web application](first-compose-project-on-web.png){width=550}
249+
218250
## Next step
219251

220252
In the next part of the tutorial, you'll learn how to implement composable functions and launch your application on each

topics/compose-onboard/compose-multiplatform-explore-composables.md

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,16 @@ Take a look at the `App()` function in `composeApp/src/commonMain/kotlin`:
2020
```kotlin
2121
@OptIn(ExperimentalResourceApi::class)
2222
@Composable
23+
@Preview
2324
fun App() {
2425
MaterialTheme {
2526
var showContent by remember { mutableStateOf(false) }
26-
val greeting = remember { Greeting().greet() }
2727
Column(Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) {
2828
Button(onClick = { showContent = !showContent }) {
2929
Text("Click me!")
3030
}
3131
AnimatedVisibility(showContent) {
32+
val greeting = remember { Greeting().greet() }
3233
Column(Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) {
3334
Image(painterResource(Res.drawable.compose_multiplatform), null)
3435
Text("Compose: $greeting")
@@ -84,8 +85,8 @@ The changes occur when the image is shown or hidden because the parent `Animated
8485

8586
## Launching UI on different platforms
8687

87-
The `App()` function execution is different for each platform. On Android, it's managed by an activity, on iOS by a view
88-
controller, and on desktop by a window. Let's examine each of them.
88+
The `App()` function execution is different for each platform. On Android, it's managed by an activity; on iOS, by a view
89+
controller; on the desktop, by a window; and on the web, by a container. Let's examine each of them.
8990

9091
### On Android
9192

@@ -119,7 +120,7 @@ role as an activity on Android. Notice that both the iOS and Android types simpl
119120

120121
### On desktop
121122

122-
For desktop, look again at the `main()` function in `composeApp/src/desktopMain/kotlin`:
123+
For desktop, look at the `main()` function in `composeApp/src/desktopMain/kotlin`:
123124

124125
```kotlin
125126
fun main() = application {
@@ -137,6 +138,34 @@ fun main() = application {
137138
Currently, the `App` function doesn't declare any parameters. In a larger application, you typically pass parameters to
138139
platform-specific dependencies. These dependencies could be created by hand or using a dependency injection library.
139140

141+
### On web
142+
143+
For web, look again at the `main()` function in `composeApp/src/wasmJsMain/kotlin`. The function has two variants:
144+
145+
```kotlin
146+
// First variant:
147+
@OptIn(ExperimentalComposeUiApi::class)
148+
fun main() {
149+
ComposeViewport(viewportContainer = document.body!!) { App() }
150+
}
151+
152+
153+
// Second variant:
154+
@OptIn(ExperimentalComposeUiApi::class)
155+
fun main() {
156+
ComposeViewport(viewportContainerId = "composeApplication") { App() }
157+
}
158+
```
159+
160+
* In the first variant, the web app is inserted into the container assigned to the `viewportContainer` parameter.
161+
The `viewportContainer` parameter stores the entire body of the HTML document. The entire document's body works as the container for rendering the UI.
162+
* In the second variant, the web app is inserted into a container added in your `index.html` file, where the UI is rendered.
163+
The `composeApplication` element corresponds to the ID of this container and is assigned to the `viewportContainerId` parameter.
164+
* In both variants, the `@OptIn(ExperimentalComposeUiApi::class)` annotation tells the compiler that you are using an API marked as
165+
experimental and may change in future releases.
166+
* The `ComposeViewport()` function sets up the Compose environment for the application.
167+
* The `App()` function is responsible for building the UI components of your application using Jetpack Compose.
168+
140169
## Next step
141170

142171
In the next part of the tutorial, you'll add a dependency to the project and modify the user interface.

topics/compose-onboard/compose-multiplatform-modify-project.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,9 @@ and desktop:
100100
101101
![First Compose Multiplatform app on desktop](first-compose-project-on-desktop-2.png){width=400}
102102
103-
> You can find this state of the project in our [GitHub repository](https://github.com/kotlin-hands-on/get-started-with-cm/tree/main/ComposeDemoStage1).
103+
<!-- > You can find this state of the project in our [GitHub repository](https://github.com/kotlin-hands-on/get-started-with-cm/tree/main/ComposeDemoStage1).
104104
>
105-
{type="tip"}
105+
{type="tip"} -->
106106
107107
## Next step
108108

topics/compose-onboard/compose-multiplatform-new-project.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -410,9 +410,9 @@ code to load and display them:
410410

411411
![The country flags in the Compose Multiplatform app on desktop](first-compose-project-on-desktop-9.png){width=350}
412412

413-
> You can find this state of the project in our [GitHub repository](https://github.com/kotlin-hands-on/get-started-with-cm/tree/main/ComposeDemoStage4).
413+
<!-- > You can find this state of the project in our [GitHub repository](https://github.com/kotlin-hands-on/get-started-with-cm/tree/main/ComposeDemoStage4).
414414
>
415-
{type="tip"}
415+
{type="tip"} -->
416416

417417
## What's next
418418

topics/compose-onboard/compose-multiplatform-setup.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,17 @@ We recommend that you install the latest stable versions for compatibility and b
5757
<p>To update the plugin, on the Android Studio welcome screen, select <strong>Plugins | Installed</strong>. Click <strong>Update</strong> next to Kotlin. You can also check the Kotlin version in <strong>Tools | Kotlin | Configure Kotlin Plugin Updates</strong>.</p>
5858
<p>The Kotlin plugin should be compatible with the Kotlin Multiplatform Mobile plugin. Refer to the <a href="https://kotlinlang.org/docs/multiplatform-plugin-releases.html#release-details">compatibility table</a>.</p></td>
5959
</tr>
60+
<tr>
61+
<td>Browsers</td>
62+
<td>
63+
<p>To run multiplatform applications in a browser, you need a browser supporting the <a href="https://github.com/WebAssembly/gc">Wasm Garbage Collection (GC) feature</a>.</p>
64+
<list>
65+
<li><strong>Chrome and Chromium-based:</strong> works by default starting from version 119.</li>
66+
<li><strong>Firefox:</strong> works by default starting from version 120.</li>
67+
<li><strong>Safari/WebKit:</strong> Wasm GC support is currently under <a href="https://bugs.webkit.org/show_bug.cgi?id=247394">active development</a>.</li>
68+
</list>
69+
</td>
70+
</tr>
6071
</table>
6172

6273
## Check your environment
@@ -143,6 +154,9 @@ To make sure everything works as expected, install and run the KDoctor tool:
143154
<li><code>command not found: java</code><a href="https://www.oracle.com/java/technologies/javase-downloads.html">install Java</a>.</li>
144155
</list>
145156
</def>
157+
<def title="Browsers">
158+
Make sure that your browser version supports the new <a href="https://github.com/WebAssembly/gc">WasmGC</a> by default. If you are working with older browser versions, <a href="https://kotlinlang.org/docs/wasm-troubleshooting.html#browser-versions">configure the environment</a>.
159+
</def>
146160
<def title="Still having trouble?">
147161
<p>Share your problems with the team by <a href="https://kotl.in/issue">creating a YouTrack issue</a>.</p>
148162
<p>For a smoother multiplatform experience, you can also try <a href="https://www.jetbrains.com/help/kotlin-multiplatform-dev/fleet.html">JetBrains Fleet</a>: it integrates with Compose Multiplatform and allows writing Swift code without switching to Xcode, with less IDE juggling overall.</p>

topics/multiplatform-publish-apps.md

Lines changed: 57 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
[//]: # (title: Publish your application)
22

3-
Once your mobile apps are ready for release, it's time to deliver them to the users by publishing them in app stores.
4-
Multiple stores are available for each platform. However, in this article we'll focus on the official ones:
5-
[Google Play Store](https://play.google.com/store) and [Apple App Store](https://www.apple.com/ios/app-store/).
3+
Once your apps are ready for release, it's time to deliver them to the users by publishing them.
4+
5+
For mobile apps, multiple stores are available for each platform. However, in this article, we'll focus on the official ones:
6+
[Google Play Store](https://play.google.com/store) and [Apple App Store](https://www.apple.com/ios/app-store/). For web apps, we'll use [GitHub pages](https://pages.github.com/).
7+
68
You'll learn how to prepare Kotlin Multiplatform applications for publishing, and we'll highlight
79
the parts of this process that deserve special attention.
810

@@ -77,4 +79,55 @@ file. This helps you analyze crashes that happen in the shared module's code.
7779

7880
When an iOS app is rebuilt from bitcode, its `dSYM` file becomes invalid. For such cases, you can compile the shared module
7981
to a static framework that stores the debug information inside itself. For instructions on setting up crash report
80-
symbolication in binaries produced from Kotlin modules, see the [Kotlin/Native documentation](https://kotlinlang.org/docs/native-ios-symbolication.html).
82+
symbolication in binaries produced from Kotlin modules, see the [Kotlin/Native documentation](https://kotlinlang.org/docs/native-ios-symbolication.html).
83+
84+
## Web app
85+
86+
To publish your web application, create the artifacts containing the compiled files
87+
and resources that make up your application. These artifacts are necessary to deploy your application to a web hosting platform like GitHub Pages.
88+
89+
### Generate artifacts
90+
91+
Create a run configuration for running the **wasmJsBrowserDistribution** task:
92+
93+
1. Select the **Run | Edit Configurations** menu item.
94+
2. Click the plus button and choose **Gradle** from the dropdown list.
95+
3. In the **Tasks and arguments** field, paste this command:
96+
97+
```shell
98+
wasmJsBrowserDistribution
99+
```
100+
101+
4. Click **OK**.
102+
103+
Now, you can use this configuration to run the task:
104+
105+
![Run the Wasm distribution task](compose-run-wasm-distribution-task.png){width=350}
106+
107+
Once the task completes, you can find the generated artifacts in the `composeApp/build/dist/wasmJs/productionExecutable`
108+
directory:
109+
110+
![Artifacts directory](compose-web-artifacts.png){width=600}
111+
112+
### Publish your application on GitHub Pages
113+
114+
With the artifacts ready, you can deploy your application on the web hosting platform:
115+
116+
1. Copy the contents of your `productionExecutable` directory into the repository where you want to create a site.
117+
2. Follow GitHub's instructions for [creating your site](https://docs.github.com/en/pages/getting-started-with-github-pages/creating-a-github-pages-site#creating-your-site).
118+
119+
> It can take up to 10 minutes for changes to your site to publish after you push the changes to GitHub.
120+
>
121+
{type="note"}
122+
123+
3. In a browser, navigate to your GitHub pages domain.
124+
125+
![Navigate to GitHub pages](publish-your-application-on-web.png){width=650}
126+
127+
Congratulations! You have published your artifacts on GitHub pages.
128+
129+
### Debug your web application
130+
131+
You can debug your web application in your browser out of the box, without additional configurations. To learn how to debug
132+
in the browser, see the [Debug in your browser](https://kotlinlang.org/docs/wasm-debugging.html#debug-in-your-browser)
133+
guide in Kotlin docs.

0 commit comments

Comments
 (0)