question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Correct way to set metro.config.js

See original GitHub issue

I added this library to the project long ago when there wasn’t metro.config.js file. I have just noticed when I upgraded React Native to version 0.64.1 that the metro.config.js is added to the create-react-native-app. So the file looks somethings like this:

module.exports = {
  transformer: {
    getTransformOptions: async () => ({
      transform: {
        experimentalImportSupport: false,
        inlineRequires: true,
      },
    }),
  },
};

and metro.config.js to use this library looks like this:

module.exports = (async () => {
  const {
    resolver: { sourceExts, assetExts },
  } = await getDefaultConfig();
  return {
    transformer: {
      babelTransformerPath: require.resolve('react-native-svg-transformer'),
    },
    resolver: {
      assetExts: assetExts.filter((ext) => ext !== 'svg'),
      sourceExts: [...sourceExts, 'svg'],
    },
  };
})();

so what I think the correct way to merge them together is something like this:

module.exports = (async () => {
  const {
    resolver: { sourceExts, assetExts },
  } = await getDefaultConfig();
  return {
    transformer: {
      getTransformOptions: async () => ({
        transform: {
          experimentalImportSupport: false,
          inlineRequires: true,
        },
      }),
      babelTransformerPath: require.resolve('react-native-svg-transformer'),
    },
    resolver: {
      assetExts: assetExts.filter((ext) => ext !== 'svg'),
      sourceExts: [...sourceExts, 'svg'],
    },
  };
})();

But this doesn’t work for me. It does build successfully, however, the screen is blank after the splash screen is gone. What works for me (the screen is not blank after staring up) is this:

module.exports = (async () => {
  const {
    resolver: { sourceExts, assetExts },
  } = await getDefaultConfig();
  return {
    transformer: {
      babelTransformerPath: require.resolve('react-native-svg-transformer'),
      experimentalImportSupport: false,
      inlineRequires: true,
    },
    resolver: {
      assetExts: assetExts.filter((ext) => ext !== 'svg'),
      sourceExts: [...sourceExts, 'svg'],
    },
  };
})();

But I’m not sure this is the correct way to paste those keys (experimentalImportSupport, inlineRequires).

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:17
  • Comments:7

github_iconTop GitHub Comments

61reactions
dpolivycommented, Sep 10, 2021

I was running into a few issues with the metro.config.js promoted in the README and our Expo app, so wanted to report back here with my experiences and resolution. We recently upgraded to Expo SDK 42 and EAS Build. With the recommended config in the README, I’d get this warning when trying to do a build:

It looks like that you are using a custom metro.config.js that does not extend @expo/metro-config.
This can result in unexpected and hard to debug issues, like missing assets in the production bundle.
We recommend you to abort, fix the metro.config.js, and try again.

This is fixed, as others mentioned above, by adding the assetPlugins prop to transformer – however, if this prop is missing, there may be others there that are missing as well. Here’s my modified metro.config.js which simply merges in the SVG fields into the existing config in the method documented by Expo in Customizing Metro.

I was also having issues with iOS builds not including assets, and I can now happily report this is resolved using the config below. Perhaps it’s time to update the README in this project with a new example?

const {getDefaultConfig} = require('expo/metro-config');

module.exports = (async () => {
    const config = await getDefaultConfig(__dirname);

    const {transformer, resolver} = config;

    config.transformer = {
        ...transformer,
        babelTransformerPath: require.resolve('react-native-svg-transformer'),
    };
    config.resolver = {
        ...resolver,
        assetExts: resolver.assetExts.filter(ext => ext !== 'svg'),
        sourceExts: [...resolver.sourceExts, 'svg'],
    };

    return config;
})();
10reactions
pangolingocommented, Aug 24, 2021

Using the recommended config, I encountered an error when using the expo-asset library. Expo Asset expects an assetPlugins transformer. Without it, there are no errors, but images don’t show up in iOS release builds.

I fixed it by adding the assetPlugins config. Figured I would mention it here because it might be worth documenting.

Original metro.config.js (based on this library’s documentation):

// Learn more https://docs.expo.io/guides/customizing-metro
const { getDefaultConfig } = require('expo/metro-config');

// extra config is needed to enable `react-native-svg-transformer`
module.exports = (async () => {
  const {
    resolver: { sourceExts, assetExts },
  } = await getDefaultConfig(__dirname);
  return {
    transformer: {
      babelTransformerPath: require.resolve('react-native-svg-transformer'),
    },
    resolver: {
      assetExts: assetExts.filter((ext) => ext !== 'svg'),
      sourceExts: [...sourceExts, 'svg'],
    },
  };
})();

Updated config to support Expo Assets:

// Learn more https://docs.expo.io/guides/customizing-metro
const { getDefaultConfig } = require('expo/metro-config');

// extra config is needed to enable `react-native-svg-transformer`
module.exports = (async () => {
  const {
    resolver: { sourceExts, assetExts },
  } = await getDefaultConfig(__dirname);
  return {
    transformer: {
      babelTransformerPath: require.resolve('react-native-svg-transformer'),
      assetPlugins: ['expo-asset/tools/hashAssetFiles'],
    },
    resolver: {
      assetExts: assetExts.filter((ext) => ext !== 'svg'),
      sourceExts: [...sourceExts, 'svg'],
    },
  };
})();

This line was added: assetPlugins: ['expo-asset/tools/hashAssetFiles'],

Read more comments on GitHub >

github_iconTop Results From Across the Web

Configuring Metro - Meta Open Source
A Metro config can be created in these three ways (ordered by priority):. metro.config.js; metro.config.json; The metro field in package.json.
Read more >
Metro bundler - Expo Documentation
You can customize the Metro bundler by creating a metro.config.js file at the ... First, install Terser in your project by running the...
Read more >
Expo - React Native - Metro Config File - Stack Overflow
We recommend you to abort, fix the metro.config.js, and try again. app.json. { "expo": { "name": "Unfiltered", "slug": ...
Read more >
@expo/metro-config - npm
A Metro config for running React Native projects with the Metro bundler. Latest version: 0.5.2, last published: 6 days ago.
Read more >
@expo/metro-config | Yarn - Package Manager
If you need to modify your Node modules manually, be sure to change the files in your lib/commonjs/ folder. ... cjs is added....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found