Hey guys, I have a question about publishing. TL;D...
# javascript
p
Hey guys, I have a question about publishing. TL;DR: Is there some correct way to publish a klib what uses its own JS modules via
@JsModule
? I'm writing an internal library that has a few JS modules accessed via
file:@JsModule
(the files are tucked into
resources
) . Library's tests work fine, but the app that uses the published library complains about missing those JS modules. The library is published using
maven-publish
and I see that the original JS modules are packed into the resulting klib. So I guess library's JS modules are not being copied into app's dist, which leads to
@JsModule
having no chance to resolve them. Is there a way to make Gradle copy resources from dependencies into the final dist? Or maybe it's doing something like this already, but the paths used by
@JsModule
become invalid due to location change? I've seen that some people publish JS modules to NPM and then make their Kotlin libraries depend on that, thus avoiding the whole issue, but I feel that there should be a more straightforward way.
r
p
Thanks, I'll take a look
The library looks really cool, but due to some configuration shenanigans it didn't work on my project (reflection logic was expecting a different class than the one it was getting). I ended up writing a Gradle task that resolves artifacts from my libraries at build time and extracts JS modules from these artifacts. Said JS modules are then passed to
resources.srcDir()
for
wasmJs
target and everything works. It assumes a few things, so it's not very reusable, but it suits me.
Copy code
val extractWasmResourcesFromAllInternalLibs by tasks.registering(Sync::class) {
    val getConfig = {
        configurations.getByName("wasmJsRuntimeClasspath")
    }
    dependsOn(getConfig())
    val sourcePaths = getConfig()
        .incoming
        .artifactView {
            lenient(true)
            attributes {
                attribute(KotlinPlatformType.attribute, KotlinPlatformType.wasm)
            }
            componentFilter { componentIdentifier ->
                componentIdentifier.displayName.startsWith(/* you group here, e.g. "my.team" */)
            }
        }
        .artifacts
        .resolvedArtifacts
        .map { resolvedArtifactResult ->
            resolvedArtifactResult.map {
                zipTree(it.file)
                    .matching {
                        include(/* pattern for your JS module root folder here, e.g. "src/**" */)
                    }
            }
        }
    from(sourcePaths)
    into(layout.buildDirectory.dir("extracted/jsModules"))
}

kotlin {
    sourceSets {
        val wasmJsMain by getting {
            resources.srcDir(extractWasmResourcesFromAllInternalLibs)
        }    
    }
}
c
Hey, thanks for trying my library!
(reflection logic was expecting a different class than the one it was getting)
Can you send a bit more information? I'd like to fix this if I can
p
@CLOVIS Hey, sure, I'll try to report that issue on GitLab. Though I'm not certain that I'll be able to create an MRE - the project I'm working on is a bit big and it may take some time to strip it down to this state.
c
By "reflection logic", do you mean something on your side, or what the plugin does? The only place where it uses reflection is to access the internals of KGP, so unless you're using an uncommon version of KGP I have no idea what anything else could affect it 🤔
p
Yeah, AFAIR it couldn't get the adhoc component.