If anybody needs animated webP support with Expo (Custom Dev Client) for the native <Image />
and <FastImage />
(read comments):
// create a file like plugins/withAnimatedWebPSupport.js -> this is for the native <Image />
const {
createRunOncePlugin,
withGradleProperties
} = require('@expo/config-plugins');
const withAnimatedWebPSupport = (config) => {
const propertyToModify = {
type: 'property',
key: 'expo.webp.animated',
value: true,
};
return withGradleProperties(config, (config) => {
config.modResults = config.modResults.filter(
(item) => !(item.type === propertyToModify.type && item.key === propertyToModify.key)
);
config.modResults.push(propertyToModify);
return config;
});
};
module.exports = createRunOncePlugin(withAnimatedWebPSupport, 'animated-webp-support', '1.0.0');
// create a plugins/withFastImageWebPSupportAndroid.js - This is for `<FastImage />` Support
// note that this will need withAnimatedWebPSupport, because I've replaced it in that if-condition. Feel free to customize if you only want webP with FastImage
const {
withAppBuildGradle,
} = require("@expo/config-plugins");
const withCustomAppBuildGradle = (config) => {
const insertString = `implementation "com.github.zjupure:webpdecoder:2.0.4.12.0"`;
return withAppBuildGradle(config, (config) => {
if (
config.modResults.contents.includes(
insertString
)
) {
return config;
}
config.modResults.contents = config.modResults.contents.replace(
`if (isWebpAnimatedEnabled) {`,
`if (isWebpAnimatedEnabled) {
${insertString}`
);
return config;
});
};
module.exports = function withFastImageWebPSupportAndroid(config) {
config = withCustomAppBuildGradle(config);
return config;
};
// create a plugins/withFastImageWebPSupportIOS.js
const {
WarningAggregator,
withAppDelegate,
createRunOncePlugin
} = require('@expo/config-plugins');
const RNFI_EXPO_WEBP_IMPORT = `#import "AppDelegate.h"
// expo-config-plugin fast-image webp animated support
#import "SDImageCodersManager.h"
#import <SDWebImageWebPCoder/SDImageWebPCoder.h>
// end config plugin
`
const RNFI_EXPO_WEBP_DID_FINISH_LAUNCHING_IDENTIFIER = `- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{`
const RNFI_EXPO_WEBP_DID_FINISH_LAUNCHING_CODE = `
// start expo-config-plugin fast-image webp animated support
[SDImageCodersManager.sharedManager addCoder: SDImageWebPCoder.sharedCoder];
// end expo-config-plugin fast-image webp animated support
`
function modifyAppDelegate(appDelegate) {
if (!appDelegate.includes(RNFI_EXPO_WEBP_IMPORT)) {
appDelegate = appDelegate.replace(
/#import "AppDelegate.h"/g,
RNFI_EXPO_WEBP_IMPORT,
);
}
if (appDelegate.includes(RNFI_EXPO_WEBP_DID_FINISH_LAUNCHING_IDENTIFIER)) {
if (!appDelegate.includes(RNFI_EXPO_WEBP_DID_FINISH_LAUNCHING_CODE)) {
const block = RNFI_EXPO_WEBP_DID_FINISH_LAUNCHING_IDENTIFIER + RNFI_EXPO_WEBP_DID_FINISH_LAUNCHING_CODE
appDelegate = appDelegate.replace(RNFI_EXPO_WEBP_DID_FINISH_LAUNCHING_IDENTIFIER, block)
} else {
WarningAggregator.addWarningIOS('withFastImageWebPSupportIOSAppDelegate', `FastImage webP support already setup in AppDelegate`)
}
} else {
throw new Error('Failed to detect didFinishLaunchingWithOptions in AppDelegate')
}
return appDelegate
}
const withFastImageWebPSupportIOS = (config) => {
return withAppDelegate(config, (config) => {
if (['objc', 'objcpp'].includes(config.modResults.language)) {
config.modResults.contents = modifyAppDelegate(config.modResults.contents)
} else {
WarningAggregator.addWarningIOS('withFastImageWebPSupportIOSAppDelegate', `Cannot setup FastImage webP support, the project AppDelegate is not a supported language: ${config.modResults.language}`)
}
return config
})
}
module.exports = createRunOncePlugin(withFastImageWebPSupportIOS, 'rnfi-expo-animated-webp-support', '1.0.0');
Install plugin in your app.json / app.config.js (expo.plugins)
['./plugins/withAnimatedWebPSupport'],
['./plugins/withFastImageWebPSupportIOS.js'],
['./plugins/withFastImageWebPSupportAndroid.js'],
Based on other config plugins by @GollyJer, @wodin, @barthap, @EvanBacon and @nandorojo Thanks guys!
In case you only need native <Image />
support, just install this package:
https://github.com/Aleksefo/react-native-webp-format
and only use the withAnimatedWebPSupport Plugin for Android.
@GollyJer careful, the config-plugin does not currently work on iOS with Expo SDK 45. AppDelegate.m changed to .mm and there is currently no clean way to patch Swift App Delegate files. Might need to pick a brutforce method and patch it with FileSystem.