【问题标题】:SyntaxError with Jest and React and importing CSS filesJest 和 React 的 SyntaxError 以及导入 CSS 文件
【发布时间】:2021-08-19 10:09:51
【问题描述】:

我正在尝试使用 React 和 Babel 让我的第一个 Jest 测试通过。

我收到以下错误:

语法错误:/Users/manueldupont/test/avid-sibelius-publishing-viewer/src/components/TransportButton/TransportButton.less:意外令牌

    >  7 | @import '../variables.css';
          | ^

我的 package.json 配置看起来像这样:

"babel": {
    "presets": [
      "es2015",
      "react"
    ],
    "plugins": [
      "syntax-class-properties",
      "transform-class-properties"
    ]
  },
  "jest": {
    "moduleNameMapper": {
      "^image![a-zA-Z0-9$_-]+$": "GlobalImageStub",
      "^[./a-zA-Z0-9$_-]+\\.png$": "RelativeImageStub"
    },
    "testPathIgnorePatterns": [
      "/node_modules/"
    ],
    "collectCoverage": true,
    "verbose": true,
    "modulePathIgnorePatterns": [
      "rpmbuild"
    ],
    "unmockedModulePathPatterns": [
      "<rootDir>/node_modules/react/",
      "<rootDir>/node_modules/react-dom/",
      "<rootDir>/node_modules/react-addons-test-utils/",
      "<rootDir>/node_modules/fbjs",
      "<rootDir>/node_modules/core-js"
    ]
  },

那么我错过了什么?

【问题讨论】:

    标签: reactjs babeljs jestjs


    【解决方案1】:

    moduleNameMapper 是告诉 Jest 如何解释具有不同扩展名的文件的设置。你需要告诉它如何处理 Less 文件。

    在您的项目中创建一个这样的文件(如果您愿意,可以使用不同的名称或路径):

    config/CSSStub.js

    module.exports = {};
    

    这个存根是我们将告诉 Jest 使用而不是 CSS 或 Less 文件的模块。然后更改moduleNameMapper 设置并将此行添加到其对象以使用它:

    '^.+\\.(css|less)$': '<rootDir>/config/CSSStub.js'
    

    现在 Jest 会将任何 CSS 或 Less 文件视为导出空对象的模块。你也可以做其他事情——例如,如果你使用 CSS 模块,你可以使用代理,这样每次导入都会返回导入的属性名称。

    guide 中了解更多信息。

    【讨论】:

    • 我正在使用 Jest v19+ 并且在 moduleNameMappers 中有以下键值对:"\\.(css|sass)$": "identity-obj-proxy",但是,我有一些使用 @import 关键字的 .sass 文件使 transformAndBuildScript 函数扔。有没有办法解决这个问题?
    • 事实上,即使 sassMock.js 文件只为所有 \\.sass$ 文件导出一个空对象,我也看到了同样的错误。
    • 使用 "\\.(css|less)$": "identity-obj-proxy" 为我工作
    • @JaKXz 你是怎么解决这个问题的?我遇到了同样的问题,我正在使用 css-modules 导入 css 文件。您可以在以下位置找到有关该问题的更多详细信息:stackoverflow.com/questions/48286678/…
    • 我之前只有 *.scss,添加 *.css 也解决了我的问题。谢谢。
    【解决方案2】:

    我通过在 package.json 文件的 jest 配置中使用 moduleNameMapper 键解决了这个问题

    {
       "jest":{
            "moduleNameMapper":{
                 "\\.(css|less|sass|scss)$": "<rootDir>/__mocks__/styleMock.js",
                 "\\.(gif|ttf|eot|svg)$": "<rootDir>/__mocks__/fileMock.js"
            }
       }
    }
    

    在此之后,您需要创建如下所述的两个文件

    • __mocks__/styleMock.js

      module.exports = {};

    • __mocks__/fileMock.js

      module.exports = 'test-file-stub';

    如果您使用的是 CSS 模块,那么最好模拟代理以启用类名查找。 因此您的配置将更改为:

    {
      "jest":{
         "moduleNameMapper": {
          "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
          "\\.(css|less|scss|sass)$": "identity-obj-proxy"
        },
      }
    }
    

    但您需要安装 identity-obj-proxy 软件包作为开发依赖项,即

    yarn add identity-obj-proxy -D
    

    了解更多信息。可以参考jest docs

    【讨论】:

    • 对于从 create-react-app 到达这里的任何人,moduleNameMapper 不是受支持的覆盖。评论点的版本是 1.1.4。
    • 我不使用 CRA,这些解决方案都不起作用。我很沮丧:(
    • 因为 identity-obj-proxy 很旧,不确定是否应该使用它,但是使用存根肯定适用于我的 webpack react jest 项目
    • 这对我有帮助。我没有使用 create-react-app,而是使用 Parcel 而不是 Webpack。谢谢。
    • 将这些类型的文件映射到模拟版本是个好主意。辉煌。
    【解决方案3】:

    更新谁使用 create-react-app 从 2018 年 2 月开始。 您不能覆盖 package.json 中的 moduleNameMapper 但在 jest.config.js 中它可以工作,不幸的是我还没有找到任何关于它为什么这样做的文档。 所以我的 jest.config.js 看起来像这样:

    module.exports = {
    ...,
      "moduleNameMapper": {
        "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
        "\\.(scss|sass|css)$": "identity-obj-proxy"
      }
    }
    

    它很好地跳过了scss文件和@import。

    支持我的回答,我关注了jest webpack

    【讨论】:

      【解决方案4】:

      类似的情况,安装 identity-object-proxy 并将其添加到我的 CSS 笑话配置中对我有用。

      //jest.config.js
      
      module.exports = {
        moduleNameMapper: {
          "\\.(css|sass)$": "identity-obj-proxy",
        },
      };
      

      我看到的具体错误:

      Jest encountered an unexpected token
      
      /Users/foo/projects/crepl/components/atoms/button/styles.css:1
      ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){.button { }
                                                                                               ^
      
      SyntaxError: Unexpected token .
      
        1 | import React from 'react';
      > 2 | import styles from './styles.css';
      

      【讨论】:

      • 工作就像一个魅力(我正在测试一个开玩笑的 nuxt 应用程序)
      【解决方案5】:

      如果您使用的是ts-jest,上述解决方案均无效!您需要模拟转换。

      jest.config.js

      module.exports = {
        preset: 'ts-jest',
        testEnvironment: 'jsdom',
        roots: [
          "<rootDir>/src"
        ],
        transform: {
          ".(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/jest-config/file-mock.js",
          '.(css|less)$': '<rootDir>/jest-config/style-mock.js'
        },
      };
      

      文件-mock.js

      module.exports = {
        process() {
          return `module.exports = 'test-file-stub'`;
        },
      };
      

      style-mock.js

      module.exports = {
          process() {
            return 'module.exports = {};';
          }
        };
      

      如果您想了解更多详细信息,我发现这个工作 example

      【讨论】:

      • 如果您仍然遇到无法找到模块错误,请确保您有一个带有 declare module '*.scss'; 或类似名称的 types.d.ts 文件。
      【解决方案6】:

      解决@import Unexpected token=:)

      安装包:

      npm i --save-dev identity-obj-proxy
      

      在 jest.config.js 中添加

      module.exports = {
        "moduleNameMapper": {
          "\\.(css|less|scss)$": "identity-obj-proxy"
        }
      }
      

      【讨论】:

        【解决方案7】:

        更新:2021 年 8 月 如果您使用带有 TypeScript 的 Next JS。只需按照示例存储库进行操作即可。

        否则您将浪费时间配置环境。

        https://github.com/vercel/next.js/blob/canary/examples/with-typescript-eslint-jest/package.json

        【讨论】:

        • 链接已关闭。你介意更新一下吗?
        【解决方案8】:

        我在 package.json 的底部添加了 moduleNameMapper,我在其中配置了我的玩笑,就像这样:

        "jest": {
            "verbose": true,
            "moduleNameMapper": {
                "\\.(scss|less)$": "<rootDir>/config/CSSStub.js"
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2018-04-24
          • 1970-01-01
          • 2017-06-10
          • 2021-01-22
          • 2018-09-16
          • 1970-01-01
          • 2017-01-30
          • 1970-01-01
          相关资源
          最近更新 更多