Search code examples
gradlewebpackkotlinkotlin-frontend

Creating a Kotlin React App using gradle


I have been looking forward on how to create a kotlin-react-app using gradle (I am aware with the create-kotlin-react-app CLI tool, which doesn't use radle) and i couldn't get any sources to point me through. I have stumbled accross the kotlin frontend plugin (It works) and the npm and webpack plugin, but I couldnt configure them to run/create me a kotlin-react-project. I not an expert in configuring webpack so it probably even harder for me.

Initial Intentions

I intend to create a multiplatform project (yes, the kotlin experiental packed up in IntelliJ)

Alternative Approach

when I failed, I choose to go with this approach.

  1. Write my code using kotlin multiplatform plugin
  2. Compile it into a jar
  3. Add it as a library into the create-react-kotlin-app i'd create
  4. Run and wait for the magic to happen (it ddnt) Turns out, some how the preconfigured webpack wasn't compiling because it wasn't available during compile time. but the IDE worked well and even provided code compleion

Can someone please point me in a direction?


Solution

  • Building a react app using gradle is easy when using the kotlin frontend plugin. In IntelliJ,follow these steps

    New module > gradle > kotlin (Javascript) > [next,next,next...finish]

    You'll have to configure gradle ofcourse (based how you like it).

    I configured mine as shown below:-

    buildscript {
        ext.kotlin_version = '1.2.41'
        ext.kotlinx_html_version = "0.6.4"
        ext.kotlin_frontend_version = "0.0.30"
        ext.react_version = "16.4.0-pre.31-kotlin-$kotlin_version"
        ext.react_dom_version = "16.4.0-pre.31-kotlin-$kotlin_version"
        repositories {
            mavenCentral()
            maven {
                url "https://dl.bintray.com/kotlin/kotlin-eap"
            }
        }
        dependencies {
            classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
            classpath "org.jetbrains.kotlin:kotlin-frontend-plugin:$kotlin_frontend_version"
        }
    }
    apply plugin: 'org.jetbrains.kotlin.frontend'
    apply plugin: 'kotlin2js'
    sourceCompatibility = 1.8
    repositories {
        mavenLocal()
        mavenCentral()
        jcenter()
        maven { url "http://dl.bintray.com/kotlin/kotlin-dev" }
        maven { url "http://dl.bintray.com/kotlinx/kotlinx" }
        maven { url "http://dl.bintray.com/kotlin/kotlin-js-wrappers" }
    }
    dependencies {
        compile "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlin_version"
        compile "org.jetbrains.kotlinx:kotlinx-html-js:$kotlinx_html_version"
        compile "org.jetbrains:kotlin-react:$react_version"
        compile "org.jetbrains:kotlin-react-dom:$react_dom_version"
    }
    kotlinFrontend {
        npm {
            dependency "style-loader" // production dependency
            dependency "react"
            dependency "react-dom"
            dependency "kotlin"
            dependency "@jetbrains/kotlin-extensions"
            dependency "@jetbrains/kotlin-react"
        }
        webpackBundle {
            bundleName = "main"
            sourceMapEnabled = false   // enable/disable source maps
            contentPath = file("${projectDir}/public") // a file that represents a directory to be served by dev server)
            publicPath = "/"  // web prefix
            host = "localhost" // dev server host
            port = 8088   // dev server port
            stats = "errors-only"  // log level
        }
    }
    task copyDocs(type: Copy) {
        println ":md-react:copyDocs: Copying to public directory"
        from("${projectDir}/build/bundle") {
            include "**/*.js"
            include "*.js"
        }
        into "${projectDir}/public/static"
        println ":md-react:copyDocs: Done copying"
    }
    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.endsWith(".map")) && (path.startsWith("META-INF/resources/") ||
                            !path.startsWith("META-INF/"))
                }
            })
        }
        from compileKotlin2Js.destinationDir
        into "${projectDir}/build/classes/main"
        dependsOn classes
    }
    //run.dependsOn copyDocs
    assemble.dependsOn assembleWeb
    copyDocs.dependsOn bundle
    //assemble.finalizedBy(copyDocs)
    compileKotlin2Js {
        kotlinOptions.outputFile = "${projectDir}/build/classes/main/web.js"
        kotlinOptions.moduleKind = "umd"
        kotlinOptions.sourceMap = true
    }
    

    Hope this helps you.

    Happy Hacking