Reputation: 22923
I am trying to get the same import statements going for both a Vite and Webpack setup (used by Storybook) and I am failing to get it to work for Webpack as advertised.
According to the docs for @svgs/webpack
, version 5.5, this should work:
// Does not work (undefined)
import {ReactComponent as UilPlus} from '@iconscout/unicons/svg/line/plus.svg'
But it does not. There is only the default
export:
// Works
import UilPlus from '@iconscout/unicons/svg/line/plus.svg'
How can I fix this? I have even tried explicitly using the namedExport
option, but it does not take effect.
Config:
use: [
{
loader: '@svgr/webpack',
options: { namedExport: 'ReactComponent' }
},
$ jq .version node_modules/\@svgr/webpack/package.json
"5.5.0"
Upvotes: 2
Views: 4233
Reputation: 393
As said in doc of @svgr/webpack
, you should add url-loader
or file-loader
https://github.com/gregberge/svgr/tree/main/packages/webpack
{
test: /\.svg$/,
use: ['@svgr/webpack', 'url-loader'],
}
then you can use it in your code
import starUrl, { ReactComponent as Star } from './star.svg'
const App = () => (
<div>
<img src={starUrl} alt="star" />
<Star />
</div>
)
Upvotes: 1
Reputation: 22923
After reading the source code for v5.5 of @svgr/webpack
, @svgr/core
and @svgr/babel-plugin-transform-svg-component
and reading up on how loaders work, things finally made sense.
Turns out there was a crucial bit missing: the example showing use of ReactComponent
has an extra loader added for the svg processing. I did not understand how a loader added later could affect something earlier. That was until I read the loader docs for Webpack 4 which explains how loaders are applied Right to Left.
Once that was out of the way, it was now clear that the svgr plugin somehow sees that the input it receives is from another loader and adjusts it behavior accordingly. That is exactly what happens in @svgr/webpack
in line 32 to 41 and you can see the expected output in the snapshot test:
...
export default \\"data:image/svg+xml;base64,PD94bWwg..."
export { SvgIcon as ReactComponent };"```
The webpack module actually only does the detection and passes that info on to @svgr/core
, whereas the core module is using babel-plugin-transform-svg-component
to actually change the output based on the presence of a previous export.
Upvotes: 3