reactjs - Jest: SVG-krav orsakar "SyntaxError: Oväntad token <"


Osäker på var man ska leta efter detta fel.

Att använda Typescript med React, samt Jest och Enzyme för enhetstestning.

Exempel på package.json:

"scripts": {
    "start": "node server.js",
    "bundle": "cross-env NODE_ENV=production webpack -p",
    "test": "jest"
  },
  "jest": {
    "transform": {
      "^.+\\.tsx?$": "<rootDir>/node_modules/ts-jest/preprocessor.js"
    },
    "testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$",
    "moduleFileExtensions": [
      "ts",
      "tsx",
      "js",
      "json"
    ]
  }

Att köra npm test resulterar i:

FAIL src/components/Component.test.tsx

 ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){<?xml version="1.0" encoding="UTF-8"?>
                                                                                             ^

    SyntaxError: Unexpected token <

Redigera: Det verkar hända på det första stället där jag använder require för att ladda en statisk .svg-fil. Varför kan det inte hantera det? Finns det ett sätt att ignorera att detta fel kastas när man använder require?

Svar #1

Jest använder inte Webpack, så det vet inte hur man laddar andra filändelser än js/jsx. För att lägga till stöd för andra ändelser behöver du skriva egna transformatorer. En av transformatorerna är en Typescript-transformator som du har definierat i din konfiguration i detta fragment:

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

Nu behöver du lägga till transformator för SVG-filer. Låt oss utöka din Jest-konfiguration

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

och skapa filen svgTransform.js i din rotkatalog med följande innehåll

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

Självklart, det är en grundläggande transformer som alltid returnerar samma värde.

Länk till dokumentationen: https://jestjs.io/docs/configuration#transform-objectstring-pathtotransformer--pathtotransformer-object

Svar #2

Om du har använt @svgr/webpack-modulen för att låta webpack hantera import av svgs tillhandahåller @svgr en sida som går igenom hur man hanterar testning med Jest. Resurs här

Kopierad för eftervärlden.

/__mocks__/svgrMock.js
import * as React from 'react'
export default 'SvgrURL'
export const ReactComponent = 'div'

I package.json

"jest": {
  "moduleNameMapper": {
    "\\.svg": "<rootDir>/__mocks__/svgrMock.js"
  }
}

Relaterade artiklar