react-native-svg-transformer
react-native-svg-transformer copied to clipboard
Semi dynamic import
Sorry if this is documented somewhere in an Issue but I can't seem to find it.
I'm trying to do something like this and get an Invariant Violation.
const ListItem = ({ icon: Icon }) => (
<View>
<Icon />
<View>
);
<ListItem icon={require('../path/to/yo-that.svg')} />
I'm also open to other ways of doing this as well that allow for a smidge of code reuse.
It doesn't seem like require()
syntax works at all 🤷♂
Closest I could get is declaring all the imports up top import MySvg1 from '...';
etc.
Thanks @spacesuitdiver! It looks indeed like the require
syntax is not supported at all. I have always been using import
, so I have not even noticed it.
I wonder if there is something in the Metro packager configuration that is related to this? https://facebook.github.io/metro/docs/en/configuration
@spacesuitdiver I'm importing svg files using require
, and it only works if I use default
attribute of the object returned by required
call.
So I think what you need is <ListItem icon={require('../path/to/yo-that.svg').default} />
@buzbohdan any idea how to get that working with flow and jest?
Flow throws the following error:
Cannot get `require(...).default` because property `default` is missing in `String` [1].Flow(InferError)
And Jest sees the SVG component as undefined using the supplied svgMock.js
.
I managed to get require(...).default
working in jest by using the following mock, but then importing the SVG results in { default: 'Svg' }
.
exports.default = 'Svg';
exports.default.ReactComponent = 'Svg';
I got it working with the following flow type definition and jest mock.
flow-typed/svg.js
// @flow
declare module SvgImageStub {
declare export default 'Svg';
}
.flowconfig
module.name_mapper='^[./a-zA-Z0-9$_-]+\.svg$' -> 'SvgImageStub'
__mocks__/svg.js
// @flow
const Svg = 'Svg';
export default Svg;
Now it works with both import ... from '...'
and require('...').default
.