How to add code to native using expo-bare-react-native-app
For situations where you need to verify the generated platform files, the expo-bare-react-native-app repository is available. This repository can be used to test builds and confirm that app configurations are functioning as expected.
Get Started
Clone the
expo-bare-react-native-apprepositoryInstall all dependencies using
yarn installAdd your plugin to
packages/pluginsdirectoryCreate an
app.plugin.jsfile at the root of your plugin with the following content:module.exports = function customExportFunction(config) {
return config;
};Update the
expo_pluginsarray inappmaker.package.plugin.jsonto include the path to your plugin'sapp.plugin.jsfile:{
"expo_plugins": [
"@appmaker-xyz/plugins/my-plugin-1/app.plugin.js",
"@appmaker-xyz/plugins/my-plugin-2/app.plugin.js",
"@appmaker-xyz/plugins/my-plugin-2/app.plugin.js",
]
}Run
expo prebuildto generate platform files with your custom configuration
After completing these steps, you should be able to see your custom configuration within the generated platform files.
Configuring platform files
Under the hood, this is using expo-config-plugins to generate the paltform files. You can learn more about it here
For Android (build.gradle)
To add a new implementation in the build.gradle file, you can modify your app.plugin.js file as follows:
const { withAppBuildGradle } = require('@expo/config-plugins');
const PATH_TO_ADD = `implementation("com.facebook.react:react-android")`;
const withCustomAppBuildGradleImplementation = (
config,
{ implementationPackage },
) => {
return withAppBuildGradle(config, (config) => {
if (config.modResults.contents.includes(implementationPackage)) {
return config;
}
config.modResults.contents = config.modResults.contents.replace(
PATH_TO_ADD,
`${PATH_TO_ADD}
${implementationPackage}`,
);
return config;
});
};
module.exports = function withCustom(config) {
config = withCustomAppBuildGradleImplementation(config, {
implementationPackage: 'implementation("com.custom:app-android-sdk:12.5.06")',
});
return config;
};
How it works
- The code first checks if the specified implementation is already present in the
build.gradlefile. - If the implementation is not found, it adds the new implementation to the file.
- It uses the
withAppBuildGradlemethod to modify thebuild.gradlefile. - Inside the
withAppBuildGradlemethod, it locates the stringimplementation("com.facebook.react:react-android")and adds the new implementation directly below it.
This approach ensures that your custom implementation is added to the build.gradle file without duplicating existing entries, and places it in a specific location within the file.
For iOS (Info.plist)
To add new entries in the Info.plist file, you can modify your app.plugin.js file as follows:
const { withInfoPlist } = require('expo/config-plugins');
module.exports = function myCustomExpoFunctionName(config) {
config = withInfoPlist(config, (config) => {
// Type 1: Adding a String
config.modResults['YourCustomMessageKey'] = 'Your custom message';
// Type 2: Adding a Dictionary
config.modResults.MyCustomDictionary = {
MY_FIRST_KEY: 'My first value',
MY_SECOND_KEY: 'My second value'
};
// Type 3: Adding an Array
config.modResults.MyCustomArray = ['My first value', 'My second value'];
return config;
});
return config;
};
How it works
- The code uses the
withInfoPlistmethod from Expo's config plugins to modify theInfo.plistfile. - It demonstrates three types of modifications: adding a string, a dictionary, and an array.
- For each type, it directly modifies the
config.modResultsobject, which represents the contents of theInfo.plistfile. - The changes are applied without checking for existing entries, so be cautious to avoid overwriting important existing configurations.
Modifying MainApplication.java and AppDelegate.m
You can find the guides for injecting code into AppDelegate.m and MainApplication.java.