javascript - 使用 Jest、Babel、Webpack 和 React 进行测试。目前尚未启用对实验性语法 'classProperties' 的支持

标签 javascript reactjs react-native webpack jestjs

好吧,我在尝试在我的 React-native 应用程序上启用 Jest 时遇到了很大的问题。本主题的每个答案都为我的 webpack 或 package.json 提供了不同的配置。我希望能在这里找到答案。

对于这个简单的测试:

import 'react-native';
import React from 'react';
import Index from '../index.ios.js';

// Note: test renderer must be required after react-native.
import renderer from 'react-test-renderer';

it('renders correctly', () => {
  const tree = renderer.create(
    <Index />
  );
});

我运行:npm test 并得到:

SyntaxError: D:\workspaces\web\react\site\node_modules\react-native\jest\mockComponent.js: Support for the experimental syntax 'classProperties' isn't currently enabled (20:24):

有一个可爱的解决方案:

Add @babel/plugin-proposal-class-properties (https://git.io/vb4SL) to the 'plugins' section of your Babel config to enable transformation.

但是我不知道该怎么做。

这是我的 package.json 配置:

{
  "name": "site",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start",
    "build-sitedev-home-css": "NODE_ENV=sitedev node_modules/webpack/bin/webpack.js --config ./modules/Home/assets/css/src/webpack.config.js",
    "build-sitedev-home-js": "NODE_ENV=sitedev node_modules/bundle-js/bin/bundle-js.js ./modules/Home/assets/js/src/entryfile.js --disable-beautify -p > ./modules/Home/assets/js/build/bundle.js",
    "startweb": "cross-env NODE_ENV=webdevelopment node_modules/webpack/bin/webpack.js --watch",
    "buildweb": "cross-env NODE_ENV=webproduction node_modules/webpack/bin/webpack.js -p",
    "test": "jest",
    "android": "react-native run-android",
    "ios": "react-native run-ios",
    "android:expo": "react-native-scripts android",
    "react-devtools": "react-devtools"
  },
  "dependencies": {
    "abortcontroller-polyfill": "1.3.0",
    "adb": "0.2.0",
    "ag-grid": "18.1.1",
    "ag-grid-react": "18.1.0",
    "blueimp-file-upload": "9.32.0",
    "bundle-js": "1.0.3",
    "chart.js": "2.8.0",
    "elastic-apm-js-base": "3.0.0",
    "jquery": "3.4.1",
    "lodash.get": "4.4.2",
    "lodash.isequal": "4.5.0",
    "material-ui": "0.20.2",
    "meow": "5.0.0",
    "moment": "2.24.0",
    "moment-timezone": "0.5.26",
    "qrcode.react": "0.9.3",
    "react": "16.4.2",
    "react-art": "16.8.6",
    "react-chartjs": "1.2.0",
    "react-dom": "16.8.6",
    "react-dom-factories": "1.0.2",
    "react-infinite-scroller": "1.2.4",
    "react-native": "^0.60.5",
    "react-native-calendars": "1.21.0",
    "react-native-drawer": "2.5.1",
    "react-native-floating-label-text-input": "0.1.5",
    "react-native-progress-circle": "2.0.1",
    "react-native-snap-carousel": "3.8.0",
    "react-native-vector-icons": "4.6.0",
    "react-native-video": "4.4.4",
    "react-native-web": "0.11.5",
    "react-native-web-linear-gradient": "1.0.5",
    "react-tooltip": "3.10.0",
    "video.js": "7.6.0",
    "xdate": "0.8.2"
  },
  "devDependencies": {
    "@babel/core": "7.4.3",
    "@babel/plugin-proposal-class-properties": "7.5.5",
    "@babel/preset-env": "7.4.3",
    "@babel/preset-es2016": "7.0.0-beta.53",
    "@babel/preset-react": "7.0.0",
    "@babel/runtime": "7.4.3",
    "@types/prop-types": "15.7.1",
    "babel-cli": "6.26.0",
    "babel-core": "6.22.1",
    "babel-eslint": "10.0.1",
    "babel-jest": "24.1.0",
    "babel-loader": "6.2.10",
    "babel-plugin-transform-async-to-generator": "6.24.1",
    "babel-plugin-transform-runtime": "6.23.0",
    "babel-preset-env": "1.7.0",
    "babel-preset-es2016": "6.24.1",
    "babel-preset-react": "6.24.1",
    "babel-preset-react-native": "3.0.2",
    "babel-preset-stage-0": "6.24.1",
    "babel-register": "6.26.0",
    "cross-env": "5.2.0",
    "css-loader": "3.1.0",
    "eslint": "5.16.0",
    "eslint-plugin-react": "7.12.4",
    "expo": "33.0.7",
    "extract-text-webpack-plugin": "3.0.2",
    "file-loader": "4.1.0",
    "jest": "24.8.0",
    "jest-react-native": "18.0.0",
    "metro-react-native-babel-preset": "0.55.0",
    "react-devtools": "3.4.3",
    "react-native-scripts": "2.0.1",
    "react-test-renderer": "16.4.2",
    "style-loader": "0.23.1",
    "webpack": "3.10.0",
    "webpack-dev-server": "3.2.1"
  },
  "jest": {
    "preset": "react-native"
  },
  "rnpm": {
    "assets": [
      "./assets/fonts/"
    ]
  }
}

这是我的 webpack 配置:

var debug = process.env.NODE_ENV !== "webproduction";
var webpack = require('webpack');
var path = require('path');
var fs = require('fs');

var buildPath = __dirname + "/../../siteweb/site/www/themes/tmpux/assets/js/uxbuild";
var wpk_local_configuration = {};
if (fs.existsSync('./local.webpack.config.js')) {
  let local_webpack_config = require('./local.webpack.config');
  buildPath = local_webpack_config.buildPath;
  wpk_local_configuration = local_webpack_config.wpk_local_configuration;
}

console.log('buildPath = ' + buildPath);
console.log('wpk_local_configuration = ' + JSON.stringify(wpk_local_configuration));

if (!fs.existsSync(buildPath)) {
  fs.mkdirSync(buildPath);
}

fs.createReadStream(__dirname + "/components/parts/PDFViewer/configPDFViewer.js")
  .pipe(fs.createWriteStream(buildPath + "/configPDFViewer.js"));

var _version = new Date().getTime();
console.log('version = ' + _version);

var wpk_configuration = {
  entry: {
    main: './index.web.js',
  },
  output: {
    path: buildPath,
    filename: "bundle.main.js",
    publicPath: "./assets/js/uxbuild/",
    chunkFilename: "bundle.[name].js"
  },
  module: {
    loaders: [
      {
        test: /\.js?$/,
        exclude: function (modulePath) {
          return (
            /node_modules/.test(modulePath) &&
            !/node_modules(\\|\/)react-native-datepicker/.test(modulePath) &&
            !/node_modules(\\|\/)react-native-progress-circle/.test(modulePath) &&
            !/node_modules(\\|\/)react-native-snap-carousel/.test(modulePath)
          );
        },
        loader: 'babel-loader',
        query: {
          presets: ['es2016', 'react-native'],
          plugins: ['transform-runtime']
        },
      },
      {
        test: /\.(png|jpg|gif|mp4)$/,
        loader: 'file-loader?context=' + __dirname + "/themes/tmpux/assets/js/components/" + '&emitFile=true&name=[path][hash].[ext]',
        options: {
          publicPath: "./assets/js/uxbuild/"
        }
      },
      {
        test: /\.css$/,
        loader: 'style-loader!css-loader'
      },
      {
        test: /\.ttf$/,
        loader: 'file-loader',
        include: path.resolve(__dirname, "node_modules/react-native-vector-icons"),
      }
    ],
  },
  resolve: {
    alias: {
      'react-native': 'react-native-web',
      'jquery-ui/ui/widget': 'blueimp-file-upload/js/vendor/jquery.ui.widget.js',
    },
    extensions: [ '.web.js', '.js' ]
  },
  plugins: debug ? [
          new webpack.optimize.CommonsChunkPlugin({
              name: 'node-static',
              path: buildPath,
              filename: 'node-static.js',
              minChunks(module, count) {
                  var context = module.context;
                  return context && context.indexOf('node_modules') >= 0;
              }
          }),
          new webpack.DefinePlugin({
            'process.env': {
              NODE_ENV: JSON.stringify('development')
            }
          }),
        ] : [
          new webpack.optimize.CommonsChunkPlugin({
                name: 'node-static',
                path: buildPath,
                filename: 'node-static.js',
                minChunks(module, count) {
                    var context = module.context;
                    return context && context.indexOf('node_modules') >= 0;
                }
          }),
          new webpack.DefinePlugin({
            'process.env': {
             NODE_ENV: JSON.stringify('production')
            }
          }),
          new webpack.optimize.DedupePlugin(),
          new webpack.optimize.OccurrenceOrderPlugin(),
          new webpack.optimize.UglifyJsPlugin({ mangle: false, sourceMap: true }),
        ]
};

module.exports = Object.assign(wpk_configuration, wpk_local_configuration);

还有我的本地 babel 配置:local.webpack.config

module.exports = {
    buildPath: __dirname + "/../../siteweb/site/www/themes/tmpux/assets/js/uxbuild",
    wpk_local_configuration: {
        devtool: 'eval-source-map',
    },
    presets: ["module:metro-react-native-babel-preset"], 
    plugins: ["@babel/plugin-proposal-class-properties"]
};

最佳答案

将其添加到 package.json

"jest": {
    "preset": "react-native",
    "transform": {
      "^.+\\.js$": "<rootDir>/node_modules/react-native/jest/preprocessor.js"
    }
  },

https://github.com/facebook/react-native/issues/21075

关于javascript - 使用 Jest、Babel、Webpack 和 React 进行测试。目前尚未启用对实验性语法 'classProperties' 的支持,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57809391/

相关文章:

javascript - 桶文件、webpack 和 jest

javascript - 使用 setTimeout() 在 React 中渲染一个带有超时的列表

javascript - 在授予的地理定位权限上附加事件监听器

react-native - React Native 漏斗图

react-native - 错误 : Error: Unable to resolve module ./ Hook 来自/node_modules/react-native-reanimated/src/reanimated2/index.ts

javascript - jQuery 如何从字符串中删除多个空格

javascript - 选中一个复选框时启用多个复选框

javascript - 将新函数插入数组 - Javascript

javascript - Websockets 不能在 javascript 和 python 中工作

reactjs - 根据其动态数据查找子组件的高度