You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 16:00:51