martmists
05/22/2025, 5:56 PMcompileProductionExecutableKotlinWebOptimize
taking a really long time? (about 15 mins on my end)Robert Jaros
05/22/2025, 6:04 PMmartmists
05/22/2025, 6:10 PMmartmists
05/22/2025, 6:13 PMimport externals.DownloadZipTask
import org.jetbrains.kotlin.gradle.dsl.JsSourceMapEmbedMode
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrLink
import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile
plugins {
kotlin("multiplatform")
kotlin("plugin.serialization")
kotlin("plugin.compose")
id("org.jetbrains.compose")
}
repositories {
mavenLocal()
}
val sharedConfiguration: Configuration by configurations.creating {
isCanBeConsumed = true
isCanBeResolved = false
}
kotlin {
wasmJs("web") {
browser {
commonWebpackConfig {
sourceMaps = !project.production
outputFileName = "index.js"
devServer = (devServer ?: KotlinWebpackConfig.DevServer()).apply {
static = (static ?: mutableListOf()).apply {
// Serve sources to debug inside browser
add(project.rootDir.path)
add(project.projectDir.path)
}
}
}
}
binaries.executable()
}
sourceSets {
val commonMain by getting {
kotlin.srcDir(layout.buildDirectory.dir("generated/graphql/commonMain/kotlin"))
dependencies {
implementation(project(":site-common"))
implementation(compose.ui)
implementation(compose.foundation)
implementation(compose.material3)
implementation(compose.runtime)
implementation(compose.runtimeSaveable)
implementation(compose.animation)
implementation(compose.animationGraphics)
implementation(compose.components.resources)
implementation("io.ktor:ktor-client-core:${Versions.ktor}")
implementation("io.ktor:ktor-client-content-negotiation:${Versions.ktor}")
implementation("io.ktor:ktor-client-websockets:${Versions.ktor}")
implementation("org.jetbrains.kotlinx:kotlinx-datetime:${Versions.datetime}")
}
}
val webMain by getting {
dependencies {
implementation("io.ktor:ktor-client-js:${Versions.ktor}")
}
}
}
}
tasks {
val createGraphQLBindings by registering(graphql.GenerateGraphQLTask::class) {
schemaFallback = projectDir.resolve("src/webMain/graphql/schema.graphqls")
outputDir = layout.buildDirectory.dir("generated/graphql/commonMain/kotlin")
packageName = "com.martmists.template.frontend.graphql"
}
val downloadJetbrainsMonoFont by registering(DownloadZipTask::class) {
outputDirectory = layout.buildDirectory.dir("downloaded/JetbrainsMono")
url = "<https://github.com/JetBrains/JetBrainsMono/releases/download/v2.304/JetBrainsMono-2.304.zip>"
}
val downloadInterFont by registering(DownloadZipTask::class) {
outputDirectory = layout.buildDirectory.dir("downloaded/Inter")
url = "<https://github.com/rsms/inter/releases/download/v4.1/Inter-4.1.zip>"
}
val downloadLucideIcons by registering(DownloadZipTask::class) {
outputDirectory = layout.buildDirectory.dir("downloaded/Lucide")
url = "<https://github.com/lucide-icons/lucide/releases/download/0.461.0/lucide-icons-0.461.0.zip>"
}
val copyFonts by registering(Copy::class) {
from(downloadJetbrainsMonoFont, downloadInterFont)
into(layout.buildDirectory.dir("downloaded/allResources/font"))
eachFile {
path = path.split("/").last()
}
include("**/ttf/*.ttf")
}
val copyIcons by registering(Copy::class) {
from(downloadLucideIcons)
into(layout.buildDirectory.dir("downloaded/allResources/drawable"))
eachFile {
path = path.split("/").last()
}
include("**/*.svg")
}
// Required by gradle to add the tasks as dependencies
val copyNonXmlValueResourcesForCommonMain by getting {
dependsOn(copyFonts, copyIcons)
}
// Run these tasks on IDEA import
rootProject.tasks.named("prepareKotlinBuildScriptModel") {
dependsOn(
createGraphQLBindings,
copyFonts,
copyIcons,
)
}
withType<AbstractKotlinCompile<*>> {
dependsOn(createGraphQLBindings)
compilerOptions.optIn.add("kotlin.uuid.ExperimentalUuidApi")
}
// Not sure which I need to use for WASM
withType<Kotlin2JsCompile> {
compilerOptions {
sourceMapEmbedSources = JsSourceMapEmbedMode.SOURCE_MAP_SOURCE_CONTENT_INLINING
}
}
withType<KotlinJsIrLink> {
compilerOptions {
sourceMapEmbedSources = JsSourceMapEmbedMode.SOURCE_MAP_SOURCE_CONTENT_INLINING
}
}
// For some reason gradle forces me to add these two
named("webBrowserDevelopmentWebpack") {
dependsOn("webProductionExecutableCompileSync")
}
named("webBrowserProductionWebpack") {
dependsOn("webDevelopmentExecutableCompileSync")
}
}
artifacts {
add(sharedConfiguration.name, tasks.named("copyFonts"))
add(sharedConfiguration.name, tasks.named("copyIcons"))
// if production, use webBrowserDistribution
// if development, use webBrowserDevelopmentExecutableDistribution
add(sharedConfiguration.name, tasks.named("webBrowser${if (project.production) "" else "DevelopmentExecutable"}Distribution"))
}
compose {
resources {
customDirectory(
"commonMain",
layout.buildDirectory.dir("downloaded/allResources")
)
}
}
Robert Jaros
05/22/2025, 6:14 PMafterEvaluate {
tasks.withType<BinaryenExec> {
binaryenArgs = mutableListOf(
"--enable-nontrapping-float-to-int",
"--enable-gc",
"--enable-reference-types",
"--enable-exception-handling",
"--enable-bulk-memory",
"--inline-functions-with-loops",
"--traps-never-happen",
"--fast-math",
"--closed-world",
"-O0",
)
}
}
Robert Jaros
05/22/2025, 6:15 PM