Webpack not able to import React component with `<svg`> tag

Viewed 974

I have a standard React funtional component which exports a SVG as so;

SomeSVG.js

import React from 'react';

const SomeSVG = props => (
  <svg width={24} height={24} {...props}>...</svg>
)

export default SomeSVG;

When using this in Create React App, works fine. Nice inlined SVG where it was expected to be.

Now I'm trying to use this in another project, with a custom webpack setup. But I get the error;

    Module parse failed: Unexpected token (4:2)
    You may need an appropriate loader to handle this file type.
    | 
    | const SomeSVG = props => (
    >   <svg width={24} height={24} {...props}>

I imagine I need to have a webpack loader than can support these, my existing webpack settings for JS/JSX/SVG

        {
          test: /\.jsx?$/,
          exclude: /node_modules/,
          use: [
            'babel-loader?cacheDirectory=true',
            'eslint-loader'
          ]
        },
        {
          test: /\.svg$/,
          loader: 'file-loader',
          options: {
            name: 'assets_seller/[name].[ext]'
          }
        },

(I don't think the SVG part is revelant but I'll include it for completeness)

I've tried react-svg-loader as a loader as well with and without options;

        {
          test: /\.jsx?$/,
          exclude: /node_modules/,
          use: [
            'babel-loader?cacheDirectory=true',
            {
              loader: "react-svg-loader",
              options: {
                jsx: true // true outputs JSX tags
              }
            },
            'eslint-loader'
          ]
        },

But that errors as well

NonErrorEmittedError: (Emitted value instead of an instance of Error) Error in parsing SVG: Non-whitespace before first tag.

My .babelrc config

{
  "presets": [
    [
      "@babel/preset-env", {
        "modules": false
      }
    ],
    "@babel/preset-react"
  ],
  "plugins": [
    "@babel/plugin-transform-modules-commonjs",
    "transform-async-to-generator",
    "syntax-dynamic-import",
    "universal-import",
    "@babel/plugin-transform-exponentiation-operator"
  ]
}

Any ideas would be greatly appriciated.

EDIT: I upgraded Webpack and it's plugins to the latest versions beforehand.

1 Answers

This issue is not related with how babel/webpack handles the SVG but, it's because the (Expo?) webpack config it's not transforming the JSX from the react-svg-main package because of configuration settings (webpack.config.js).

Furthermore, when you add it to the list, the compile process finishes, but the components are not there in runtime because the dependency isn't included and it will never work in this environment (Attempted import error: 'SvgXml' is not exported from react-native-svg).

I will try to update this response & send a pull request to the affected project.

I think I can get this working if I make some changes in the react-svg-main project...

In my case, this is a problem while trying to run an Expo project with web/browser.

Related