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

Man*_*ont 36 babel reactjs jestjs

我想让我的第一个Jest Test通过React和Babel.

我收到以下错误:

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

    >  7 | @import '../variables.css';
          | ^
Run Code Online (Sandbox Code Playgroud)

我的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"
    ]
  },
Run Code Online (Sandbox Code Playgroud)

那我错过了什么?

Dan*_*mov 51

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

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

config/CSSStub.js

module.exports = {};
Run Code Online (Sandbox Code Playgroud)

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

'^.+\\.(css|less)$': '<rootDir>/config/CSSStub.js'
Run Code Online (Sandbox Code Playgroud)

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

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

  • 我正在使用Jest v19 +并且在`moduleNameMappers`中有以下键值对:`"\\.(css | sass)$":"identity-obj-proxy"`,但是,我有一些`.sass`文件使用`@ import`关键字使transformAndBuildScript函数抛出.有没有什么办法解决这一问题? (3认同)
  • 使用`“ \\。(css | less)$”:“ identity-obj-proxy”`为我工作 (2认同)

Jja*_*nis 18

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

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

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

  • __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"
    },
  }
}
Run Code Online (Sandbox Code Playgroud)

但是你需要安装identity-obj-proxy包作为开发依赖,即

yarn add identity-obj-proxy -D
Run Code Online (Sandbox Code Playgroud)

欲获得更多信息.您可以参考jest docs

  • 对于从 create-react-app 到达这里的任何人,`moduleNameMapper` 不是受支持的覆盖。评论时的版本是 1.1.4。 (2认同)

Mel*_*hia 16

如果您使用ts-jest,上述解决方案都不起作用!您需要模拟转换。

笑话配置.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'
  },
};
Run Code Online (Sandbox Code Playgroud)

文件模拟.js

module.exports = {
  process() {
    return `module.exports = 'test-file-stub'`;
  },
};
Run Code Online (Sandbox Code Playgroud)

样式模拟.js

module.exports = {
    process() {
      return 'module.exports = {};';
    }
  };
Run Code Online (Sandbox Code Playgroud)

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


小智 13

@import Unexpected token=:) 的解决方案

安装包:

npm i --save-dev identity-obj-proxy
Run Code Online (Sandbox Code Playgroud)

添加 jest.config.js

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


Jad*_*dam 10

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

//jest.config.js

module.exports = {
  moduleNameMapper: {
    "\\.(css|sass)$": "identity-obj-proxy",
  },
};
Run Code Online (Sandbox Code Playgroud)

我看到的具体错误:

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';
Run Code Online (Sandbox Code Playgroud)


Ale*_*nov 7

UPDATE,他们从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"
  }
}
Run Code Online (Sandbox Code Playgroud)

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

支持我的回答,我跟随开玩笑的webpack

  • 在我的 .storybook/preview.js 中,我使用 import '@fontsource/roboto/400.css' 导入 mui 字体。运行 jest 脚本时,我遇到错误 `.../node_modules/@fontsource/material-icons/index.css:2 @font-face { ^ SyntaxError: Invalid or Unexpected token...` 为了修复它,我在 moduleNameMapper `'@fontsource': 'identity-obj-proxy',` 中的 jest.config.js 中添加,它解决了我的问题 (2认同)