带有 Jest 和 React 的 SyntaxError 并导入 CSS 文件

IT技术 reactjs babeljs jestjs
2021-03-25 05:07:49

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

我收到以下错误:

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

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

我的 package.json 配置 jest 如下所示:

"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"
    ]
  },

那么我错过了什么?

6个回答

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

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

config/CSSStub.js

module.exports = {};

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

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

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

在本指南中阅读更多内容

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

我通过使用moduleNameMapperpackage.json 文件中 jest 配置中的密钥解决了这个问题

{
   "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 = '测试文件存根';

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

{
  "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 文档

我不使用 CRA,这些解决方案都不起作用。我很沮丧:(
2021-06-14 05:07:49
用模拟版本映射这些类型的文件是个好主意。杰出的。
2021-06-14 05:07:49
对于从 create-react-app 到达这里的任何人,moduleNameMapper不支持覆盖。评论时的版本是 1.1.4。
2021-06-15 05:07:49
这对我有帮助。我没有使用 create-react-app,我使用的是 Parcel 而不是 Webpack。谢谢你。
2021-06-15 05:07:49
由于 identity-obj-proxy 很旧,不确定是否应该使用它,但使用存根肯定适用于我的 webpack react jest 项目
2021-06-21 05:07:49

从 2018 年 2 月开始使用create-react-app 的更新。您无法覆盖 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

类似的情况,安装身份对象代理并将其添加到 CSS 的 jest 配置中对我有用。

//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 应用程序)
2021-06-07 05:07:49

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

开玩笑的配置文件

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'
  },
};

文件模拟.js

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

style-mock.js

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

如果您想要更多详细信息,我找到了这个工作示例

declare module '*.scss';如果您仍然收到“无法找到module”错误,请确保您有一个包含或类似的 types.d.ts 文件
2021-06-19 05:07:49