React Jest - 导入意外的令牌错误

5

我正在学习React,并且想要测试我的组件之一,但是我卡在了这个错误上:

{import React from 'react';                                                                                   
^^^^^^
SyntaxError: Unexpected token import

我尝试了一些在stackoverflow和github上阅读的方法:

向我的babel配置文件添加了测试预设以及这些插件:"transform-es2015-modules-commonjs","dynamic-import-node"

{
  "presets":  ["es2015", "react"],
  "env": {
  "test": {
      "presets":[
        ["es2015", { "modules": false }],
         "stage-0",
        "react"],
      "plugins": [
        "transform-es2015-modules-commonjs",
        "dynamic-import-node"
      ]
    }
}
}

在我的 package.json 文件中,Jest 属性有以下设置:

"jest": {
    "verbose": true,
    "moduleFileExtensions": [
      "ts",
      "tsx",
      "jsx",
      "js"
    ],
   "transform": {},
    "moduleDirectories": [
      "node_modules"
    ],
    "transformIgnorePatterns": [
      "node_modules/(?!react)/"
    ],
    "testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$"
  },

如果有帮助的话,我的实际组件是使用ES6和typescript构建的。

从我看过的内容来看,似乎jest会因为node不理解ES6的import而出错。我尝试过的所有在线解决方案都没有奏效。

此外,这是我的开发依赖项:

"devDependencies": {
    "awesome-typescript-loader": "^3.2.2",
    "babel-cli": "^6.24.1",
    "babel-core": "^6.25.0",
    "babel-eslint": "^7.2.3",
    "babel-jest": "^20.0.3",
    "babel-loader": "^7.1.1",
    "babel-plugin-dynamic-import-node": "^1.0.2",
    "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-react": "^6.24.1",
    "babel-preset-stage-0": "^6.24.1",
    "css-loader": "^0.28.4",
    "enzyme": "^2.9.1",
    "eslint": "^4.4.1",
    "eslint-config-airbnb": "^15.1.0",
    "eslint-loader": "^1.9.0",
    "eslint-plugin-import": "^2.7.0",
    "eslint-plugin-jsx-a11y": "^6.0.2",
    "eslint-plugin-react": "^7.2.0",
    "extract-text-webpack-plugin": "^3.0.0",
    "html-webpack-harddisk-plugin": "^0.1.0",
    "html-webpack-plugin": "^2.30.1",
    "jest": "^20.0.4",
    "node-sass": "^4.5.3",
    "react-test-renderer": "^15.6.1",
    "regenerator-runtime": "^0.10.5",
    "sass-loader": "^6.0.6",
    "source-map-loader": "^0.2.1",
    "style-loader": "^0.18.2",
    "ts-jest": "^20.0.10",
    "typescript": "^2.4.2",
    "webpack": "^3.5.1",
    "webpack-dev-middleware": "^1.12.0",
    "webpack-dev-server": "^2.7.0"
  },

Webpack配置

const webpack = require('webpack');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const HtmlWebpackHarddiskPlugin = require('html-webpack-harddisk-plugin');

const HOST = "127.0.0.1";
const PORT = "9000";

const devServerUrl = "http://localhost:" + PORT + "/";

const config = {
  devtool: 'source-map',
  context: __dirname, // `__dirname` is root of project and `src` is source
  entry:
  [
    './src/index.js',
    './src/ui/styles.scss'
  ],
  output: {
    path: path.join(__dirname, 'dist'),
    filename: "bundle.js",
    publicPath: ''
  },
  resolve: {
    extensions: ['.ts', '.tsx', '.js', '.jsx', '.scss', '.css']
  },
  module: {
    rules: [
      { test: /\.tsx?$/, loader: "awesome-typescript-loader" },
      { test: /\.js$/, exclude: /node_modules/, loader: ['babel-loader', 'eslint-loader'] },
      { test: /\.jsx$/, exclude: /node_modules/, loader: ['babel-loader', 'eslint-loader'] },
      {
        test: /\.(sass|scss)$/, use: ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: ['css-loader', 'sass-loader']
        })
      }
    ]
  },
  devServer: {
    contentBase: "dist/",
    noInfo: true,
    inline: true,
    compress: true,
    port: PORT,
    host: HOST,
    hot: true
  },
  plugins: [
    new HtmlWebpackPlugin({
      filename: 'index.html', // Output file name.
      template: './public/index.html', // Use our HTML file as a template for the new one.
      inject: 'body',
      alwaysWriteToDisk: true,
      output: {
        path: path.join(__dirname, 'dist'),
        filename: 'bundle.js'
      },
    }),
    new ExtractTextPlugin({ // define where to save the file
      filename: 'styles.bundle.css'}),
    new webpack.HotModuleReplacementPlugin(),
    new HtmlWebpackHarddiskPlugin({
  outputPath: path.resolve(__dirname, 'dist')
})
  ],
};

module.exports = config;

谢谢

3个回答

3
Jest不支持Typescript。我已从项目中删除Jest,并安装了Mocha、Karma、Chai和Enzyme。与自称为“零配置测试平台”的Jest相比,这些工具更容易设置。这篇文章对我帮助很大:Getting Started on Testing with Typescript, ReactJS, and Webpack。希望这能帮助其他人节省时间,不必费力让Jest与Typescript兼容。

1
如果您使用预处理器(例如https://github.com/kulshekhar/ts-jest),则可以将Jest与Typescript一起使用。 - oyvindym

2

这是因为您已经配置了babel,使其不转译ES6模块

  "presets":[
    ["es2015", { "modules": false }],

尝试将modules设置为true(或省略,因为它默认为true),然后它应该可以正常工作。


我将其设置为true以查看是否有帮助,但并没有。我的测试确实有一个配置,如下所示: "env": { "test": { "presets":[ "es2015", "stage-0", "react"], "plugins": [ "transform-es2015-modules-commonjs", "dynamic-import-node" ] } } - Liam Kenneth
嗯,我以为那就是问题所在。将你的配置与我的一个正常工作的配置进行比较,我并没有看到其他的差异。尝试移除那些模块/导入插件 - 我只使用 "presets": [ "es2015", "stage-0", "react" ] 就可以正常工作了。 - davnicwil
你如何运行jest?我已经在我的package.json中设置了当我键入npm test时运行jest。所以我不使用webpack来运行测试。那是我错了吗?同样的问题也出现在这里 - "presets": [ "es2015", "stage-0", "react" ] - Liam Kenneth
我也是这样做的,只是从npm test运行jest - 最后一次尝试,你确定jest正在使用"env": "test": ...配置吗?还是只是使用常规配置?为了排除这个问题,我建议尝试同时更改两者并查看结果。或者只需为jest使用.babelrc文件。 - davnicwil
我认为它没有查看Babel文件中的任何内容,因为我将stage-0更改为stage-1,这是一个我没有的预设,并且它没有出错。 - Liam Kenneth

0

你需要安装 Babel 来编译你的 ES6 和 React 代码

请使用以下方式

   C:\Users\username\Desktop\reactApp>npm install babel-core
C:\Users\username\Desktop\reactApp>npm install babel-loader
C:\Users\username\Desktop\reactApp>npm install babel-preset-react
C:\Users\username\Desktop\reactApp>npm install babel-preset-es2015

尽量保持我们的webpack

var config = {
   entry: './todoApp.js',

   output: {
      path:'./',
      filename: 'index.js',
   },

   devServer: {
      inline: true,
      port: 9191
   },

   module: {
         rules: [
      {
        test: /\.css$/,
        use: [ 'style-loader', 'css-loader' ]
      }
      ],
      loaders: [
         {
            test: /\.jsx?$/,
            exclude: /node_modules/,
            loader: 'babel',

            query: {
               presets: ['es2015', 'react']
            }
         }

      ]
   }
}

module.exports = config;

我已经有它们了,你可以在依赖列表中看到它们。 - Liam Kenneth
我添加了我的webpack配置,这样你就可以看到我也在使用babel加载器。 - Liam Kenneth
尝试按照我的代码将你的测试对象定义为加载器,而不是规则。 - Vikram Saini

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接