react-native-svg-transformer
react-native-svg-transformer copied to clipboard
work on the web, Warning: </static/media/splashScreen.0f923900.svg /> is using incorrect casing. Use PascalCase for React components, or lowercase for HTML elements.
I have installed in my project expo install react-native-svg.
I have exported the svg as a component by doing:
import Logo from './logo.svg';
export default Logo;
It can render on native but fail on the web.
bundle.js:69367 Warning: </static/media/splashScreen.0f923900.svg /> is using incorrect casing. Use PascalCase for React components, or lowercase for HTML elements.
I have followed that configuration https://github.com/react-native-community/react-native-svg#use-with-svg-files
My metro.config.js is equal:
const { getDefaultConfig } = require('metro-config');
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'],
},
};
})();
My app.json got added
{
+ "packagerOpts": {
+ "config": "metro.config.js",
+ "sourceExts": ["js", "jsx", "ts", "tsx", "svg"]
+ },
}
- react-native-svg 9.13.3
- react-native-svg-transformer 0.14.3
- SDK: 36 Documentation: https://docs.expo.io/versions/latest/sdk/svg/
This is quite blocking for doing web.
I have prepared a reproduction and I have found inconsistency with another project that is configured the same way:
kopax/expo-bug-reportsbranchissue-6660(travis) I have found inconsistency with another project that is configured the same way
svg/test.svg:
<svg height="100%" width="100%">
<rect fill="lime" width="100%" height="100%" />
</svg>
svg/index.js
import Svg from 'test.svg';
console.log(Svg)
export default Svg;
There are two issues:
- web:
console.log(Svg)does not return a component (it return for exampledata:image/svg+xml;base64,ICA8c3ZnIGhlaWdodD0iMTAwJSIgd2lkdGg9IjEwMCUiPgogICAgPHJlY3QgZmlsbD0ibGltZSIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgLz4KICA8L3N2Zz4=) - test: jest unit testing does not return a component (instead an integer and test always have
Platform.OS === 'ios'(why?))
While in the original project I was creating the issue for:
- web:
console.log(Svg)does not return a component (it return for example/static/media/logo.0e5dcfee.svg) - jest: unit testing does return a component (and
Platform.OS === 'ios')
Both work fine on iOS and Android.
I know from the past that @svgr and @svgr/webpack work perfectly for the web (normally with import { ReactComponent } from './test.svg';
Hi @kopax! I currently have no idea of how the Web side works in Expo. I think that I need to sit down and have a look at it.
There is an example app with Native + Web support, which does not use Expo, but uses Webpack + SVGR instead: https://github.com/kristerkari/react-native-svg-example
Thanks @kristerkari for your reply. I will post the expo webpack configuration of expo. I think this is due to this probably missing, I will let you know
https://github.com/kristerkari/react-native-svg-example/blob/master/webpack.config.js#L33
I just add a whole session around your example and the svgr documentation.
After multiple attempl, including a copy past of your webpack config, I still have a path when requiring an svg.
I have re-asked my question here : https://github.com/gregberge/svgr/issues/375
And opened an issue on expo here: https://github.com/expo/expo/issues/6660
But they closed it, so far nobody from any of the core libs want to dig into it at the moment.
Note that I have pasted in here the whole webpack configuration used by expo, and they had by default nothing configured between webpack and svgr.
Is it possible for the user of Expo to extend Expo's Webpack config? That way you could add the @svgr/webpack dependency and configure it.
Is it possible for the user of Expo to extend Expo's Webpack config?
Yes, it is possible as described here
That way you could add the
@svgr/webpackdependency and configure it.
I have already tried and it does not work at all. (see comment here)
Basically, this is how my webpack.config.js looks like : https://github.com/kopax/expo-bug-reports/blob/issue-6660/webpack.config.js
The whole reproduction (which is an expo blank project, nothing more) can be run:
git clone https://github.com/kopax/expo-bug-reports.git
cd expo-bug-reports
git checkout issue-6660
npm i
npm test
npm run web

Without the webpack.config.js, at least we can use the require return in <img />, while with @svgr/webpack, we can't (error remains the same)
Hello! I ran into the same issue while using the default Expo webpack config for web. You indeed have to extend the default config, but also modify some existing rules that would otherwise override @svgr/webpack. I posted a fix here: https://github.com/expo/expo/issues/6660#issuecomment-573506912
Thanks for looking into it @michaelgira23! Let's see if we manage to get some fix for the documentation to Expo or this repo, so that in the future it will be easier to use the same code for both Web and Native.
I have tested @michaelgira23 fix and it does work. To be near perfection, we should be able to decide if we import the url or the react component, usually with import svg, { ReactComponent } from './mysvg.svg';. This is already possible with svgr, and should be configured for native and webpack.
Yes this should definitely be included in the expo core configuration.
I'm doing this for now to make it work,
const Icon = ({ children }) => {
if (Platform.OS === 'web') {
return <img src={children.type} {...children.props} />;
}
return children;
};
<Icon>
<ArrowBackIcon width={32} height={32} />
</Icon>
Would just mention my comment here: https://github.com/expo/expo/issues/6660#issuecomment-1076338873
There is someone who has fixed this issue in this unpublished package: https://github.com/HolovisSoftwareDev/react-native-svg-transformer-fix-expo
See my comment for an example.
I can confirm it then works with latest Expo, react-native-svg and react-native-svg-transfomer on web, iOS and Android without the need to run Platform.OS checks when importing static svg files.
It is however not clear to me if this issue fix has to be implemented on the Expo side or in react-native-svg-transformer, but maybe you could take a look when you have time @kristerkari . This issue has been a huge pain for me, used several days troubleshooting, finally found a solution that works. But it would be nice to get rid of the unpublished fix package and just use react-native-svg and react-native-svg-transformer when using Expo, but the bug has to be fixed first.
Here's how I'm configured to do React Native plus React Native Web .svg file loading, using the react-native-svg-transformer and @svgr/webpack packages allowing for same import / use on both mobile and web. The SVGs are also resizable and can have their fill color changed (if you do no fill in the .svg)
metro.config.js
/**
* Metro configuration for React Native
* https://github.com/facebook/react-native
*
* @format
*/
const { getDefaultConfig } = require('metro-config');
module.exports = async () => {
const {
resolver: { sourceExts, assetExts },
} = await getDefaultConfig();
return {
transformer: {
babelTransformerPath: require.resolve('react-native-svg-transformer'),
getTransformOptions: async () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: false,
},
}),
},
resolver: {
assetExts: assetExts.filter(ext => ext !== 'svg'),
sourceExts: [...sourceExts, 'svg'],
},
};
};
webpack.config.js (excerpt)
...
const svgLoaderConfiguration = {
test: /\.svg$/i,
issuer: /\.[jt]sx?$/,
use: [{ loader: '@svgr/webpack', options: { typescript: true, dimensions: false } }],
};
...
Example use
import AppLogo from './assets/AppLogo.svg';
...
<AppLogo fill={'green'} width={100} height={100} />