react-native-svg-transformer icon indicating copy to clipboard operation
react-native-svg-transformer copied to clipboard

Semi dynamic import

Open spacesuitdiver opened this issue 5 years ago • 6 comments

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.

spacesuitdiver avatar Aug 12 '19 21:08 spacesuitdiver

It doesn't seem like require() syntax works at all 🤷‍♂

spacesuitdiver avatar Aug 12 '19 21:08 spacesuitdiver

Closest I could get is declaring all the imports up top import MySvg1 from '...'; etc.

spacesuitdiver avatar Aug 12 '19 21:08 spacesuitdiver

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

kristerkari avatar Aug 14 '19 21:08 kristerkari

@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 avatar Sep 17 '19 17:09 buzbohdan

@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';

geraintwhite avatar Dec 02 '20 11:12 geraintwhite

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.

geraintwhite avatar Dec 02 '20 12:12 geraintwhite