11
votes

In my app I use React and TypeScript. I tried to run jest tests I get following error:

C:\Users\e-KDKK\workspace\konrad\mikskarpety\src\images\icons\Sock.svg:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){<svg xmlns="http://www.w3.org/2000/svg" width="18.725" height="23.947" viewBox="0 0 18.725 23.947">
                                                                                         ^

SyntaxError: Unexpected token <

  1 | import React, { FC } from 'react';
  2 | 
> 3 | import SockIcon from '../../images/icons/Sock.svg';
    | ^
  4 | 
  5 | export const Spinner: FC = () => {
  6 |   return (

  at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/ScriptTransformer.js:537:17)
  at ScriptTransformer.transform (node_modules/@jest/transform/build/ScriptTransformer.js:579:25)
  at Object.<anonymous> (src/components/Spinner/Spinner.tsx:3:1)

This file is not even tested. I don't know why it tries to compile it. My jest.config.json file contains only coverage thresholds.

I read that jest sometimes needs additional transform section for specific files like SVG, but when I added to configuration

"transform": {
    "^.+\\.svg$": "jest-svg-transformer"
},

my error message changed only to:

C:\Users\e-KDKK\workspace\konrad\mikskarpety\test\utils\debounce.test.ts:1 ({"Object.":function(module,exports,require,__dirname,__filename,global,jest){import { getVersion } from 'jest'; ^

SyntaxError: Unexpected token {

  at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/ScriptTransformer.js:537:17)
  at ScriptTransformer.transform (node_modules/@jest/transform/build/ScriptTransformer.js:579:25)

Which is even more confusing to me.

The code for the app you can find here: https://github.com/KonradKlimczak/mikskarpety

6

6 Answers

29
votes

jest doesn't know how to load other file extensions than js/jsx,you need to find the jest.config.js and add transformer for svg files.

"transform": {
   "^.+\\.tsx?$": "<rootDir>/node_modules/ts-jest/preprocessor.js",
   "^.+\\.svg$": "<rootDir>/svgTransform.js"
},

and create the svgTransform.js file (see Custom transformers) in your root directory with the following content.

module.exports = {
    process() {
        return 'module.exports = {};';
    },
    getCacheKey() {
        // The output is always the same.
        return 'svgTransform';
    },
};

link:https://jestjs.io/docs/en/configuration.html#transform-object-string-string

14
votes

Another easier option to solve this problem is jest-svg-transformer.

Just install it: npm i jest-svg-transformer or yarn add jest-svg-transformer

And add to the jest.config.js to the transform's section:

"transform": {
   ...
   "^.+\\.svg$": "jest-svg-transformer"
}
7
votes

Another option (not specific to React) is to use jest-transform-stub since that will work for any non-JS file you want.

{
  "jest": {
    // ..
    "transform": {
      "^.+\\.js$": "babel-jest",
      ".+\\.(svg|css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$": "jest-transform-stub"
    }
  }
}
2
votes

If you are still looking for a easy solution you can define your mock file as this

// svgMock.js
var createReactClass = require('create-react-class');

var Greeting = createReactClass({
  render: function() {
    return null;
  }
});
module.exports = Greeting;

Then in jest.config file do

{
    "moduleNameMapper": {
        "^.+\\.svg$": "<rootDir>/__mocks__/svgMock.js"
    }
}
1
votes

Importing *.svg from node_modules?

I had the same problem when importing *.svg files from an icon library in node_modules1. Using jest-transform-stub in the "transform" section of jest.config.js did not work for me, I had to use it in the "moduleNameMapper" section instead.

What helped for me was (in jest.config.js):

module.exports = {
  ...
  moduleNameMapper: {
    '^.+.(svg)$': 'jest-transform-stub',
  }
};

1 The reason for this can be found in jest-transform-stub's README.

Jest doesn't apply transforms to node_modules by default. You can solve this by using moduleNameMapper.

0
votes

While using jest-svg-transformer, for the setup I had it didn't work when placed under the transformer section. So I had to add it under moduleNameMapper and it worked.

yarn add jest-svg-transformer --dev
 moduleNameMapper: {
    "^.+\\.svg$": "jest-svg-transformer",
  }