【问题标题】:Jest cannot load svg fileJest 无法加载 svg 文件
【发布时间】: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" 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)

这个文件甚至没有经过测试。我不知道为什么它试图编译它。我的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

【问题讨论】:

    标签: javascript reactjs svg jestjs


    【解决方案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

    【讨论】:

    【解决方案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 文件?
    • 这个答案对我有用:stackoverflow.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',
            }
          

          【讨论】:

            猜你喜欢
            • 2021-11-15
            • 1970-01-01
            • 1970-01-01
            • 2020-09-20
            • 2021-06-23
            • 1970-01-01
            • 2014-12-08
            • 2021-06-26
            • 1970-01-01
            相关资源
            最近更新 更多