Vue-test-utils не может найти `Set()`: ReferenceError: Невозможно найти переменную: Set

В настоящее время я пытаюсь написать несколько тестов для компонента Vue. Однако, когда я пытаюсь запустить тесты, он выдает следующее сообщение:

[BABEL] Note: The code generator has deoptimised the styling of /home/bono/dev/git_repos/hypernode-control-panel/hncp/vue/common/tests/unit/UpdateElementRadio.spec.es5.js as it exceeds the max of 500KB.
13 12 2018 15:52:18.339:INFO [karma-server]: Karma v3.1.3 server started at http://0.0.0.0:9876/
13 12 2018 15:52:18.341:INFO [launcher]: Launching browsers PhantomJS with concurrency unlimited
13 12 2018 15:52:18.344:INFO [launcher]: Starting browser PhantomJS
13 12 2018 15:52:18.594:INFO [PhantomJS 2.1.1 (Linux 0.0.0)]: Connected on socket fBfbs8v8mD1WMsLOAAAA with id 26571362
ERROR LOG: '[Vue warn]: Error in config.errorHandler: "ReferenceError: Can't find variable: Set"'
ERROR LOG: ReferenceError: Can't find variable: Set
patchRenderMixin
callHook
_init
VueComponent
createComponentInstanceForVnode
init
createComponent
createElm
patch
_update
updateComponent
get
Watcher
mountComponent
$mount
mount
shallowMount

callFn@http://localhost:9876/base/node_modules/mocha/mocha.js?840d4fbbcc65a16cec39f9e25af2ea6d2cff68ea:4550:25
run@http://localhost:9876/base/node_modules/mocha/mocha.js?840d4fbbcc65a16cec39f9e25af2ea6d2cff68ea:4542:13
runTest@http://localhost:9876/base/node_modules/mocha/mocha.js?840d4fbbcc65a16cec39f9e25af2ea6d2cff68ea:5078:13
http://localhost:9876/base/node_modules/mocha/mocha.js?840d4fbbcc65a16cec39f9e25af2ea6d2cff68ea:5196:19
next@http://localhost:9876/base/node_modules/mocha/mocha.js?840d4fbbcc65a16cec39f9e25af2ea6d2cff68ea:4992:16
http://localhost:9876/base/node_modules/mocha/mocha.js?840d4fbbcc65a16cec39f9e25af2ea6d2cff68ea:5002:11
next@http://localhost:9876/base/node_modules/mocha/mocha.js?840d4fbbcc65a16cec39f9e25af2ea6d2cff68ea:4926:16
http://localhost:9876/base/node_modules/mocha/mocha.js?840d4fbbcc65a16cec39f9e25af2ea6d2cff68ea:4970:9
timeslice@http://localhost:9876/base/node_modules/mocha/mocha.js?840d4fbbcc65a16cec39f9e25af2ea6d2cff68ea:82:27
ERROR LOG: '[Vue warn]: Error in beforeCreate hook: "ReferenceError: Can't find variable: Set"

found in

---> <UpdateElementRadio> at hncp/vue/common/src/components/UpdateElementRadio.vue
       <Root>'
ERROR LOG: ReferenceError: Can't find variable: Set
patchRenderMixin
callHook
_init
VueComponent
createComponentInstanceForVnode
init
createComponent
createElm
patch
_update
updateComponent
get
Watcher
mountComponent
$mount
mount
shallowMount

callFn@http://localhost:9876/base/node_modules/mocha/mocha.js?840d4fbbcc65a16cec39f9e25af2ea6d2cff68ea:4550:25
run@http://localhost:9876/base/node_modules/mocha/mocha.js?840d4fbbcc65a16cec39f9e25af2ea6d2cff68ea:4542:13
runTest@http://localhost:9876/base/node_modules/mocha/mocha.js?840d4fbbcc65a16cec39f9e25af2ea6d2cff68ea:5078:13
http://localhost:9876/base/node_modules/mocha/mocha.js?840d4fbbcc65a16cec39f9e25af2ea6d2cff68ea:5196:19
next@http://localhost:9876/base/node_modules/mocha/mocha.js?840d4fbbcc65a16cec39f9e25af2ea6d2cff68ea:4992:16
http://localhost:9876/base/node_modules/mocha/mocha.js?840d4fbbcc65a16cec39f9e25af2ea6d2cff68ea:5002:11
next@http://localhost:9876/base/node_modules/mocha/mocha.js?840d4fbbcc65a16cec39f9e25af2ea6d2cff68ea:4926:16
http://localhost:9876/base/node_modules/mocha/mocha.js?840d4fbbcc65a16cec39f9e25af2ea6d2cff68ea:4970:9
timeslice@http://localhost:9876/base/node_modules/mocha/mocha.js?840d4fbbcc65a16cec39f9e25af2ea6d2cff68ea:82:27

  UpdateElementRadio
    ✗ accepts label_text prop
    Can't find variable: Set
    patchRenderMixin
    callHook
    _init
    VueComponent
    createComponentInstanceForVnode
    init
    createComponent
    createElm
    patch
    _update
    updateComponent
    get
    Watcher
    mountComponent
    $mount
    mount
    shallowMount



PhantomJS 2.1.1 (Linux 0.0.0): Executed 1 of 1 (1 FAILED) ERROR (0.041 secs / 0.01 secs)

npm ERR! Test failed.  See above for more details.

Это тест, который я пытаюсь запустить (обратите внимание, что это может быть немного бессмысленным тестом, я просто пытаюсь заставить вещи работать в первую очередь):

import Vue from 'vue'
import { expect } from 'chai';
import { shallowMount } from '@vue/test-utils';
import UpdateElementRadio from '../../src/components/UpdateElementRadio.vue';

describe('UpdateElementRadio', () => {
  it('accepts label_text prop', () => {
    shallowMount(UpdateElementRadio);
    const vm = new Vue(UpdateElementRadio).$mount();
    console.log(vm.props);
    expect(vm.props.label_text).to.equal(String);
  });
});

Я не слишком опытен в настройке этой вещи, но все работает нормально, когда я не пытаюсь использовать какую-либо mount функция от vue-test-utils, У меня такое чувство, что что-то не так с моей настройкой Babel или что-то в этом роде, так как это ссылка на es2015 (по крайней мере, я обнаружил, что пытался получить ее от lib.es2015 файл). Я пытался использовать разные предустановки Babel, но ни одна из них не работала (или выдавала больше ошибок). Я также проверил документы для @babel/preset-env и я думаю, что это правильный пресет для использования.

Я поделюсь своим конфигом кармы, конфигом вебпака и package.json также:

karma.conf.js:

// Karma configuration
// Generated on Thu Dec 13 2018 11:28:18 GMT+0100 (Central European Standard Time)
let webpackConfig = require('./webpack.config.js');

module.exports = function (config) {
    config.set({

        // base path that will be used to resolve all patterns (eg. files, exclude)
        basePath: '',


        // frameworks to use
        // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
        frameworks: ['mocha'],


        // list of files / patterns to load in the browser
        files: [
            'hncp/vue/**/tests/unit/*.spec.js'
        ],


        // preprocess matching files before serving them to the browser
        // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
        preprocessors: {
            'hncp/vue/**/tests/unit/*.spec.js': ['webpack', 'sourcemap', 'babel']
        },


        babelPreprocessor: {
            options: {
                presets: ['@babel/preset-env'],
                sourceMap: 'inline',
            },
            filename: function (file) {
                return file.originalPath.replace(/\.js$/, '.es5.js')
            },
            sourceFileName: function (file) {
                return file.originalPath;
            },
        },


        webpack: webpackConfig,


        // test results reporter to use
        // possible values: 'dots', 'progress'
        // available reporters: https://npmjs.org/browse/keyword/karma-reporter
        reporters: ['spec'],


        plugins: [
            'karma-phantomjs-launcher',
            'karma-webpack',
            'karma-sourcemap-loader',
            'karma-mocha',
            'karma-spec-reporter',
            'karma-babel-preprocessor',
            'karma-chai',
        ],


        // web server port
        port: 9876,


        // enable / disable colors in the output (reporters and logs)
        colors: true,


        // level of logging
        // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
        logLevel: config.LOG_INFO,


        // enable / disable watching file and executing tests whenever any file changes
        autoWatch: true,


        // start these browsers
        // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
        browsers: ['PhantomJS'],


        // Continuous Integration mode
        // if true, Karma captures browsers, runs the tests and exits
        singleRun: true,

        // Concurrency level
        // how many browser should be started simultaneous
        concurrency: Infinity,
    })
};

webpack.config.js:

var path = require ('path'); var webpack = require ('webpack'); var BundleTracker = require ('webpack-bundle-tracker'); const VueLoaderPlugin = require ('vue-loader / lib / plugin');

module.exports = {
    context: __dirname,
    mode: 'development',
    entry: {
        'hncp/order': ['./hncp/vue/order/src/main'],
    },
    output: {
        path: path.resolve('./hncp/static/webpack_bundles/'),
        filename: "[name].js"
    },
    module: {
        rules: [
            {  // Needed for loading Vue stuff
                test: /\.vue$/,
                loader: 'vue-loader'
            },
            {  // Needed for loading things like <style> tags (used inside Vue stuff)
                test: /\.css$/,
                loader: 'style-loader!css-loader'
            },
            {  // Needed for loading things like png files (used inside Vue templates)
                test: /\.(eot|svg|png|ttf|woff|woff2)(\?\S*)?$/,
                loader: 'file-loader'
            },
            {
                test: /\.js$/,
                exclude: /(node_modules|bower_components)/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['@babel/preset-env']
                    }
                }
            }
        ]
    },

    plugins: [
        new BundleTracker({filename: './webpack-stats.json'}),
        new VueLoaderPlugin()
    ],
};

package.json:

{
    "scripts": {
        "test": "karma start --single-run"
    },
    "dependencies": {
        "babel-preset-es2015": "^6.24.1",
        "karma-cli": "^2.0.0",
        "karma-phantomjs-launcher": "^1.0.4",
        "vue-template-compiler": "^2.5.21"
    },
    "devDependencies": {
        "@babel/core": "^7.2.0",
        "@babel/preset-env": "^7.2.0",
        "@vue/test-utils": "^1.0.0-beta.27",
        "babel-loader": "^8.0.4",
        "chai": "^4.2.0",
        "css-loader": "^2.0.0",
        "file-loader": "^2.0.0",
        "karma": "^3.1.3",
        "karma-babel-preprocessor": "^8.0.0-beta.0",
        "karma-chai": "^0.1.0",
        "karma-chrome-launcher": "^2.2.0",
        "karma-mocha": "^1.3.0",
        "karma-sourcemap-loader": "^0.3.7",
        "karma-spec-reporter": "0.0.32",
        "karma-webpack": "^3.0.5",
        "mocha": "^5.2.0",
        "style-loader": "^0.23.1",
        "vue": "^2.5.21",
        "vue-loader": "^15.4.2",
        "vue-test-utils": "^1.0.0-beta.11",
        "webpack": "^4.27.1",
        "webpack-bundle-tracker": "^0.4.2-beta",
        "webpack-cli": "^3.1.2"
    }
}

Если попробуйте использовать $mount от Vue это отлично работает То есть:

import Vue from 'vue'
import { expect } from 'chai';
import { mount } from '@vue/test-utils';
import UpdateElementRadio from '../../src/components/UpdateElementRadio.vue';

describe('UpdateElementRadio', () => {
  it('accepts label_text prop', () => {
    const vm = new Vue(UpdateElementRadio).$mount();
    console.log(vm);
    expect(vm.props.label_text).to.equal(String);
  });
});

Я знаю, что это немного на что смотреть, но не хватает идей о том, как это исправить.


редактировать

Это UpdateElementRadio:

<template>
    <div class="float-label">
      <label>{{ label_text }}</label>
      <input type="radio" :name="name" v-on:change="$emit('update-value', value)"/>
      <slot></slot>
      <div class="update-element-radio-content" style="float:right">
        {{ value }}
      </div>
    </div>
</template>

<script>
export default {
  name: 'UpdateElementRadio',
  props: {
    label_text: String,
    name: String,
    value: Number
  },
};
</script>

2 ответа

Решение

Поэтому я выяснил, почему это происходит, когда оказывается, что виновником был PhantomJS. Поскольку он больше не разрабатывается активно, это также означает, что он не поддерживает ES6. Смотрите эту проблему на Github для той же проблемы, с которой я столкнулся.

Поэтому вместо этого я решил использовать Chrome для своих тестов и внес следующие изменения:

В karma.conf.js:

//Other config...

plugins: [
            'karma-chrome-launcher',
            ...
         ]

//Other config...

browsers: ['ChromeHeadless'],

//Other config

В файле package.json убедитесь, что karma-chrome-launcher установлено:

{
  //other
  "devDependencies": {
    // Other...
    "karma-chrome-launcher": "^2.2.0",
    // Other...
  }
}

Я думаю, что это связано с compact флаг в babel, его значение по умолчанию составляет 500 КБ.

Вы можете изменить конфигурацию в .babelrc

{
    "compact": false
    // other config
}

Если у вас нет файла Babel, вы можете попробовать отредактировать веб-пакет

rules: [
    {  // Needed for loading Vue stuff
        test: /\.vue$/,
        loader: 'vue-loader',
        compact: false
    },
    {  // Needed for loading things like <style> tags (used inside Vue stuff)
        test: /\.css$/,
        loader: 'style-loader!css-loader',
        compact: false

    },
    {  // Needed for loading things like png files (used inside Vue templates)
        test: /\.(eot|svg|png|ttf|woff|woff2)(\?\S*)?$/,
        loader: 'file-loader'
    },
    {
        test: /\.js$/,
        exclude: /(node_modules|bower_components)/,
        use: {
            loader: 'babel-loader',
            options: {
                presets: ['@babel/preset-env']
            }
        },
        compact: false

    }
]

Babel Doc ссылка

Другие вопросы по тегам