svg-react-loader: "Reference Error: React is not defined" with server side rendering. How to implement in an isomorphic context?

Hi!

This is likely just a configuration issue on my part, but I’m getting the following error message when attempting to use this loader in an isomorphic react app:

error:

/Users/Tom/Code/src/svg/circle.inline.svg:3
React.createElement(
^

ReferenceError: React is not defined
    at Object.<anonymous> (circle.inline.svg:1:1)
    at Module._compile (module.js:413:34)
    at loader (/Users/Tom/Code/node_modules/babel-register/lib/node.js:148:5)
    at Object.require.extensions.(anonymous function) [as .js] (/Users/Tom/Code/node_modules/babel-register/lib/node.js:158:7)
    at Module.load (module.js:357:32)
    at Function.Module._load (module.js:314:12)
    at Module.require (module.js:367:17)
    at require (internal/module.js:16:19)
    at Object.<anonymous> (BlockAdComponent.js:3:1)
    at Module._compile (module.js:413:34)

webpack loader config:

      {
        test: /\.inline.svg$/,
        loader: 'babel!svg-react',
      },

contents of SVG file:

<svg
  version="1.1"
  xmlns="http://www.w3.org/2000/svg"
  x="0px"
  y="0px"
  viewBox="0 0 100 100"
  enable-background="new 0 0 100 100"
>
  <circle
    className="svg-inline-circle"
    cx="50"
    cy="50"
    r="48"
  >
  </circle>
</svg>

simplified example of how the SVG is being imported:

import React from 'react';
import Circle from 'svg/circle.inline.svg';

class BlockComponent extends React.Component {

  render() {
    const { config, swipeArrows } = this.props;
    return (
      <div>
        <Circle className="block-ad__circle" />
      </div>
    );
  }
}

export default BlockComponent;

The setup instructions I followed were from this guide (method 2)

Environment is: Node: 5.5.0 NPM: 2.15.9 Webpack: 1.13.1 React: 0.14.0 svg-react-loader: 0.3.7 Express: 4.14.0

A coworker had this working on his local via a simple webpack-dev-server, however while attempting to implement it into an isomorphic react context (express server backened), I am now getting this error.

If you need any other info from me please feel free to ask. Any help much appreciated.

About this issue

  • Original URL
  • State: open
  • Created 8 years ago
  • Reactions: 4
  • Comments: 22 (6 by maintainers)

Most upvoted comments

meet this problem,try:

plugins: [
  new webpack.ProvidePlugin({
    "React": "react",
  }),
],

OK, I worked it out. When testing with Mocha, it’s not even using the webpack config. So mocha on it’s own just doesn’t know how to handle a raw SVG file being imported as it isn’t a javascript file. I don’t quite understand why it was failing on React.createElement within the SVG as that kind of implies the loader has converted it, but can’t find a dependency? Perhaps the error isn’t correct?

Either way, I found 2 ways around it. Option 1 is to use mocha-webpack and compile everything with webpack before testing. I didn’t go down that path though.

Option 2 is what I have done and is to remove the SVG extension from those that are imported with mocha and use babel-plugin-rewire to overwrite the import statement for the SVG. The whole thing looks like this now:

  • My mocha command in package.json

"test": "mocha tools/test-setup.js \"src/**/*.spec.js\" --reporter progress"

  • My test-setup.js file
require('babel-register')({
  plugins: ['babel-plugin-rewire']
})
require.extensions['.svg'] = () => null;
  • Then in a test file, then do something like…
import ComponentUnderTest from './ComponentUnderTest'
ComponentUnderTest.__Rewire__('SVGImport', () => <p>SVGPlaceholder</p>);

Any ideas? Think the root issue is it’s unclear how to implement this in an isomorphic (server side) environment.

Similar issue with svg-sprite-loader. I found a solution that I think might help https://github.com/kisenka/svg-sprite-loader/issues/40