Skip to content

Instantly share code, notes, and snippets.

@nanodeath
Created April 17, 2021 18:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nanodeath/23b03c5d3aacf3724d06865acb763fe6 to your computer and use it in GitHub Desktop.
Save nanodeath/23b03c5d3aacf3724d06865acb763fe6 to your computer and use it in GitHub Desktop.
Downloading and unpacking WebJars with Gradle Kotlin for use with Sass

If you're doing frontend development in a Kotlin project with Gradle, you may be interested in using WebJars to avoid having to also maintain a package.json and using Node. If you want to use Sass, Sass can't access the contents of these WebJars, so you have to unpack them first. Attached below is how I did this in my build.gradle.kts.

// First we define a new configuration, so we only unpack webjars instead of everything.
val webJar by configurations.creating {
isTransitive = false
}
// Next I use it to add a webjar I'm interested in.
dependencies {
webJar("org.webjars.npm:bulma:0.9.2")
}
// Here we have a custom Copy subclass. This ended up not being strictly necessary,
// but it serves as a nice namespace for the extension properties.
open class UnpackWebJars : Copy() {
companion object {
const val OUTPUT = "tmp/webjars/"
}
}
val UnpackWebJars.Companion.outputDir get() = buildDir.resolve(OUTPUT)
val UnpackWebJars.Companion.loadPaths get() = webJar.dependencies.map { dep ->
outputDir.resolve("META-INF/resources/webjars/${dep.name}/${dep.version}")
}.also {
logger.info("UnpackWebJars: generated loadPath: {}", it)
}
// This defines the actual task where we unpack each of our webJar dependencies into build/tmp/webjars/.
// Note that it doesn't do any cleanup, so if you're changing versions a lot you may want to invoke the
// `clean` task.
val unpackWebJars = tasks.register<UnpackWebJars>("unpackWebJars") {
webJar.files.forEach { from(zipTree(it)) }
into(UnpackWebJars.outputDir)
}
// This last step will vary by use case, but I want to use the loadPaths generated and pass them to Sass
val compileCss = tasks.register<Exec>("compileCss") {
dependsOn(unpackWebJars) // forces UnpackWebJars to run first
group = "build"
val inputDir = projectDir.resolve("src/sass")
val outputDir = staticOutputDirectory
description = "Compiles the Sass in ${inputDir.relativeToProject()} into ${outputDir.relativeToProject()}"
inputs.dir(inputDir)
outputs.dir(outputDir)
commandLine = listOf("sass", "${inputDir}:${outputDir}")
doFirst {
// add each of the load paths from our webJars dependency closure to this invocation
UnpackWebJars.loadPaths.forEach { webjar -> args("--load-path=$webjar") }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment