React Native build release APK Error: duplicate resource
問題說明
在更新到 0.60 之後打包 android release APK 時遇到了這樣的錯誤:Error: Duplicate resources
主要的問題是在進行 react-native bundle 指令時會重複的打包資源,因此在後續打包 APK 時出現錯誤
解決方式
主要的解決方法是在 react-native library 的 react.gradle
檔案中找到 doFirst
程式區塊,並在下方加入一段 doLast
程式碼來避免重複的打包資源
node_modules/react-native/react.gradle
1 | doFirst { |
由於這個方法是直接對 node_module 進行修改,當重新安裝 node_module 時,修改過的設定就會被蓋掉,為了避免重複的修改行為,我們可以利用 script 和 postinstall 設定來自動化。
建立一個新資料夾
fixAndroid
,在資料夾新增一個檔案android-gradle-fix
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17doLast {
def moveFunc = { resSuffix ->
File originalDir = file("${resourcesDir}/drawable-${resSuffix}")
if (originalDir.exists()) {
File destDir = file("${resourcesDir}/drawable-${resSuffix}-v4")
ant.move(file: originalDir, tofile: destDir)
}
}
moveFunc.curry("ldpi").call()
moveFunc.curry("mdpi").call()
moveFunc.curry("hdpi").call()
moveFunc.curry("xhdpi").call()
moveFunc.curry("xxhdpi").call()
moveFunc.curry("xxxhdpi").call()
}
// Set up inputs and outputs so gradle can cache the result在
fixAndroid
資料夾中再建立一個檔案android-release-fix.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21const fs = require('fs')
try {
var curDir = __dirname
var rootDir = process.cwd()
var file = `${rootDir}/node_modules/react-native/react.gradle`
var dataFix = fs.readFileSync(`${curDir}/android-gradle-fix`, 'utf8')
var data = fs.readFileSync(file, 'utf8')
var doLast = "doLast \{"
if (data.indexOf(doLast) !== -1) {
throw "Already fixed."
}
var result = data.replace(/\/\/ Set up inputs and outputs so gradle can cache the result/g, dataFix);
fs.writeFileSync(file, result, 'utf8')
console.log('Android Gradle Fixed!')
} catch (error) {
console.error(error)
}修改
package.json
加入postinstall
script1
2
3...
"postinstall": "node ./fixAndroid/android-release-fix.js"
...
postInstall 指令會在每次 node_module 安裝結束後執行
這樣就能在重新安裝 node_module 後自動重新加入修復的 doLast
程式碼
參考資源: https://gist.github.com/maiquemalmeida/2f0df4a5ab79c9d4a25dc142633ac3c1