使用Jest和React并导入CSS文件的SyntaxError

时间:2016-09-09 19:30:51

标签: reactjs babel jestjs

我正在努力让我的第一次Jest测试通过React和Babel。

我收到以下错误:

  

SyntaxError:/Users/manueldupont/test/avid-sibelius-publishing-viewer/src/components/TransportButton/TransportButton.less:意外的令牌

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

我对于jest的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"
    ]
  },

那么我错过了什么?

7 个答案:

答案 0 :(得分:47)

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

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

config/CSSStub.js

module.exports = {};

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

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

现在,Jest会将任何CSS或Less文件视为导出空对象的模块。您也可以执行其他操作 - 例如,如果使用CSS模块,则可以使用代理,以便每次导入都返回导入的属性名称。

阅读本指南中的更多内容:https://facebook.github.io/jest/docs/en/webpack.html

答案 1 :(得分:12)

我通过在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模块,那么最好模拟代理以启用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 docs

答案 2 :(得分:1)

从2018年2月开始使用 create-react-app

UPDATE。 您不能在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

答案 3 :(得分:1)

如果您使用的是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'
  },
};

file-mock.js

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

style-mock.js

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

我发现此功能有效example

答案 4 :(得分:0)

类似的情况,安装identity-object-proxy并将其添加到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';

答案 5 :(得分:0)

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

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

答案 6 :(得分:0)

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

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

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