Skip to content

Conversation

Schahen
Copy link
Collaborator

@Schahen Schahen commented Jul 24, 2025

Testing

Clone https://github.com/Schahen/ComposeWebApp and run

 ./gradlew  :composeApp: composeCompatibilityBrowserDistribution

Release Notes

Features - Web

  • Introduce composeCompatibilityBrowserDistribution task. This task combines two prod distributions - for js and for wasm in such way so that if modern required features are not supported by the consumer browser, application switch to js mode.

@Schahen Schahen requested review from eymar and terrakok July 24, 2025 08:20
@igordmn
Copy link
Collaborator

igordmn commented Jul 24, 2025

Just in case, if it is not already planned, please, fix the PR description before merging (better also before review, if not agreed beforehand):

  • Describe the changes
  • Release notes should describe a user-faced change, otherwise it is N/A

Comment on lines 71 to 72
val jsTargetModuleName = jsDistTask.outputModuleName
val wasmTargetModuleName = wasmDistTask.outputModuleName
Copy link
Member

@eymar eymar Jul 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do both outputModuleName have some default value when a user doesn't explicitly specify it in the DSL?

When would this be false?

onlyIf {
            jsTargetModuleName != null && wasmTargetModuleName != null
        }

}
}

private fun Project.introduceComposeWebCompatibilityTask(targets: Collection<KotlinJsIrTarget>) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are some gradle plugin tests in the project.

Would you like to add some tests?
For example:

  • a task is created when the condition match and it's not created otherwise
  • Run the task and check the output directory exists. And the output directory contains the must-have files (index.html, .js file, wasm file, etc)

Copy link
Member

@terrakok terrakok left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's add a test with a custom target name wasmJs("myStrangeTarget")

wasmDistFiles = tasks.named("wasmJsBrowserDistribution").get().outputs.files
}

internal fun Project.configureWebCompatibility() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's add a description what's going here

}

kotlin {
js(IR) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I know, we already don't need IR here


kotlin {
js(IR) {
outputModuleName.set("composeApp")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we want to test a custom name here, then you need a different name, because "composeApp" is a name of the module already


@OptIn(ExperimentalWasmDsl::class)
wasmJs {
outputModuleName.set("composeApp")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what will happen if there is a different name?


copySpec.from(jsDistFiles) {
copySpec.rename { name ->
val moduleName = jsOutputName.get()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: Since jsOutputName and wasmOutputName are annotated with @Optional, calling .get() directly could throw an IllegalStateException if they're unset.

Would it make sense to either:

  • Use orNull ?: return@rename name here, or
  • Remove @Optional if these properties are guaranteed to be set by the time the task runs?

This keeps the annotation and implementation consistent 🙂

Copy link
Member

@eymar eymar Jul 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the task is not expected to run when either of them is not set. There is onlyIf { ... } checking it.

So yes, they seem to be not Optional

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exactly, that was my point. Since the properties aren't actually optional, removing @Optional would make it clearer 👍

Comment on lines 119 to 125
outputDir.file("${jsOutputName.get()}.js").get().asFile.writeText(
fallbackResolverCode
)

outputDir.file("${wasmOutputName.get()}.js").get().asFile.writeText(
fallbackResolverCode
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

val outputDir = outputDir.get().asFile
File(outputDir, jsAppFileName).writeText(fallbackResolverCode)
File(outputDir, wasmAppFileName).writeText(fallbackResolverCode)

Comment on lines 149 to 152
if (!hasBothDistributions) {
logger.lifecycle("Task ${this.name} skipped: no js and wasm distributions found, both are required for compatibility")
} else if (!hasBothOutputs) {
logger.lifecycle("Task ${this.name} skipped: no js and wasm output names specified")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add tests for this logic too, please

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can add a log check into one of existed tests for other cases with only one of the web targets

@Schahen Schahen merged commit 64200ba into master Jul 31, 2025
15 checks passed
@Schahen Schahen deleted the sh/introduce_web_dist_task branch July 31, 2025 11:52
henryqwe pushed a commit to henryqwe/compose-multiplatform that referenced this pull request Oct 1, 2025
## Testing
Clone https://github.com/Schahen/ComposeWebApp and run 
```
 ./gradlew  :composeApp: composeCompatibilityBrowserDistribution
```

## Release Notes
### Features - Web
- Introduce composeCompatibilityBrowserDistribution task. This task
combines two prod distributions - for js and for wasm in such way so
that if modern require features are not supported by the consumer
browser, application switch to js mode.

---------

Co-authored-by: Oleksandr Karpovich <[email protected]>
Co-authored-by: Konstantin Tskhovrebov <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants