kristerkari / react-native-svg-transformer

Import SVG files in your React Native project the same way that you would in a Web application.
MIT License
1.54k stars 116 forks source link

Error while bundling SVGs on Android after upgrading React Native from 0.67.5 to 0.74.0 #362

Open nallakshyams opened 1 week ago

nallakshyams commented 1 week ago

I recently upgraded my React Native project from version 0.67.5 to 0.74.0. Since the upgrade, I have been encountering an error while bundling SVGs on both Android and iOS.

Error:

BUNDLE  app/assets/images/accessibilityDark.svg ░░░░░░░░░░░░░░░░ 0.0% (0/1)
<--- Last few GCs --->

[72075:0x150008000]   174885 ms: Mark-sweep (reduce) 8095.1 (8239.5) -> 8095.1 (8239.5) MB, 6437.5 / 0.0 ms  (average mu = 0.243, current mu = 0.001) allocation failure; scavenge might not succeed
[72075:0x150008000]   181419 ms: Mark-sweep (reduce) 8098.0 (8241.4) -> 8098.0 (8242.4) MB, 6531.3 / 0.0 ms  (average mu = 0.129, current mu = 0.000) allocation failure; scavenge might not succeed

<--- JS stacktrace --->

FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory

Environment:

System:
  OS: macOS 14.4.1
  CPU: (12) arm64 Apple M3 Pro
  Memory: 3.72 GB / 18.00 GB
  Shell: version 5.9 (/bin/zsh)
Binaries:
  Node: version 18.20.2 (/opt/homebrew/opt/node@18/bin/node)
  Yarn: version 3.6.4 (/opt/homebrew/opt/node@18/bin/yarn)
  npm: version 10.5.0 (/opt/homebrew/opt/node@18/bin/npm)
  Watchman: version 2024.05.06.00 (/opt/homebrew/bin/watchman)
Managers:
  CocoaPods: version 1.15.2 (/opt/homebrew/bin/pod)
SDKs:
  iOS SDK:
    Platforms: DriverKit 22.2, iOS 16.2, macOS 13.1, tvOS 16.1, watchOS 9.1
  Android SDK:
    API Levels: 28, 33, 34
    Build Tools: 28.0.3, 30.0.3, 31.0.0, 34.0.0
    System Images: android-28 | Google APIs ARM 64 v8a, android-33 | Google APIs ARM 64 v8a, android-34 | Google APIs ARM 64 v8a
  Android NDK: Not Found
IDEs:
  Android Studio: 2023.2 AI-232.10300.40.2321.11668458
  Xcode: version 14.2/14C18 (/usr/bin/xcodebuild)
Languages:
  Java: version 17.0.11 (/usr/bin/javac)
  Ruby: version 2.7.8 (/opt/homebrew/opt/ruby@2.7/bin/ruby)
npmPackages:
  "@react-native-community/cli": Not Found
  react: installed 18.2.0, wanted 18.2.0
  react-native: installed 0.74.0, wanted 0.74.0
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: false
iOS:
  hermesEnabled: true
  newArchEnabled: false

Step(s) to Reproduce:

-Upgrade React Native from 0.67.5 to 0.74.0 and follow react-native-svg and react-native-svg-transformer docs.

Tried below but issue persist: 1.Attempt to bundle the project for Android using the following script: "bundle:android": "NODE_OPTIONS='--max_old_space_size=8192' npx react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res",

2.Attempt to increase the node memory using the following script: "start": "node --expose-gc --max-old-space-size=8192 node_modules/.bin/react-native start --reset-cache",

Additional Context:

The issue occurs only after the upgrade. It seems to be related to the memory allocation during the bundling process.

Any guidance or suggestions to resolve this issue would be greatly appreciated. Thank you!

kristerkari commented 1 week ago

Thanks @nallakshyams,

It's quite difficult to help out with your exact problem, but I suspect that something might have gone wrong when you updated react-native or react-native-svg to a newer version.

I have the example app for this library that is using the latest versions of both libraries: https://github.com/kristerkari/react-native-svg-example

nallakshyams commented 6 days ago

Thanks for the reply @kristerkari .

I am experiencing an out of memory error when bundling SVGs using react-native-svg-transformer. My project involves a large number of SVG images (around 300), and I have modified the code to dynamically import these images rather than importing each one as an independent component.

Code Implementation Here's a summary of my implementation:

App.js

import {SafeAreaView, ScrollView} from 'react-native';
import images from './images';
import ImageComponent from './ImageComponent';

type Props = {};
export default class App extends Component<Props> {
  render() {
    return (
      <SafeAreaView style={styles.container}>
        <ScrollView style={styles.scrollView} contentContainerStyle={styles.containerStyles}>
          <ImageComponent source={images.bower}/> 
          <ImageComponent source={images.composer}/>
          {/* Other components */}
        </ScrollView>
      </SafeAreaView>
    );
  }
}

const styles = {
  logo: {
    marginTop: 20,
    marginBottom: 20,
  },
  container: {
    flex: 1,
    justifyContent: 'flex-start',
    alignItems: 'center',
    backgroundColor: '#efefef',
  },
  scrollView: {
    width: '100%',
  },
  containerStyles: {
    display: 'flex',
    flexDirection: 'column',
    alignItems: 'center',
  },
};

images.js

const imageObjects = {
  bower: import('./logos/bower.svg'),
  composer: import('./logos/composer.svg'),
  //and so on for about 300 images
};

class Images {
  constructor() {
    this.ImageAssets = imageObjects;
  }

  static getInstance() {
    if (!this.instance) {
      this.instance = new Images();
    }
    return this.instance;
  }

  get bower() {
    return this.ImageAssets.bower;
  }

  get composer() {
    return this.ImageAssets.composer;
  }
  //and so on for about 300 images
}

const images = Images.getInstance();
export default images;

ImageComponent.js

import { View } from 'react-native';

const MyCustomImage = props => {
  const { source } = props;
  const DynamicComponent = React.lazy(() => source);
  return (
    <Suspense fallback={<View />}>
      <View>
        <DynamicComponent style={{marginTop: 20, marginBottom: 20}}/>
      </View>
    </Suspense>
  );
};

export default React.memo(MyCustomImage);

After modifying the code to dynamically import SVG images, Metro bundler throws an "out of memory" error when attempting to bundle these images. This issue arises particularly when dealing with a large number of images (around 300 in my case).

Request Could you please provide guidance on how to handle such a scenario effectively? Are there any recommended practices or adjustments that can be made to react-native-svg-transformer to accommodate large-scale SVG imports without running into memory issues?

Thank you for your assistance! @kristerkari

nallakshyams commented 3 days ago

Hi @kristerkari , On more observation. Even when importing just two images dynamically after altering the sample(https://github.com/kristerkari/react-native-svg-example) as mentioned above, the SVGs are being bundled in Metro. if i import SVG directly same as given in the example, i don't see they are bundled.