Created
January 4, 2023 23:15
-
-
Save grossadamm/b68a7d1f70d4884ecc760bc73107497b to your computer and use it in GitHub Desktop.
Use code push with expo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { AndroidConfig, withAppDelegate, withPlugins, withInfoPlist, withSettingsGradle, withAppBuildGradle, withMainApplication, withStringsXml } = require('@expo/config-plugins'); | |
function withCodePushAppDelegate(config) { | |
return withAppDelegate(config, (cfg) => { | |
const { modResults } = cfg; | |
const { contents } = modResults; | |
const lines = contents.split('\n'); | |
const importIndex = lines.findIndex((line) => | |
/^#import "AppDelegate.h"/.test(line) | |
); | |
const bundleURLIndex = lines.findIndex((line) => | |
line.includes('return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];') | |
); | |
modResults.contents = [ | |
...lines.slice(0, importIndex + 1), | |
'#import <CodePush/CodePush.h>', | |
// ...lines.slice(importIndex + 1) | |
...lines.slice(importIndex + 1, bundleURLIndex), | |
' return [CodePush bundleURL];', | |
...lines.slice(bundleURLIndex + 1), | |
].join('\n'); | |
return cfg; | |
}); | |
} | |
function applySettings(gradleSettings: string) { | |
const settings = `include ':react-native-code-push' | |
project(':react-native-code-push').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-code-push/android/app')` | |
// Make sure the project does not have the settings already | |
if (!gradleSettings.includes(`include ':react-native-code-push'`)) { | |
return gradleSettings + settings | |
} | |
return gradleSettings | |
} | |
function withCodePushSettingsGradle(config) { | |
return withSettingsGradle(config, (cfg) => { | |
cfg.modResults.contents = applySettings(cfg.modResults.contents) | |
return cfg | |
}) | |
} | |
function addApplies(appBuildGradle: string) { | |
const applies = `apply from: "../../node_modules/react-native/react.gradle" | |
apply from: "../../node_modules/react-native-code-push/android/codepush.gradle"` | |
// Make sure the project does not have the dependency already | |
if (!appBuildGradle.includes(applies)) { | |
return appBuildGradle.replace( | |
/apply from: new File(reactNativeRoot, "react.gradle")/, | |
`apply from: new File(reactNativeRoot, "react.gradle") | |
${applies}` | |
) | |
} | |
return appBuildGradle | |
} | |
function withCodePushBuildGradle(config) { | |
return withAppBuildGradle(config, (cfg) => { | |
cfg.modResults.contents = addApplies(cfg.modResults.contents) | |
return cfg | |
}) | |
} | |
function applyMainApplication(mainApplication: string) { | |
const packageImport = `import com.microsoft.codepush.react.CodePush;\n` | |
const jsBundle = `protected String getJSBundleFile() { | |
return CodePush.getJSBundleFile(); | |
}` | |
// Make sure the project does not have the settings already | |
if (!mainApplication.includes(packageImport)) { | |
mainApplication = mainApplication.replace( | |
/import android.app.Application;/, | |
`import android.app.Application;\n${packageImport}` | |
) | |
} | |
if (!mainApplication.includes("getJSBundleFile")) { | |
mainApplication = mainApplication.replace( | |
/protected String getJSMainModuleName\(\) {/, | |
`${jsBundle} | |
@Override | |
protected String getJSMainModuleName() {` | |
) | |
} | |
return mainApplication | |
} | |
function withCodePushMainApplication(config) { | |
return withMainApplication(config, (cfg) => { | |
cfg.modResults.contents = applyMainApplication(cfg.modResults.contents) | |
return cfg | |
}) | |
} | |
function withCodePushInfoPlist(config) { | |
return withInfoPlist(config, (cfg) => { | |
const { extra: { codePush: { production: { iosDeploymentKey }, codePushPublicKey } } } = cfg; | |
cfg.modResults.CodePushDeploymentKey = iosDeploymentKey; | |
cfg.modResults.CodePushPublicKey = codePushPublicKey; | |
return cfg; | |
}); | |
} | |
function withCodePushStringsXml(config) { | |
return withStringsXml(config, (cfg) => { | |
const { extra: { codePush: { production: { androidDeploymentKey }, codePushPublicKey } } } = cfg; | |
cfg.modResults = AndroidConfig.Strings.setStringItem( | |
[ | |
// XML represented as JSON | |
// <string name="CodePushDeploymentKey" moduleConfig="true">value</string> | |
{ $: { name: 'CodePushDeploymentKey', moduleConfig: 'true' }, _: androidDeploymentKey }, | |
], | |
cfg.modResults | |
); | |
cfg.modResults = AndroidConfig.Strings.setStringItem( | |
[ | |
// XML represented as JSON | |
// <string name="CodePushDeploymentKey">value</string> | |
{ $: { name: 'CodePushPublicKey' }, _: codePushPublicKey }, | |
], | |
cfg.modResults | |
); | |
return cfg; | |
}); | |
} | |
function withCodePush(config) { | |
return withPlugins(config, [ | |
withCodePushAppDelegate, | |
withCodePushInfoPlist, | |
withCodePushSettingsGradle, | |
withCodePushBuildGradle, | |
withCodePushMainApplication, | |
withCodePushStringsXml | |
]); | |
} | |
export default withCodePush; | |
// { | |
// "expo": { | |
// "extra": { | |
// "codePush": { | |
// "production": { | |
// "iosDeploymentKey": "iosDeploymentKey", | |
// "androidDeploymentKey": "androidDeploymentKey" | |
// }, | |
// "codePushPublicKey": "codePushPublicKey" | |
// } | |
// } | |
// } | |
// |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment