Kotlin/JS项目使用Dukat生成Firebase声明后出现Uncaught ReferenceError: firebase is not defined问题排查求助
从你的报错信息Package path . is not exported from package /.../firebase来看,核心问题出在Firebase v9+的模块化结构和Dukat生成的声明文件不匹配,导致webpack无法正确解析Firebase的导入路径。下面是一步步的排查和解决方法:
1. 确认Firebase版本与模块化特性
Firebase从v9开始采用了ES模块化设计,不再默认导出整个firebase包,而是要求导入具体的子模块(比如firebase/app、firebase/auth等)。你的报错正是因为代码尝试导入根路径firebase,但这个路径在v9+的package.json的exports字段里并未被导出。
2. 修正Dukat生成的声明文件
Dukat生成的声明文件可能默认使用了旧的导入路径,需要手动调整:
- 找到生成的声明文件顶部的
@file:JsModule注解,把@file:JsModule("firebase")改成@file:JsModule("firebase/app") - 如果声明里还有其他Firebase服务的引用(比如Firestore),对应的模块也要改成
firebase/firestore等具体路径 - 同时确保声明文件里的
@JsNonModule注解(如果有的话)也适配新的导入方式,比如:@file:JsModule("firebase/app") @file:JsNonModule @file:Suppress("NON_EXTERNAL_DECLARATION_IN_INAPPROPRIATE_FILE") package firebase.app
3. 调整Kotlin代码的导入逻辑
在你的Kotlin代码中,确保Firebase相关的API是从正确的模块导入的。比如初始化App的代码,应该对应firebase/app的导出:
@JsModule("firebase/app") @JsNonModule external fun initializeApp(config: dynamic): FirebaseApp
如果之前是通过Dukat生成的声明导入,确认声明里的函数已经关联到正确的模块路径。
4. 验证webpack的模块解析
Kotlin JS默认的webpack配置通常能处理ES模块,但可以做以下检查:
- 查看项目
build/js/node_modules/firebase/package.json里的exports字段,确认./app是被导出的路径 - 如果需要,可以在项目的
webpack.config.d目录下添加自定义配置,确保webpack能正确解析Firebase的模块:module.exports = { resolve: { extensions: ['.js', '.json'], alias: { 'firebase/app': require.resolve('firebase/app') } } };
5. 尝试显式导入Firebase模块
如果上述方法无效,可以在Kotlin代码中显式导入Firebase模块,强制webpack将其打包:
fun main() { // 显式导入,确保webpack捕获到这个依赖 val firebaseAppModule = require("firebase/app") val firebaseConfig: Json = json(...) val fire = initializeApp(firebaseConfig) // ... 其他代码 }
注意这里的require路径必须是firebase/app,而不是firebase。
6. 排查DCE(Dead Code Elimination)问题
Kotlin JS的DCE可能会误判Firebase代码为无用代码而剔除,可以尝试临时关闭DCE来验证:
- 在
build.gradle.kts中修改Kotlin JS插件配置:kotlin.js { browser { binaries.executable() dceTask { dceMode = org.jetbrains.kotlin.gradle.targets.js.dce.DceMode.DISABLED } } }
如果关闭DCE后问题消失,说明需要调整DCE的规则,保留Firebase相关的代码。
内容的提问来源于stack exchange,提问作者jlengrand

