KMP项目中SQLDelight已配置generateAsync仍报异步驱动异常
KMP Web端SQLDelight异步Web Worker异常排查与修复
问题说明
在KMP项目Web端使用SQLDelight异步Web Worker驱动时,触发以下异常:
IllegalStateException: The driver used with SQLDelight is asynchronous, so SQLDelight should be configured for asynchronous usage
已在SQLDelight配置中设置generateAsync=true,依赖和DatabaseDriverFactory代码也按文档配置,但问题未解决。
现有配置与代码
SQLDelight配置
sqldelight { databases { create("MyDatabase") { packageName.set("com.example.projectname") generateAsync.set(true) } } }
依赖版本
- sqldelight = "2.0.1"
- web-worker-driver = { module = "app.cash.sqldelight:web-worker-driver", version.ref = "sqldelight" }
jsMain依赖
jsMain.dependencies { implementation(compose.html.core) implementation(libs.ktor.client.js) implementation(libs.web.worker.driver) implementation(devNpm("copy-webpack-plugin", "9.1.0")) implementation(npm("@cashapp/sqldelight-sqljs-worker", "2.0.0")) implementation(npm("sql.js", "1.8.0")) }
DatabaseDriverFactory实现
actual class DatabaseDriverFactory { private val mutex = Mutex() actual suspend fun createDriver(): SqlDriver { @Suppress("UnsafeCastFromDynamic") val driver = WebWorkerDriver( Worker(js("""new URL("@cashapp/sqldelight-sqljs-worker/sqljs.worker.js", import.meta.url)""")), ) mutex.withLock { MyDatabase.Schema.awaitCreate(driver) return driver } } }
修复方案
1. 统一依赖版本
当前SQLDelight核心版本为2.0.1,但配套的@cashapp/sqldelight-sqljs-worker使用2.0.0,版本不一致会导致内部API不兼容。将npm依赖版本同步为2.0.1:
implementation(npm("@cashapp/sqldelight-sqljs-worker", "2.0.1"))
2. 明确Web平台的异步生成配置
确保SQLDelight仅针对Web平台生成异步代码,避免多平台配置冲突。修改SQLDelight配置:
sqldelight { databases { create("MyDatabase") { packageName.set("com.example.projectname") // 为Web平台单独启用异步代码生成 target("js") { generateAsync.set(true) } // 其他平台保持同步配置(按需调整) target("jvm") { generateAsync.set(false) } } } }
3. 使用异步数据库实例API
生成异步代码后,必须使用异步构造方法初始化数据库,不能混用同步API:
// 错误:同步构造方法,会触发异常 // val database = MyDatabase(driver) // 正确:异步构造方法 val database = MyDatabase.invokeAsync(driver)
4. 清理构建缓存
KMP项目的Gradle缓存可能保留旧的同步代码,导致新生成的异步代码未生效。执行以下命令清理并重新构建:
./gradlew clean ./gradlew jsBrowserDevelopmentRun
5. 验证Web Worker文件路径
检查Webpack是否正确复制了worker文件到输出目录。构建完成后,查看build/js/packages/<你的项目名>/kotlin目录,确认sqljs.worker.js存在。如果缺失,需调整copy-webpack-plugin配置确保文件被复制。
内容的提问来源于stack exchange,提问作者Meet
相关产品推荐
相关产品推荐

