React Native打包Release APK时遇未声明变量警告求助
问题描述
按照React Native官方指南完成Android Release打包的全部步骤:生成keystore文件并放置到android/app目录,更新build.gradle与gradle.properties配置,执行./gradlew clean后运行./gradlew assembleRelease命令,却出现大量变量未声明的警告,涉及DebuggerInternal、setTimeout、fetch等常用全局变量。尝试移除第三方依赖包、创建全新React Native项目重新打包,问题仍然存在,需要解决该问题。
警告信息示例
android\app\build\generated\assets\createBundleReleaseJsAndAssets\index.android.bundle:2545:18: warning: the variable "DebuggerInternal" was not declared in function "__shouldPauseOnThrow" typeof DebuggerInternal !== 'undefined' && ^~~~~~~~~~~~~~~~ android\app\build\generated\assets\createBundleReleaseJsAndAssets\index.android.bundle:6203:7: warning: the variable "setTimeout" was not declared in function "logCapturedError" setTimeout(function () { ^~~~~~~~~~ android\app\build\generated\assets\createBundleReleaseJsAndAssets\index.android.bundle:4172:108: warning: the variable "nativeFabricUIManager" was not declared in function "onChange" ...lInstanceHandle ? (from && nativeFabricUIManager.setIsJSResponder(from.sta... ^~~~~~~~~~~~~~~~~~~~~ android\app\build\generated\assets\createBundleReleaseJsAndAssets\index.android.bundle:4784:21: warning: the variable "clearTimeout" was not declared in anonymous function " 114#" cancelTimeout = clearTimeout; ^~~~~~~~~~~~ android\app\build\generated\assets\createBundleReleaseJsAndAssets\index.android.bundle:8534:30: warning: the variable "__REACT_DEVTOOLS_GLOBAL_HOOK__" was not declared in anonymous function " 114#" if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ android\app\build\generated\assets\createBundleReleaseJsAndAssets\index.android.bundle:10903:5: warning: the variable "setImmediate" was not declared in function "handleResolved" setImmediate(function () { ^~~~~~~~~~~~ android\app\build\generated\assets\createBundleReleaseJsAndAssets\index.android.bundle:15187:12: warning: the variable "fetch" was not declared in anonymous function " 351#" fetch: fetch, ^~~~~ android\app\build\generated\assets\createBundleReleaseJsAndAssets\index.android.bundle:15188:14: warning: the variable "Headers" was not declared in anonymous function " 351#" Headers: Headers, ^~~~~~~ android\app\build\generated\assets\createBundleReleaseJsAndAssets\index.android.bundle:15189:14: warning: the variable "Request" was not declared in anonymous function " 351#" Request: Request, ^~~~~~~ android\app\build\generated\assets\createBundleReleaseJsAndAssets\index.android.bundle:15190:15: warning: the variable "Response" was not declared in anonymous function " 351#" Response: Response ^~~~~~~~ android\app\build\generated\assets\createBundleReleaseJsAndAssets\index.android.bundle:15347:24: warning: the variable "FileReader" was not declared in function "readBlobAsArrayBuffer" var reader = new FileReader(); ^~~~~~~~~~ android\app\build\generated\assets\createBundleReleaseJsAndAssets\index.android.bundle:15398:36: warning: the variable "Blob" was not declared in anonymous function " 362#" } else if (support.blob && Blob.prototype.isPrototypeOf(body)) { ^~~~ android\app\build\generated\assets\createBundleReleaseJsAndAssets\index.android.bundle:15400:40: warning: the variable "FormData" was not declared in anonymous function " 362#" } else if (support.formData && FormData.prototype.isPrototypeOf(body)) { ^~~~~~~~ android\app\build\generated\assets\createBundleReleaseJsAndAssets\index.android.bundle:15402:44: warning: the variable "URLSearchParams" was not declared in anonymous function " 362#" ...e if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body... ^~~~~~~~~~~~~~~ android\app\build\generated\assets\createBundleReleaseJsAndAssets\index.android.bundle:15521:26: warning: the variable "AbortController" was not declared in anonymous function " 368#" var ctrl = new AbortController(); ^~~~~~~~~~~~~~~ android\app\build\generated\assets\createBundleReleaseJsAndAssets\index.android.bundle:15655:23: warning: the variable "XMLHttpRequest" was not declared in anonymous function " 372#" var xhr = new XMLHttpRequest(); ^~~~~~~~~~~~~~ android\app\build\generated\assets\createBundleReleaseJsAndAssets\index.android.bundle:15200:71: warning: the variable "self" was not declared in anonymous function " 354#" ...undefined' && globalThis || typeof self !== 'undefined' && self || ^~~~ android\app\build\generated\assets\createBundleReleaseJsAndAssets\index.android.bundle:25801:27: warning: the variable "performance" was not declared in anonymous function " 676#" if ("object" === typeof performance && "function" === typeof performance.no... ^~~~~~~~~~~ android\app\build\generated\assets\createBundleReleaseJsAndAssets\index.android.bundle:25824:26: warning: the variable "navigator" was not declared in anonymous function " 676#" "undefined" !== typeof navigator && undefined !== navigator.scheduling && u... ^~~~~~~~~ android\app\build\generated\assets\createBundleReleaseJsAndAssets\index.android.bundle:25934:37: warning: the variable "MessageChannel" was not declared in anonymous function " 676#" };else if ("undefined" !== typeof MessageChannel) { ^~~~~~~~~~~~~~ android\app\build\generated\assets\createBundleReleaseJsAndAssets\index.android.bundle:25949:34: warning: the variable "nativeRuntimeScheduler" was not declared in anonymous function " 676#" ... = "undefined" !== typeof nativeRuntimeScheduler ? nativeRuntimeScheduler.... ^~~~~~~~~~~~~~~~~~~~~~ android\app\build\generated\assets\createBundleReleaseJsAndAssets\index.android.bundle:35242:34: warning: the variable "requestAnimationFrame" was not declared in function "start 9#" ... this._animationFrame = requestAnimationFrame(this.onUpdate.bind(this)); ^~~~~~~~~~~~~~~~~~~~~ android\app\build\generated\assets\createBundleReleaseJsAndAssets\index.android.bundle:59674:20: warning: the variable "URL" was not declared in function "createURL" return new URL(createHref(to), "http://localhost"); ^~~ android\app\build\generated\assets\createBundleReleaseJsAndAssets\index.android.bundle:60003:30: warning: the variable "DOMException" was not declared in function "push 4#" if (error instanceof DOMException && error.name === "DataCloneError") {
解决方案
这些警告本质是代码压缩工具(Terser)在处理RN打包后的bundle文件时,将全局变量误判为未声明的局部变量,以下是几种可行的解决方法:
方法1:配置Metro告知Terser全局变量
在项目根目录的metro.config.js中添加Terser的配置,指定这些变量为全局保留变量,避免压缩时触发警告:
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config'); const customConfig = { transformer: { minifierConfig: { mangle: { // 将所有出现警告的变量加入保留列表 reserved: [ 'DebuggerInternal', 'setTimeout', 'clearTimeout', 'setImmediate', 'fetch', 'Headers', 'Request', 'Response', 'FileReader', 'Blob', 'FormData', 'URLSearchParams', 'AbortController', 'XMLHttpRequest', 'self', 'performance', 'navigator', 'MessageChannel', 'nativeRuntimeScheduler', 'requestAnimationFrame', 'URL', 'DOMException', 'nativeFabricUIManager', '__REACT_DEVTOOLS_GLOBAL_HOOK__' ] }, compress: { // 可选:直接关闭未声明变量的警告(不影响功能) warnings: false } } } }; module.exports = mergeConfig(getDefaultConfig(__dirname), customConfig);
方法2:检查并对齐RN与Gradle版本兼容性
部分RN版本对Gradle插件版本有严格要求,版本不匹配可能导致打包时的全局变量注入异常:
- 打开
android/build.gradle,确认buildscript.ext.gradleVersion与RN版本匹配(例如RN 0.7x系列推荐使用Gradle 7.4.2+):
buildscript { ext { buildToolsVersion = "33.0.0" minSdkVersion = 21 compileSdkVersion = 33 targetSdkVersion = 33 gradleVersion = "7.4.2" // 对应RN 0.70+版本 } dependencies { classpath("com.android.tools.build:gradle:${gradleVersion}") // ...其他依赖 } }
- 同步Gradle配置后,重新执行
./gradlew clean && ./gradlew assembleRelease。
方法3:全局变量声明兜底
如果上述方法无效,可以在项目入口文件(如index.js或App.js)顶部显式声明这些全局变量,确保压缩工具能识别:
// 声明全局变量,避免Terser误判 global.DebuggerInternal = global.DebuggerInternal || undefined; global.setTimeout = setTimeout; global.clearTimeout = clearTimeout; global.setImmediate = setImmediate; global.fetch = fetch; global.Headers = Headers; global.Request = Request; global.Response = Response; global.FileReader = FileReader; global.Blob = Blob; global.FormData = FormData; global.URLSearchParams = URLSearchParams; global.AbortController = AbortController; global.XMLHttpRequest = XMLHttpRequest; global.self = global.self || global; global.performance = performance; global.navigator = navigator; global.MessageChannel = MessageChannel; global.nativeRuntimeScheduler = global.nativeRuntimeScheduler || undefined; global.requestAnimationFrame = requestAnimationFrame; global.URL = URL; global.DOMException = DOMException; global.nativeFabricUIManager = global.nativeFabricUIManager || undefined; global.__REACT_DEVTOOLS_GLOBAL_HOOK__ = global.__REACT_DEVTOOLS_GLOBAL_HOOK__ || undefined;
内容的提问来源于stack exchange,提问作者tehkum kanchwala
相关产品推荐
相关产品推荐

