0

Jest: Ошибка "SyntaxError: Unexpected token <" при использовании require для SVG

1

Не уверен, куда обратиться по поводу этой ошибки.

Использую Typescript с React, а для юнит-тестирования — Jest и Enzyme.

Пример файла 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"
    ]
  }

При запуске команды npm test возникает ошибка:

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 <

Редактирование: Похоже, это происходит в том месте, где я использую require для загрузки статического файла .svg. Почему он не может это обработать? Существует ли способ игнорировать эту ошибку при использовании require?

4 ответ(ов)

0

Jest не использует Webpack, поэтому не знает, как загружать файлы с другими расширениями, кроме js/jsx. Чтобы добавить поддержку других расширений, вам нужно написать свои собственные трансформаторы. Один из трансформаторов — это трансформатор для TypeScript, который вы уже определили в вашей конфигурации в следующем фрагменте кода:

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

Теперь вам нужно добавить трансформатор для файлов SVG. Давайте расширим вашу конфигурацию Jest:

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

Также создайте файл svgTransform.js в корневом каталоге вашего проекта со следующим содержимым:

module.exports = {
  process() {
    return { code: 'module.exports = {};'}; // базовый трансформатор, возвращающий постоянное значение
  },
  getCacheKey() {
    // Выход всегда будет одинаковым.
    return 'svgTransform';
  },
};

Этот базовый трансформатор всегда возвращает одно и то же значение.

Ссылка на документацию: Jest Configuration - Transform.

0

Вы можете использовать пакет npm jest-transform-stub для этого. В файл конфигурации Jest добавьте следующий преобразователь:

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

Такой же преобразователь можно использовать для любых файлов ресурсов. Например:

"transform": {
  ...
  "^.+\\.(css|less|sass|scss|png|jpg|gif|ttf|woff|woff2|svg)$": "jest-transform-stub",
  ...
}

Это позволит Jest правильно обрабатывать указанные типы файлов во время тестирования.

0

Чтобы замокировать ваши SVG файлы в Jest, выполните следующие шаги:

  1. Создайте файл для моков SVG, например, __mocks__/svgMock.js, с содержимым, подобным приведенному ниже:
import React from "react";

export default "SvgURL";

export const ReactComponent = ({ width, height }) => (
  <div>
    w-{width} h-{height}
  </div>
);

Этот файл будет использоваться для замены реальных SVG файлов в тестах.

  1. Укажите Jest, где искать этот мок, добавив соответствующее свойство в ваш jest.config.js:
moduleNameMapper: {
  "\\.svg": "<rootDir>/__mocks__/svgMock.js",
},

Таким образом, когда Jest встретит импорт SVG файла, он будет использовать созданный вами мок вместо реального SVG, что упростит тестирование ваших компонентов.

0

Чтобы настроить обработку файлов SVG в Jest, вам нужно отредактировать файл jest.config.js, который находится в корневом каталоге вашего проекта.

Добавьте следующую строку внутрь объекта transform:

'^.+\\.svg$': './svgTransform.js'

Теперь ваш файл jest.config.js должен выглядеть следующим образом:

module.exports = {
  rootDir: '.',
  testEnvironment: 'jsdom',
  transform: {
    '^.+\\.(j|t)sx?$': 'babel-jest',
    '^.+\\.svg$': './svgTransform.js',
  },
  //...
}

После этого создайте файл с именем svgTransform.js в корневом каталоге проекта и добавьте в него следующий код:

module.exports = {
  process() {
    return 'module.exports = {};'
  },
  getCacheKey() {
    // Вывод всегда одинаковый.
    return 'svgTransform'
  },
}

Если вы запускаете тесты в режиме наблюдения (watch mode), убедитесь, что полностью остановили тестовый набор и перезапустили его.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь