fixing web-app
This commit is contained in:
+153
-134
@@ -6,8 +6,9 @@ import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl
|
||||
plugins {
|
||||
alias(libs.plugins.kotlin.multiplatform)
|
||||
alias(libs.plugins.kotlin.serialization)
|
||||
alias(libs.plugins.compose.multiplatform)
|
||||
alias(libs.plugins.compose.compiler)
|
||||
alias(libs.plugins.composeMultiplatform)
|
||||
alias(libs.plugins.composeCompiler)
|
||||
alias(libs.plugins.composeHotReload)
|
||||
}
|
||||
|
||||
// Project version configuration
|
||||
@@ -15,126 +16,139 @@ version = "1.0.0"
|
||||
group = "at.mocode"
|
||||
|
||||
// Build performance optimizations
|
||||
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile>().configureEach {
|
||||
compilerOptions {
|
||||
jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_21)
|
||||
freeCompilerArgs.addAll(
|
||||
"-opt-in=kotlin.RequiresOptIn",
|
||||
"-Xjvm-default=all" // Generate default methods for interfaces (JVM performance)
|
||||
)
|
||||
}
|
||||
}
|
||||
//tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile>().configureEach {
|
||||
// compilerOptions {
|
||||
// jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_21)
|
||||
// freeCompilerArgs.addAll(
|
||||
// "-opt-in=kotlin.RequiresOptIn",
|
||||
// "-Xjvm-default=all" // Generate default methods for interfaces (JVM performance)
|
||||
// )
|
||||
// }
|
||||
//}
|
||||
|
||||
kotlin {
|
||||
// Configure JVM toolchain for all JVM targets
|
||||
jvmToolchain(21)
|
||||
// // Configure JVM toolchain for all JVM targets
|
||||
// jvmToolchain(21)
|
||||
//
|
||||
// // Global compiler options for all targets
|
||||
// compilerOptions {
|
||||
// freeCompilerArgs.add("-Xexpect-actual-classes")
|
||||
// }
|
||||
|
||||
// Global compiler options for all targets
|
||||
compilerOptions {
|
||||
freeCompilerArgs.add("-Xexpect-actual-classes")
|
||||
}
|
||||
// jvm {
|
||||
// compilations.all {
|
||||
// compileTaskProvider.configure {
|
||||
// compilerOptions {
|
||||
// jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_21)
|
||||
// freeCompilerArgs.addAll(
|
||||
// "-Xjsr305=strict",
|
||||
// "-Xcontext-parameters"
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
jvm {
|
||||
compilations.all {
|
||||
compileTaskProvider.configure {
|
||||
compilerOptions {
|
||||
jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_21)
|
||||
freeCompilerArgs.addAll(
|
||||
"-Xjsr305=strict",
|
||||
"-Xcontext-parameters"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// js(IR) {
|
||||
// browser {
|
||||
// commonWebpackConfig {
|
||||
// outputFileName = "meldestelle-client.js"
|
||||
// cssSupport {
|
||||
// enabled.set(true)
|
||||
// }
|
||||
// // Webpack performance optimizations for smaller bundles
|
||||
// devServer?.apply {
|
||||
// open = false
|
||||
// port = 8080
|
||||
// }
|
||||
// }
|
||||
// runTask {
|
||||
// // Development optimizations
|
||||
// args.add("--mode=development")
|
||||
// //args.add("--optimization-minimize=false")
|
||||
// }
|
||||
// webpackTask {
|
||||
// // Production optimizations
|
||||
// args.add("--mode=production")
|
||||
// args.add("--optimization-minimize")
|
||||
// }
|
||||
// testTask {
|
||||
// // Disable browser tests due to ChromeHeadless permission issues
|
||||
// enabled = false
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // Use Node.js for testing instead of browser
|
||||
// nodejs {
|
||||
// testTask {
|
||||
// useMocha {
|
||||
// timeout = "10s"
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// binaries.executable()
|
||||
// }
|
||||
|
||||
js(IR) {
|
||||
browser {
|
||||
commonWebpackConfig {
|
||||
outputFileName = "meldestelle-client.js"
|
||||
cssSupport {
|
||||
enabled.set(true)
|
||||
}
|
||||
// Webpack performance optimizations for smaller bundles
|
||||
devServer?.apply {
|
||||
open = false
|
||||
port = 8080
|
||||
}
|
||||
}
|
||||
runTask {
|
||||
// Development optimizations
|
||||
args.add("--mode=development")
|
||||
//args.add("--optimization-minimize=false")
|
||||
}
|
||||
webpackTask {
|
||||
// Production optimizations
|
||||
args.add("--mode=production")
|
||||
args.add("--optimization-minimize")
|
||||
}
|
||||
testTask {
|
||||
// Disable browser tests due to ChromeHeadless permission issues
|
||||
enabled = false
|
||||
}
|
||||
}
|
||||
// wasmJs {
|
||||
// browser {
|
||||
// commonWebpackConfig {
|
||||
// outputFileName = "meldestelle-wasm.js"
|
||||
// cssSupport {
|
||||
// enabled.set(true)
|
||||
// }
|
||||
// // WASM-specific webpack optimizations handled by webpack.config.d files
|
||||
// devServer?.apply {
|
||||
// open = false
|
||||
// port = 8080
|
||||
// }
|
||||
// }
|
||||
// runTask {
|
||||
// // Development optimizations for WASM
|
||||
// args.add("--mode=development")
|
||||
// //args.add("--optimization-minimize=false")
|
||||
// // Dev server settings handled by webpack.config.d/dev-server.js
|
||||
// }
|
||||
// webpackTask {
|
||||
// // Production optimizations for WASM
|
||||
// args.add("--mode=production")
|
||||
// args.add("--optimization-minimize")
|
||||
// }
|
||||
// testTask {
|
||||
// // Disable WASM browser tests due to environment issues
|
||||
// enabled = false
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // WASM-specific compiler optimizations for smaller bundles
|
||||
// compilations.all {
|
||||
// compileTaskProvider.configure {
|
||||
// compilerOptions {
|
||||
// freeCompilerArgs.addAll(
|
||||
// "-Xwasm-use-new-exception-proposal",
|
||||
// "-Xwasm-debugger-custom-formatters",
|
||||
// "-Xwasm-enable-array-range-checks",
|
||||
// "-Xwasm-generate-wat=false",
|
||||
// "-opt-in=kotlin.ExperimentalStdlibApi",
|
||||
// "-opt-in=kotlin.js.ExperimentalJsExport"
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// binaries.executable()
|
||||
// }
|
||||
|
||||
// Use Node.js for testing instead of browser
|
||||
nodejs {
|
||||
testTask {
|
||||
useMocha {
|
||||
timeout = "10s"
|
||||
}
|
||||
}
|
||||
}
|
||||
jvm()
|
||||
|
||||
js {
|
||||
browser()
|
||||
binaries.executable()
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalWasmDsl::class)
|
||||
wasmJs {
|
||||
browser {
|
||||
commonWebpackConfig {
|
||||
outputFileName = "meldestelle-wasm.js"
|
||||
cssSupport {
|
||||
enabled.set(true)
|
||||
}
|
||||
// WASM-specific webpack optimizations handled by webpack.config.d files
|
||||
devServer?.apply {
|
||||
open = false
|
||||
port = 8080
|
||||
}
|
||||
}
|
||||
runTask {
|
||||
// Development optimizations for WASM
|
||||
args.add("--mode=development")
|
||||
//args.add("--optimization-minimize=false")
|
||||
// Dev server settings handled by webpack.config.d/dev-server.js
|
||||
}
|
||||
webpackTask {
|
||||
// Production optimizations for WASM
|
||||
args.add("--mode=production")
|
||||
args.add("--optimization-minimize")
|
||||
}
|
||||
testTask {
|
||||
// Disable WASM browser tests due to environment issues
|
||||
enabled = false
|
||||
}
|
||||
}
|
||||
|
||||
// WASM-specific compiler optimizations for smaller bundles
|
||||
compilations.all {
|
||||
compileTaskProvider.configure {
|
||||
compilerOptions {
|
||||
freeCompilerArgs.addAll(
|
||||
"-Xwasm-use-new-exception-proposal",
|
||||
"-Xwasm-debugger-custom-formatters",
|
||||
"-Xwasm-enable-array-range-checks",
|
||||
"-Xwasm-generate-wat=false",
|
||||
"-opt-in=kotlin.ExperimentalStdlibApi",
|
||||
"-opt-in=kotlin.js.ExperimentalJsExport"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
browser()
|
||||
binaries.executable()
|
||||
}
|
||||
|
||||
@@ -149,6 +163,10 @@ kotlin {
|
||||
// UiToolingPreview nur für Development, nicht für Production WASM
|
||||
// implementation(compose.components.uiToolingPreview)
|
||||
|
||||
implementation(compose.components.uiToolingPreview)
|
||||
implementation(libs.androidx.lifecycle.viewmodelCompose)
|
||||
implementation(libs.androidx.lifecycle.runtimeCompose)
|
||||
|
||||
// HTTP client dependencies for ping-service - optimiert
|
||||
implementation(libs.ktor.client.core)
|
||||
implementation(libs.ktor.client.contentNegotiation)
|
||||
@@ -161,6 +179,7 @@ kotlin {
|
||||
}
|
||||
jvmMain.dependencies {
|
||||
implementation(compose.desktop.currentOs)
|
||||
implementation(libs.kotlinx.coroutines.swing)
|
||||
implementation(libs.ktor.client.cio)
|
||||
}
|
||||
jsMain.dependencies {
|
||||
@@ -180,29 +199,29 @@ kotlin {
|
||||
|
||||
// Exclude Skiko runtime files from jsTest processed resources
|
||||
// to prevent overwriting logs during test packaging.
|
||||
@Suppress("UNUSED_VARIABLE")
|
||||
val configureJsTestResources = run {
|
||||
// Configure only if the task exists (JS target present)
|
||||
tasks.matching { it.name == "jsTestProcessResources" && it is Copy }.configureEach {
|
||||
(this as Copy).exclude("skiko.*", "skikod8.mjs")
|
||||
}
|
||||
}
|
||||
|
||||
// Also apply the same exclusion for WASM JS test resources, if present
|
||||
@Suppress("UNUSED_VARIABLE")
|
||||
val configureWasmJsTestResources = run {
|
||||
tasks.matching { it.name == "wasmJsTestProcessResources" && it is Copy }.configureEach {
|
||||
(this as Copy).exclude("skiko.*", "skikod8.mjs")
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure Kotlin/JS generated Sync tasks do not overwrite duplicates noisily
|
||||
@Suppress("UNUSED_VARIABLE")
|
||||
val configureJsCompileSync = run {
|
||||
tasks.matching { it.name.endsWith("CompileSync") && it is Sync }.configureEach {
|
||||
(this as Sync).duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
}
|
||||
}
|
||||
//@Suppress("UNUSED_VARIABLE")
|
||||
//val configureJsTestResources = run {
|
||||
// // Configure only if the task exists (JS target present)
|
||||
// tasks.matching { it.name == "jsTestProcessResources" && it is Copy }.configureEach {
|
||||
// (this as Copy).exclude("skiko.*", "skikod8.mjs")
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//// Also apply the same exclusion for WASM JS test resources, if present
|
||||
//@Suppress("UNUSED_VARIABLE")
|
||||
//val configureWasmJsTestResources = run {
|
||||
// tasks.matching { it.name == "wasmJsTestProcessResources" && it is Copy }.configureEach {
|
||||
// (this as Copy).exclude("skiko.*", "skikod8.mjs")
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//// Ensure Kotlin/JS generated Sync tasks do not overwrite duplicates noisily
|
||||
//@Suppress("UNUSED_VARIABLE")
|
||||
//val configureJsCompileSync = run {
|
||||
// tasks.matching { it.name.endsWith("CompileSync") && it is Sync }.configureEach {
|
||||
// (this as Sync).duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
// }
|
||||
//}
|
||||
|
||||
compose.desktop {
|
||||
application {
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Meldestelle</title>
|
||||
<link type="text/css" rel="stylesheet" href="styles.css">
|
||||
<script type="application/javascript" src="composeApp.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="ComposeTarget"></canvas>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package at.mocode
|
||||
|
||||
import androidx.compose.ui.ExperimentalComposeUiApi
|
||||
import androidx.compose.ui.window.CanvasBasedWindow
|
||||
import androidx.compose.ui.window.ComposeViewport
|
||||
|
||||
@OptIn(ExperimentalComposeUiApi::class)
|
||||
fun main() {
|
||||
CanvasBasedWindow(canvasElementId = "ComposeTarget") {
|
||||
ComposeViewport("ComposeTarget") {
|
||||
App()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package at.mocode
|
||||
|
||||
import androidx.compose.ui.ExperimentalComposeUiApi
|
||||
import androidx.compose.ui.window.CanvasBasedWindow
|
||||
import androidx.compose.ui.window.ComposeViewport
|
||||
|
||||
@OptIn(ExperimentalComposeUiApi::class)
|
||||
fun main() {
|
||||
CanvasBasedWindow(canvasElementId = "ComposeTarget") {
|
||||
ComposeViewport("ComposeTarget") {
|
||||
App()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,122 +0,0 @@
|
||||
// Bundle Analyzer Configuration for WASM Bundle Size Monitoring
|
||||
// Helps identify which parts of the bundle are largest and can be optimized
|
||||
|
||||
// Enable bundle analysis based on environment variable
|
||||
const enableAnalyzer = process.env.ANALYZE_BUNDLE === 'true';
|
||||
// Ensure mutable config sections exist to avoid spread on undefined
|
||||
config.plugins = config.plugins || [];
|
||||
config.resolve = config.resolve || {};
|
||||
config.module = config.module || {};
|
||||
|
||||
if (enableAnalyzer) {
|
||||
console.log('📊 Bundle analyzer enabled - generating bundle report...');
|
||||
|
||||
// Simple bundle size logging without external dependencies
|
||||
const originalEmit = config.plugins.find(plugin => plugin.constructor.name === 'DefinePlugin');
|
||||
|
||||
// Add a custom plugin to log bundle sizes
|
||||
config.plugins.push({
|
||||
apply: (compiler) => {
|
||||
compiler.hooks.done.tap('BundleSizeLogger', (stats) => {
|
||||
const json = stats.toJson({ all: false, assets: true });
|
||||
const assets = (json && json.assets) ? json.assets : [];
|
||||
|
||||
console.log('\n📦 WASM Bundle Analysis Report:');
|
||||
console.log('=====================================');
|
||||
|
||||
// Sort assets by size (largest first)
|
||||
const sortedAssets = assets
|
||||
.filter(asset => !asset.name.endsWith('.map'))
|
||||
.sort((a, b) => b.size - a.size);
|
||||
|
||||
let totalSize = 0;
|
||||
sortedAssets.forEach(asset => {
|
||||
const sizeKB = (asset.size / 1024).toFixed(2);
|
||||
const sizeMB = (asset.size / (1024 * 1024)).toFixed(2);
|
||||
totalSize += asset.size;
|
||||
|
||||
console.log(`📄 ${asset.name}:`);
|
||||
console.log(` Size: ${sizeKB} KB (${sizeMB} MB)`);
|
||||
|
||||
// Identify what type of asset this likely is
|
||||
if (asset.name.includes('skiko')) {
|
||||
console.log(' Type: 🎨 Skiko (Compose UI Framework)');
|
||||
} else if (asset.name.includes('ktor')) {
|
||||
console.log(' Type: 🌐 Ktor (HTTP Client)');
|
||||
} else if (asset.name.includes('kotlin')) {
|
||||
console.log(' Type: 📚 Kotlin Standard Library');
|
||||
} else if (asset.name.includes('wasm')) {
|
||||
console.log(' Type: ⚡ WebAssembly Binary');
|
||||
} else if (asset.name.includes('meldestelle')) {
|
||||
console.log(' Type: 🏠 Application Code');
|
||||
} else {
|
||||
console.log(' Type: 📦 Other/Vendor');
|
||||
}
|
||||
console.log('');
|
||||
});
|
||||
|
||||
const totalSizeKB = (totalSize / 1024).toFixed(2);
|
||||
const totalSizeMB = (totalSize / (1024 * 1024)).toFixed(2);
|
||||
|
||||
console.log(`📊 Total Bundle Size: ${totalSizeKB} KB (${totalSizeMB} MB)`);
|
||||
console.log('=====================================');
|
||||
|
||||
// Provide optimization recommendations
|
||||
const wasmAsset = sortedAssets.find(asset => asset.name.includes('.wasm'));
|
||||
const jsAsset = sortedAssets.find(asset => asset.name.includes('meldestelle-wasm.js'));
|
||||
|
||||
if (wasmAsset && jsAsset) {
|
||||
const wasmSizeMB = (wasmAsset.size / (1024 * 1024)).toFixed(2);
|
||||
const jsSizeKB = (jsAsset.size / 1024).toFixed(2);
|
||||
|
||||
console.log('\n💡 Optimization Recommendations:');
|
||||
console.log('=====================================');
|
||||
|
||||
if (wasmAsset.size > 5 * 1024 * 1024) { // > 5MB
|
||||
console.log(`⚠️ WASM binary is large (${wasmSizeMB}MB). Consider:`);
|
||||
console.log(' - Reducing Compose UI components');
|
||||
console.log(' - Lazy loading features');
|
||||
console.log(' - Tree-shaking unused dependencies');
|
||||
}
|
||||
|
||||
if (jsAsset.size > 500 * 1024) { // > 500KB
|
||||
console.log(`⚠️ JS bundle is large (${jsSizeKB}KB). Consider:`);
|
||||
console.log(' - Code splitting');
|
||||
console.log(' - Dynamic imports');
|
||||
console.log(' - Removing unused imports');
|
||||
}
|
||||
|
||||
if (sortedAssets.length > 10) {
|
||||
console.log('✅ Good chunk splitting - multiple small files for better caching');
|
||||
}
|
||||
}
|
||||
|
||||
console.log('\n🎯 To analyze specific chunks, set ANALYZE_BUNDLE=true and rebuild');
|
||||
console.log('=====================================\n');
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Additional tree-shaking optimizations
|
||||
config.resolve = {
|
||||
...(config.resolve || {}),
|
||||
// Prioritize ES6 modules for better tree-shaking
|
||||
mainFields: ['module', 'browser', 'main'],
|
||||
// Add extensions for better resolution
|
||||
extensions: ['.js', '.mjs', '.wasm', '.json']
|
||||
};
|
||||
|
||||
// Mark packages as side-effect-free for better tree-shaking
|
||||
config.module = {
|
||||
...(config.module || {}),
|
||||
rules: [
|
||||
...(config.module && config.module.rules ? config.module.rules : []),
|
||||
{
|
||||
// Mark Kotlin-generated code as side-effect-free where possible
|
||||
test: /\.js$/,
|
||||
include: /kotlin/,
|
||||
sideEffects: false
|
||||
}
|
||||
]
|
||||
};
|
||||
@@ -1,48 +0,0 @@
|
||||
// Development server configuration with API proxy
|
||||
// This forwards API requests from webpack-dev-server to the gateway
|
||||
const path = require('path');
|
||||
|
||||
if (config.mode !== 'production') {
|
||||
config.devServer = {
|
||||
...config.devServer,
|
||||
|
||||
// Proxy API requests to the gateway - using modern object syntax
|
||||
proxy: {
|
||||
'/api/**': {
|
||||
target: 'http://localhost:8081',
|
||||
changeOrigin: true,
|
||||
secure: false,
|
||||
logLevel: 'debug',
|
||||
pathRewrite: {
|
||||
'^/api': '/api' // Keep the /api prefix for gateway routing
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Disable all caches as requested in previous issue
|
||||
headers: {
|
||||
'Cache-Control': 'no-cache, no-store, must-revalidate',
|
||||
'Pragma': 'no-cache',
|
||||
'Expires': '0'
|
||||
},
|
||||
|
||||
// Development middleware settings
|
||||
devMiddleware: {
|
||||
writeToDisk: false,
|
||||
stats: 'minimal'
|
||||
},
|
||||
|
||||
// Static files configuration
|
||||
/* static: {
|
||||
directory: path.resolve(__dirname, '../../build/dist/wasmJs/developmentExecutable'),
|
||||
serveIndex: true,
|
||||
watch: true
|
||||
},*/
|
||||
|
||||
// CORS settings for development
|
||||
allowedHosts: 'all',
|
||||
historyApiFallback: true,
|
||||
hot: true,
|
||||
liveReload: true
|
||||
};
|
||||
}
|
||||
@@ -1,122 +0,0 @@
|
||||
// WASM Bundle Size Optimization Configuration
|
||||
// Advanced Webpack configuration for smaller WASM bundles
|
||||
//const path = require('path');
|
||||
|
||||
// Bundle size optimization configuration
|
||||
config.optimization = {
|
||||
...(config.optimization || {}),
|
||||
// Enable aggressive tree shaking
|
||||
usedExports: true,
|
||||
sideEffects: true,
|
||||
|
||||
// Split chunks for better caching and smaller initial bundle
|
||||
splitChunks: {
|
||||
chunks: 'all',
|
||||
cacheGroups: {
|
||||
// Separate Skiko (Compose UI) into its own chunk
|
||||
skiko: {
|
||||
test: /[\\/]skiko[\\/]/,
|
||||
name: 'skiko',
|
||||
chunks: 'all',
|
||||
priority: 30,
|
||||
reuseExistingChunk: true,
|
||||
enforce: true
|
||||
},
|
||||
// Separate Ktor client into its own chunk
|
||||
ktor: {
|
||||
test: /[\\/]ktor[\\/]/,
|
||||
name: 'ktor',
|
||||
chunks: 'all',
|
||||
priority: 20,
|
||||
reuseExistingChunk: true
|
||||
},
|
||||
// Separate Kotlin stdlib into its own chunk
|
||||
kotlinStdlib: {
|
||||
test: /[\\/]kotlin[\\/]/,
|
||||
name: 'kotlin-stdlib',
|
||||
chunks: 'all',
|
||||
priority: 15,
|
||||
reuseExistingChunk: true
|
||||
},
|
||||
// Default vendor chunk for remaining dependencies
|
||||
vendor: {
|
||||
test: /[\\/]node_modules[\\/]/,
|
||||
name: 'vendors',
|
||||
chunks: 'all',
|
||||
priority: 10,
|
||||
reuseExistingChunk: true
|
||||
},
|
||||
// Application code chunk
|
||||
default: {
|
||||
name: 'app',
|
||||
minChunks: 2,
|
||||
priority: 5,
|
||||
reuseExistingChunk: true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Minimize bundle size - conditional based on mode
|
||||
minimize: config.mode === 'production'
|
||||
// Note: minimizer is automatically configured by Kotlin/JS
|
||||
};
|
||||
|
||||
// Performance optimization
|
||||
config.performance = {
|
||||
...(config.performance || {}),
|
||||
// Realistic hint limits for WASM bundles (which are naturally larger)
|
||||
maxAssetSize: 20000000, // 20MB for individual assets (WASM files can be large)
|
||||
maxEntrypointSize: 5000000, // 5MB for entrypoints
|
||||
hints: 'warning' // Show warnings but don't fail the build
|
||||
};
|
||||
|
||||
// Resolve optimization for faster builds
|
||||
config.resolve = {
|
||||
...(config.resolve || {}),
|
||||
// Skip looking in these directories to speed up resolution
|
||||
modules: ['node_modules'],
|
||||
// Cache module resolution
|
||||
cache: true
|
||||
};
|
||||
|
||||
// Module optimization
|
||||
config.module = {
|
||||
...(config.module || {}),
|
||||
// Disable parsing for known pre-built modules
|
||||
noParse: [
|
||||
/kotlin\.js$/,
|
||||
/kotlinx-.*\.js$/
|
||||
]
|
||||
};
|
||||
|
||||
// Development vs Production optimizations
|
||||
if (config.mode === 'production') {
|
||||
// Production-specific optimizations
|
||||
config.output = {
|
||||
...(config.output || {}),
|
||||
// Use conditional filename to match HTML template expectations for main chunk only
|
||||
filename: (chunkData) => {
|
||||
return chunkData.chunk.name === 'main' ? 'meldestelle-wasm.js' : '[name].[contenthash:8].js';
|
||||
},
|
||||
chunkFilename: '[name].[contenthash:8].chunk.js'
|
||||
};
|
||||
|
||||
// Additional production optimizations
|
||||
config.optimization = {
|
||||
...(config.optimization || {}),
|
||||
// Enable module concatenation (scope hoisting)
|
||||
concatenateModules: true,
|
||||
// Remove empty chunks
|
||||
removeEmptyChunks: true,
|
||||
// Merge duplicate chunks
|
||||
mergeDuplicateChunks: true
|
||||
};
|
||||
} else {
|
||||
// Development optimizations for faster builds
|
||||
config.cache = {
|
||||
type: 'filesystem',
|
||||
buildDependencies: {
|
||||
config: [__filename]
|
||||
}
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user