import com.nixxcode.jvmbrotli.enc.Encoder
import groovy.json.JsonSlurper
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
-import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsBrowserDsl
import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpack
import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig
import org.jetbrains.kotlin.gradle.targets.js.webpack.WebpackDevtool
group = "info.mechyrdia"
-val configFile = (JsonSlurper().parse(File(rootDir, "config.json")) as Map<*, *>).mapKeys { (k, _) -> k.toString() }
+val configFile by project.extra {
+ (JsonSlurper().parse(File(rootDir, "config.json")) as Map<*, *>).mapKeys { (k, _) -> k.toString() }
+}
-val isDevMode = (configFile["isDevMode"] as? Boolean) ?: false
+val isDevMode by project.extra {
+ (configFile["isDevMode"] as? Boolean) ?: false
+}
-val configureOutput: KotlinJsBrowserDsl.(name: String) -> Unit = { name ->
- val fileName = "$name.js"
-
- commonWebpackConfig {
- outputFileName = fileName
- if (isDevMode) {
- mode = KotlinWebpackConfig.Mode.DEVELOPMENT
- devtool = WebpackDevtool.SOURCE_MAP
- sourceMaps = true
- } else {
- mode = KotlinWebpackConfig.Mode.PRODUCTION
- devtool = null
- sourceMaps = false
- }
- }
-
- webpackTask {
- mainOutputFileName.set(fileName)
- if (isDevMode) {
- mode = KotlinWebpackConfig.Mode.DEVELOPMENT
- devtool = WebpackDevtool.SOURCE_MAP
- sourceMaps = true
- } else {
- mode = KotlinWebpackConfig.Mode.PRODUCTION
- sourceMaps = false
- }
- }
+val fileDir by project.extra {
+ val fileDirPath = configFile["rootDir"]?.let { "$it" } ?: ".."
+ File(rootDir, fileDirPath)
}
-val jsTarget: KotlinMultiplatformExtension.(name: String) -> Unit = { name ->
+val assetDir by project.extra {
+ configFile["assetDir"]?.let { File(rootDir, "$it") } ?: File(fileDir, "assets")
+}
+
+val browserWebpackSuffix by project.extra {
+ if (isDevMode)
+ "BrowserDevelopmentWebpack"
+ else
+ "BrowserProductionWebpack"
+}
+
+fun KotlinMultiplatformExtension.jsConfigured(name: String) {
+ val isDevMode: Boolean by project.extra
+
js(name) {
browser {
- configureOutput(name)
+ val fileName = "$name.js"
+
+ commonWebpackConfig {
+ outputFileName = fileName
+ if (isDevMode) {
+ mode = KotlinWebpackConfig.Mode.DEVELOPMENT
+ devtool = WebpackDevtool.SOURCE_MAP
+ sourceMaps = true
+ } else {
+ mode = KotlinWebpackConfig.Mode.PRODUCTION
+ devtool = null
+ sourceMaps = false
+ }
+ }
+
+ webpackTask {
+ mainOutputFileName.set(fileName)
+ if (isDevMode) {
+ mode = KotlinWebpackConfig.Mode.DEVELOPMENT
+ devtool = WebpackDevtool.SOURCE_MAP
+ sourceMaps = true
+ } else {
+ mode = KotlinWebpackConfig.Mode.PRODUCTION
+ sourceMaps = false
+ }
+ }
}
+
binaries.executable()
}
}
}
kotlin {
- jsTarget("map")
+ jsConfigured("map")
jvmToolchain(17)
jvm("jvm") {
withJava()
val encoderParams = if (BrotliLoader.isBrotliAvailable()) Encoder.Parameters().setQuality(8) else null
- val resourceTree = fileTree(mapOf("dir" to outputs.files.asPath + "/static/", "exclude" to listOf("*.gz", "*.br", "*.sha256")))
+ val resourceTree = fileTree(mapOf("dir" to outputs.files.asPath + "/static/", "exclude" to listOf("*.gz", "*.br")))
val countDownLatch = CountDownLatch(resourceTree.count())
for (file in resourceTree) {
}
}
-val browserWebpackSuffix = if (isDevMode) "BrowserDevelopmentWebpack" else "BrowserProductionWebpack"
-
tasks.named<ShadowJar>("shadowJar") {
mergeServiceFiles()
exclude { it.name == "module-info.class" }
mainClass.set("info.mechyrdia.Factbooks")
}
-val buildJsAsset: Task.(name: String) -> Unit = { name ->
- val webpackTask = tasks.getByName<KotlinWebpack>("$name$browserWebpackSuffix")
- dependsOn(webpackTask)
+fun Task.buildJsAsset(name: String) {
+ val browserWebpackSuffix: String by project.extra
+ val browserWebpackTask by tasks.named<KotlinWebpack>("$name$browserWebpackSuffix")
+ dependsOn(browserWebpackTask)
}
-val copyToAssets: Task.(name: String, destSubDir: String, destFileName: String) -> Unit = { name, destSubDir, destFileName ->
- val webpackTask = tasks.getByName<KotlinWebpack>("$name$browserWebpackSuffix")
-
- doFirst {
- val assetsDirPath = configFile["assetDir"]?.let { "$it" }
- ?: configFile["rootDir"]?.let { "$it/assets" }
- ?: "../assets"
- val assetsDir = File(rootDir, assetsDirPath)
-
- val destJsName = "$destFileName.js"
-
- val jsFile = webpackTask
- .mainOutputFile
- .get()
- .asFile
+fun copyToAssetsTask(from: TaskProvider<KotlinWebpack>, into: String, name: String): TaskProvider<Copy> {
+ return tasks.register("${into}DeployToAssets", Copy::class) {
+ group = "build"
- val jsText = jsFile.readText()
- val jsMapName = "${webpackTask.mainOutputFileName.get()}.map"
- val sourceMapReplaceText = "//# sourceMappingURL=$jsMapName"
- val sourceMapReplacement = "//# sourceMappingURL=$destJsName.map"
-
- val destJsFile = File(assetsDir, "$destSubDir/$destJsName")
- val destJsMapFile = File(assetsDir, "$destSubDir/$destJsName.map")
+ val isDevMode: Boolean by project.extra
if (isDevMode) {
- val jsMapFile = File(jsFile.parentFile, jsMapName)
- val jsMapText = jsMapFile.readText()
+ val fromJs = from.flatMap { it.mainOutputFile }.map { it.asFile }
+ val fromJsMap = fromJs.map { File(it.parentFile, "${it.name}.map") }
- destJsFile.writeText(jsText.replace(sourceMapReplaceText, sourceMapReplacement))
- destJsMapFile.writeText(jsMapText)
+ from(files(fromJs, fromJsMap)) {
+ eachFile {
+ rename { if (it.endsWith(".map")) "$name.js.map" else "$name.js" }
+
+ val sourceMapReplaceText = "//# sourceMappingURL=${fromJsMap.get().name}"
+ val sourceMapReplacement = "//# sourceMappingURL=$name.js.map"
+ filter { line ->
+ line.replace(sourceMapReplaceText, sourceMapReplacement)
+ }
+ }
+ }
} else {
- destJsFile.writeText(jsText.replace(sourceMapReplaceText, ""))
- destJsMapFile.delete()
+ val fromJs = from.flatMap { it.mainOutputFile }.map { it.asFile }
+
+ from(fromJs) {
+ eachFile {
+ rename { "$name.js" }
+
+ val sourceMapTestText = "//# sourceMappingURL="
+ filter { line ->
+ if (line.contains(sourceMapTestText)) "" else line
+ }
+ }
+ }
}
+
+ val assetDir: File by project.extra
+ val intoDir = File(assetDir, into).apply { mkdirs() }
+
+ into(intoDir)
}
}
+val mapDeployToAssets by copyToAssetsTask(tasks.named<KotlinWebpack>("map$browserWebpackSuffix"), "map", "main")
+
tasks.withType<ShadowJar> {
buildJsAsset("map")
}
-tasks.getByName<JavaExec>("runShadow") {
- copyToAssets("map", "map", "main")
+tasks.named<JavaExec>("runShadow") {
+ dependsOn(mapDeployToAssets)
}
tasks.withType<JavaExec> {