Setting output path for Kotlin/JS distribution / webpack output

935 views Asked by At

When building my project using the browserDistribution Gradle task, Kotlin/JS puts the output which has been processed by webpack into /build/distributions/myProject.js.

Instead, I would like my output to go into a folder called /output in my project's root directory.

How can I change the path where my distributions are put after running through webpack?

I'm using the Gradle Kotlin DSL if that helps.

3

There are 3 answers

0
Raman On

If you are attempting to set the output directory in order to include the build artifacts into another project, say a backend project running ktor that needs to serve the client build artifacts, then setting the output directory directly is the wrong approach.

In order to be safe to share between projects and allow maximum performance during the build (parallelism), such artifacts must be exposed via Gradle's "outgoing configurations" mechanism.

In the client (producer) project definition, declare a browserDist configuration like this:

val browserDist: Configuration by configurations.creating {
  isCanBeResolved = false
}

and in the same project declare that the output directory of the jsBrowserDistribution task should be inluded in the artifacts of this configuration:

artifacts {
  add(browserDist.name, tasks.named("jsBrowserDistribution").map { it.outputs.files.single() })
}

Then, in the backend (consumer) project definition, declare a browserDist configuration like this:

val browserDist: Configuration by configurations.creating {
  isCanBeConsumed = false
}

and specify the dependencies of this configuration (change :client to the name of the project containing the client build artifacts):

dependencies {
  ... other dependencies ...

  browserDist(project(":client", "browserDist"))
}

and then finally register a task to copy the artifacts and serve them up. For example, for a ktor server, we'll want to copy the artifacts into a resources/web directory so they can be served via singlePageApplication.

In the backend build, define:

tasks.register<Copy>("processWebResources") {
  from(browserDist)
  into(layout.buildDirectory.dir("resources/main/web"))
}

// make processResources depend on processWebResources
// it may be useful to gate this behind a property specified only
//  for production builds, otherwise this will run even in dev,
//  where we're probably using the client `jsRun` directly
tasks.named("processResources") {
  if (providers.gradleProperty("bundleProductionJs").isPresent) {
    dependsOn("processWebResources")
  }
}

In ktor, define a route like this:

singlePageApplication {
  useResources = true
  filesPath = "web"
}

Adjust as necessary for your specific backend.

0
Sebastian A. On

The Kotlin/JS Gradle plugin provides a distribution API which can be used to adjust the output directory of a project. To put the final distribution output of a project into a folder called output in the project root, one can use the following snippet (it works in both Gradle Kotlin DSL and Groovy Gradle):

browser {
    distribution {
        directory = file("$projectDir/output/")
    }
}
0
Stefan On

The output path can be set via the outputPath property in the commonWebpackConfig or the destinationDirectory property in the webpackTask block , e.g.:

// kotlin dsl
kotlin {
    js {
        binaries.executable()
        browser {
            // either configure here
            commonWebpackConfig {
                outputPath = file("$projectDir/build/distributions/assets/js")
            }

            // or here
            webpackTask {
                destinationDirectory = file("$projectDir/build/distributions/assets/js")
            }
        }
    }
}