Jest遇到意外令牌(React,Typescript,Babel,Jest和Webpack设置)

时间:2019-08-25 09:32:04

标签: reactjs typescript jestjs babel enzyme

我已经使用React,Typescript,Babel,Webpack以及Prettier和EsLint设置了一个项目。我从头开始设置项目,并使一切正常进行。我刚刚开始使用Jest,但一切似乎都已经结束了。我已经在SO中看到了许多与我遇到的相同错误有关的问题,但是,对相同问题的回答都没有对我有任何帮助。我觉得我已经在此浪费了一天的时间,而我所做的只是通过添加似乎无济于事的其他设置来膨胀我的配置文件。我感觉到该问题与我的特定项目配置有关,但是我不确定如何调试或弄清楚问题出在哪里。

在我的package.json文件中(与Jest,Enzyme和Babel相关的依赖项):

    "@babel/core": "^7.5.5",
    "@babel/plugin-proposal-class-properties": "^7.5.5",
    "@babel/plugin-transform-runtime": "^7.5.5",
    "@babel/polyfill": "^7.4.4",
    "@babel/preset-env": "^7.5.5",
    "@babel/preset-react": "^7.0.0",
    "@babel/preset-typescript": "^7.3.3",
    "@types/enzyme": "^3.10.3",
    "@types/enzyme-adapter-react-16": "^1.0.5",
    "@types/jest": "^24.0.18",
    "@types/shallowequal": "^1.1.1",
    "babel-core": "^7.0.0-bridge.0",
    "babel-jest": "^24.9.0",
    "babel-loader": "^8.0.6",
    "babel-plugin-dynamic-import-node": "^2.3.0",
    "babel-plugin-transform-es2015-destructuring": "^6.23.0",
    "babel-plugin-transform-es2015-modules-commonjs": "^6.26.2",
    "babel-plugin-transform-object-rest-spread": "^6.26.0",
    "enzyme": "^3.10.0",
    "enzyme-adapter-react-16": "^1.14.0",
    "enzyme-to-json": "^3.4.0",
    "jest": "^24.9.0",
    "jest-environment-jsdom": "^24.9.0",
    "jest-environment-jsdom-global": "^1.2.0"
},

jest.config.js:

// eslint-disable-next-line @typescript-eslint/no-var-requires
const { defaults } = require('jest-config');
module.exports = {
  preset: 'ts-jest',
  globals: {
    'ts-jest': {
      diagnostics: false
    }
  },
  verbose: true,
  snapshotSerializers: [
    "<rootDir>/node_modules/enzyme-to-json/serializer"
  ],
  transform: {
    "^.+\\.js?$": "babel-jest",
    "^.+\\.(ts|tsx)?$": "ts-jest"
   },
  testRegex: "(.(test))\\.(ts|tsx)$",
  transformIgnorePatterns: [
    "^.+\\.js$"
  ],
  moduleFileExtensions: [ ...defaults.moduleFileExtensions, "ts", "tsx", "js", "json" ],
  moduleDirectories: [
    "node_modules",
    "src"
  ],
  moduleNameMapper: { 
    "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/assetTransformer.js", 
    "\\.(css|less|scss)$": "<rootDir>/assetTransformer.js" 
  },
  setupFilesAfterEnv: [
    "<rootDir>/jest.setup.js"
  ],
  coveragePathIgnorePatterns: [
    "/node_modules",
    "/src/root/i18n",
    "jest.setup.js"
  ],
  testEnvironment: "jsdom",
  testMatch: ["**/__tests__/**/*.ts?(x)", "**/?(*.)+(test).ts?(x)"],
  testURL: "http://localhost:8080"
}

jest.setup.js:

// Import adapter for enzyme
import Enzyme, { configure, shallow, mount, render } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import 'jest-localstorage-mock';

configure({ adapter: new Adapter() });
export { shallow, mount, render };
export default Enzyme;

// Log all jsDomErrors when using jsdom testEnvironment
window._virtualConsole &&
  window._virtualConsole.on('jsdomError', function(error) {
    console.error('jsDomError', error.stack, error.detail);
  });

process.env = Object.assign(process.env); 

babel.config.js:

module.exports = {
  "presets": [
    ['@babel/preset-env', {targets: {node: 'current'}}],
    ['@babel/env', {loose:true}],
    '@babel/preset-typescript',
    '@babel/typescript', 
    '@babel/react'
  ],
  "plugins": [
    ['@babel/proposal-class-properties', {loose:true}],
    "dynamic-import-node",
    "proposal-object-rest-spread",
    "transform-class-properties",
    "syntax-class-properties",
    "transform-es2015-modules-commonjs",
    "babel-plugin-transform-es2015-destructuring",
    "babel-plugin-transform-object-rest-spread"
  ],
  "env":{
    "test": {
      "presets": [
        ['@babel/preset-env', {targets: {node: 'current'}}],
        ['@babel/env', {loose:true}],
        '@babel/preset-typescript',
        '@babel/typescript', 
        '@babel/react'
      ],
      "plugins": [
        ['@babel/proposal-class-properties', {loose:true}],
        "dynamic-import-node",
        "proposal-object-rest-spread",
        "transform-class-properties",
        "syntax-class-properties",
        "transform-es2015-modules-commonjs",
        "babel-plugin-transform-es2015-destructuring",
        "babel-plugin-transform-object-rest-spread"
      ],
    }
  }
}

assetTransformer.js:

// eslint-disable-next-line @typescript-eslint/no-var-requires
const path = require('path');

module.exports = {
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  process(src, filename, config, options) {
    return 'module.exports = ' + JSON.stringify(path.basename(filename)) + ';';
  },
};
我要测试的

component.test.tsx文件:

import React from 'react';
import { shallow } from 'enzyme';

import { Component} from './component';

describe ('Component', () => {
  it('should render correctly with default parameters passed', () => {
    const component = shallow(<Component />);
    expect(component).toMatchSnapshot();
  });
});

无论我对任何配置文件进行什么更改,我都始终看到错误消息:

Test suite failed to run

    Jest encountered an unexpected token

    This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.

    By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".

    Here's what you can do:
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/en/configuration.html

    Details:

    SyntaxError: ...\component.test.tsx: Unexpected token (9:30)

       7 | describe ('Component', () => {
       8 |   it('should render correctly with default parameters passed', () => {
    >  9 |     const component = shallow(<Component />);
         |                               ^
      10 |     expect(component).toMatchSnapshot();
      11 |   });
      12 | });

      at Parser.raise (node_modules/@babel/parser/lib/index.js:6325:17)
      at Parser.unexpected (node_modules/@babel/parser/lib/index.js:7642:16)
      at Parser.parseExprAtom (node_modules/@babel/parser/lib/index.js:8841:20)
      at Parser.parseExprSubscripts (node_modules/@babel/parser/lib/index.js:8412:23)
      at Parser.parseMaybeUnary (node_modules/@babel/parser/lib/index.js:8392:21)
      at Parser.parseExprOps (node_modules/@babel/parser/lib/index.js:8267:23)
      at Parser.parseMaybeConditional (node_modules/@babel/parser/lib/index.js:8240:23)
      at Parser.parseMaybeAssign (node_modules/@babel/parser/lib/index.js:8187:21)
      at Parser.parseExprListItem (node_modules/@babel/parser/lib/index.js:9491:18)
      at Parser.parseCallExpressionArguments (node_modules/@babel/parser/lib/index.js:8621:22)

我在Windows 10计算机上使用VSCode。该项目运行良好,我可以继续开发组件并继续进行该项目。我只是无法配置Jest ...

通过在VSCode中在终端中简单地运行jest复制问题。

我希望单个测试通过,并创建组件的快照。

1 个答案:

答案 0 :(得分:0)

因此,在进行了进一步的挖掘之后,我设法找到了答案并使其正常工作。我希望这对将来可能会偶然发现此问题的其他人有所帮助:

  1. testRegex和testMatch不应一起使用。因此,我从jest.config.js文件中删除了testRegex。

  2. 更新jest.setup.js文件。 来自:

// Import adapter for enzyme
import Enzyme, { configure, shallow, mount, render } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import 'jest-localstorage-mock';

configure({ adapter: new Adapter() });
export { shallow, mount, render };
export default Enzyme;

收件人:

const Enzyme = require('enzyme');
const Adapter = require ('enzyme-adapter-react-16');

Enzyme.configure({ adapter: new Adapter() });
  1. 在tsconfig.json文件中,我为快捷方式指定了以下路径(我在上面的信息中错过了此路径):
"paths": {              
      "@App/*": ["src/*"],
      "@selectors/*": [ "ts/selectors/*" ],
      "@actions/*": [ "ts/actions/*" ],
      "@components/*": [ "ts/components/*" ],
      "@middleware/*": [ "ts/middleware/*" ],
      "@store/*": [ "ts/store/*" ],
      "@reducers/*": [ "ts/reducers/*" ]
    }

这些需要添加到jest.config.js文件中,否则jest似乎很难读取'@ store /'声明。

在“ moduleNameMapper”下添加了这些内容:

moduleNameMapper: { 
    "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/assetTransformer.js", 
    "\\.(css|less|scss)$": "<rootDir>/assetTransformer.js",         
    "@App/(.*)": "<rootDir>/src/$1",
    "@selectors/(.*)": "<rootDir>/src/ts/selectors/$1",
    "@actions/(.*)": "<rootDir>/src/ts/actions/$1",
    "@components/(.*)": "<rootDir>/src/ts/components/$1",
    "@middleware/(.*)": "<rootDir>/src/ts/middleware/$1",
    "@store/(.*)": "<rootDir>/src/ts/store/$1",
    "@reducers/(.*)": "<rootDir>/src/ts/reducers/$1"
  }
  1. 忘记在eslintignore中添加jest.config.js,assetTransformer.js和babel.config.js,因此也将其添加到其中(可能无关,但仍然需要完成)。

是的...测试运行。