Kotlin 1.3 - How to access external javascript library from jsMain

I am trying to create a kotlin Multiplatform library which can later convert into java and javascript using IDEA 2019.3, kotlin 1.3 .

In the jsMain I am trying to add some logic to manipulate Date and I decided to use joda js (https://mvnrepository.com/artifact/org.webjars.npm/js-joda/1.10.1) and in the gradle file I added following block

js().compilations.main.defaultSourceSet {
    dependencies {
        implementation kotlin('stdlib-js')
        implementation 'org.webjars.npm:js-joda:1.10.1'
    }
    kotlin.srcDir('src/jsMain')
}

I can see that gradle downloaded those files but in the jsMain I could not access joda js library. I know that question is bit abstract but I do not know how to ask in anyotherway.

Can someone has any idea why it’s not available in the jsMain?

You must bundle external libraries yourself. How that works depends on your module / bundling setup. See the official documentation for one example of how it can work.

Thanks for your reply. Could you please share the link of that example here.

https://kotlinlang.org/docs/tutorials/javascript/getting-started-gradle/getting-started-with-gradle.html

See the section starting with “By default, Gradle does not expand the JARs in the build process, so we need to add an additional step in our build to do so:”.

@fatjoe79
Please see my build.gradle file
plugins {
id ‘org.jetbrains.kotlin.multiplatform’ version ‘1.3.61’
}
repositories {
mavenCentral()
}
group ‘com.example’
version ‘0.0.1’

apply plugin: 'maven-publish'

kotlin {
    jvm()
    js {
        browser {
        }
        nodejs {
        }
    }
    // For ARM, should be changed to iosArm32 or iosArm64
    // For Linux, should be changed to e.g. linuxX64
    // For MacOS, should be changed to e.g. macosX64
    // For Windows, should be changed to e.g. mingwX64
    macosX64("macos")
    sourceSets {
        commonMain {
            dependencies {
                implementation kotlin('stdlib-common')
            }
        }
        commonTest {
            dependencies {
                implementation kotlin('test-common')
                implementation kotlin('test-annotations-common')
            }
        }
        jvmMain {
            dependencies {
                implementation kotlin('stdlib-jdk8')
            }
        }
        jvmTest {
            dependencies {
                implementation kotlin('test')
                implementation kotlin('test-junit')
            }
        }
        jsMain {
            dependencies {
                implementation kotlin('stdlib-js')
                implementation 'org.webjars.npm:js-joda:1.10.1'
            }
            task assembleWeb(type: Sync) {
                configurations.compile.each { File file ->
                    from(zipTree(file.absolutePath), {
                        includeEmptyDirs = false
                        include { fileTreeElement ->
                            def path = fileTreeElement.path
                            path.endsWith(".js") && (path.startsWith("META-INF/resources/") ||
                                    !path.startsWith("META-INF/"))
                        }
                    })
                }
                from compileKotlin2Js.destinationDir
                into "${projectDir}/web"

                dependsOn classes
            }

            assemble.dependsOn assembleWeb
        }
        jsTest {
            dependencies {
                implementation kotlin('test-js')
            }
        }
        macosMain {
        }
        macosTest {
        }
    }
}

While building it’s throwing error “Could not get unknown property ‘compile’ for configuration container of type org.gradle.api.internal.artifacts.configurations.DefaultConfigurationContainer.” Do you have any comment about this issue

I moved the task from jsMain to js() and it’s compiles fine but still I can not import LocalDate in js.
js() {
task assembleWeb(type: Sync) {
configurations.compile.each { File file →
from(zipTree(file.absolutePath), {
includeEmptyDirs = false
include { fileTreeElement →
def path = fileTreeElement.path
path.endsWith(“.js”) && (path.startsWith(“META-INF/resources/”) ||
!path.startsWith(“META-INF/”))
}
})
}
from compileKotlinJs.destinationDir
into “${projectDir}/web”
dependsOn classes

        }

        assemble.dependsOn assembleWeb
    }

@Alexey.Belkov Could you please share your opinion

The easiest way to achieve your goal is by using Dukat.
So all you should do is to add kotlin.js.experimental.generateKotlinExternals=true into gradle.properties. Dukat will convert TypeScript definition files to Kotlin declarations.

build.gradle

plugins {
    id "org.jetbrains.kotlin.multiplatform" version "1.3.61"
}
repositories {
    mavenCentral()
}
group "com.example"
version "0.0.1"

apply plugin: 'maven-publish'

kotlin {
    jvm()
    js {
        browser {
        }
        nodejs {
        }
    }
    // For ARM, should be changed to iosArm32 or iosArm64
    // For Linux, should be changed to e.g. linuxX64
    // For MacOS, should be changed to e.g. macosX64
    // For Windows, should be changed to e.g. mingwX64
    macosX64("macos")
    sourceSets {
        commonMain {
            dependencies {
                implementation kotlin('stdlib-common')
            }
        }
        commonTest {
            dependencies {
                implementation kotlin('test-common')
                implementation kotlin('test-annotations-common')
            }
        }
        jvmMain {
            dependencies {
                implementation kotlin('stdlib-jdk8')
            }
        }
        jvmTest {
            dependencies {
                implementation kotlin('test')
                implementation kotlin('test-junit')
            }
        }
        jsMain {
            dependencies {
                implementation kotlin('stdlib-js')
                implementation npm("js-joda", "1.10.1")
            }
        }
        jsTest {
            dependencies {
                implementation kotlin('test-js')
            }
        }
        macosMain {
        }
        macosTest {
        }
    }
}

gradle.properties

kotlin.code.style=official
kotlin.js.experimental.generateKotlinExternals=true

jsMain/kotlin/Main.kt

import JSJoda.DayOfWeek
import JSJoda.LocalDate

fun main() {
    DayOfWeek()
    LocalDate
}
2 Likes