Jest 无法加载 svg 文件

Posted

技术标签:

【中文标题】Jest 无法加载 svg 文件【英文标题】:Jest cannot load svg file 【发布时间】:2020-02-24 10:38:53 【问题描述】:

在我的应用程序中,我使用 React 和 TypeScript。我尝试运行玩笑测试,但出现以下错误:

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"   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)

这个文件甚至没有经过测试。我不知道为什么它试图编译它。我的jest.config.json 文件仅包含覆盖阈值。

我读到 jest 有时需要为特定文件(如 SVG)添加额外的转换部分,但是当我添加到配置中时

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

我的错误信息仅更改为:

C:\Users\e-KDKK\workspace\konrad\mikskarpety\test\utils\debounce.test.ts:1 ("Object.":function(module,exports,require,__dirname,__filename,global,jest)import getVersion 来自“开玩笑”; ^

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)

这让我更困惑。

您可以在此处找到该应用的代码:https://github.com/KonradKlimczak/mikskarpety

【问题讨论】:

【参考方案1】:

jest 不知道如何加载除 js/jsx 之外的其他文件扩展名,您需要找到 jest.config.js 并为 svg 文件添加转换器。

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

并在您的根目录中创建包含以下内容的 svgTransform.js 文件(参见Custom transformers)。

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

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

【讨论】:

希望我能多次对此表示赞同。 :) 哇,我找了这么久!非常感谢! 链接已更新为jestjs.io/docs/code-transformation#examples【参考方案2】:

解决此问题的另一个更简单的选择是jest-svg-transformer

只需安装它: npm i -D jest-svg-transformeryarn add -D jest-svg-transformer

并将jest.config.js 添加到转换部分:

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

【讨论】:

谢谢,兄弟,真的救了我 你有 Vue 应用的解决方法吗? 我建议使用 npm i -D jest-svg-transformer 以便将此包添加到 DevDependencies 而不是依赖项。除非你希望这个包出现在你的生产代码中。 @RichardNikolas 我正在使用Create React App Typescript 版本。在哪里以及如何添加这个 Config 文件? 这个答案对我有用:***.com/a/68391294/1264156【参考方案3】:

另一个选项(不是特定于 React)是使用 jest-transform-stub,因为它适用于您想要的任何非 JS 文件。


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

【讨论】:

这个包实际上什么都不做,只是返回一个空的 module.export。如果您不想为此添加新的依赖项,我推荐 Tom Pang 的答案。【参考方案4】:

如果您仍在寻找一个简单的解决方案,您可以将您的模拟文件定义为这样

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

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

然后在 jest.config 文件中做


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

【讨论】:

感谢您的回答。根据您的项目/linter 配置,如下所示的功能组件也可以工作:``` // svgMock.js const MockSvgFile = (): JSX.Element => >;导出默认的 MockSvgFile; ```【参考方案5】:

正在从node_modules 导入*.svg

node_modules1 中的图标库导入*.svg 文件时,我遇到了同样的问题。在jest.config.js"transform" 部分中使用jest-transform-stub 对我不起作用,我不得不在"moduleNameMapper" 部分中使用它。

对我有帮助的是(jest.config.js):

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

1这个原因可以在jest-transform-stub's README找到。

默认情况下,Jest 不会对 node_modules 应用转换。您可以使用 moduleNameMapper 解决此问题。

【讨论】:

【参考方案6】:

在使用jest-svg-transformer 时,我的设置在放在transformer 部分下时不起作用。所以我不得不将它添加到moduleNameMapper 下并且它起作用了。

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

【讨论】:

谢谢。您的解决方案有所帮助【参考方案7】:

使用默认配置,您必须在 jest.config.js 中编写

"transform": 
    "\\.[jt]sx?$": "babel-jest",
    "^.+\\.svg$": "jest-svg-transformer"

【讨论】:

【参考方案8】:

不幸的是,现代 Jest 版本似乎不再维护各种开箱即用的变压器。我改编了其中一个并简化了一些代码。希望这可以帮助那里的人。

const fs = require('fs');
const path = require('path');
const crypto = require('crypto');

const base64 = (filename, data) => 
  const type = filename.endsWith('.svg') ? 'svg+xml' : path.extname(filename).slice(1) || 'png';
  return `data:image/$type;base64,$data.toString('base64')`;
;

module.exports = 
  getCacheKey: (_fileData, filename) => crypto.createHash('md5').update(filename).digest('hex'),
  process: (sourceText, filename) => `module.exports = $JSON.stringify(base64(filename, fs.readFileSync(filename)));`,
;

使用这个 sn-p 将它添加到 jest config 转换器中:

'^.+\\.(svg|png|jpg|jpeg|gif|webp)$': '<rootDir>/test/imageTransformer.js',

【讨论】:

【参考方案9】:

如果您使用的是ts-jest,您只需在jest.config.jsjest.preset.js 文件上的转换列表中添加svg

transform: 
    '^.+\\.(ts|js|html|svg)$': 'ts-jest',
  

【讨论】:

以上是关于Jest 无法加载 svg 文件的主要内容,如果未能解决你的问题,请参考以下文章

IIS无法加载字体文件(*.woff,*.svg)的解决办法

在 Jest 测试之前无法加载 Google Maps API

IIS无法加载字体文件(*.woff,*.svg)的解决办法

Angular + Jest:错误:未捕获(承诺):无法加载 C:footer.component.html

SVG 无法在 Firefox 上加载

Vuejs 无法加载 svg 图像?