Ilya Gubanov
Ilya Gubanov

Reputation: 31

Cannot use ES6 module of vue.js in test project based on jest and vue-test-utils

Good afternoon. I need to test the vue.js interface based on .vue components. The project with UI itself lies separately from the project with tests for it and it is written in Typescript, as well as the project with tests.

The webpack config uses the vue/dist/vue.esm.js module, which allows me to use the Vue.extend, Vue.use methods and so on.

The test project is configured on a combination of vue-test-utils and jest, and when I try to use the same vue import, I get an error like

export default Vue;
^^^^^^

SyntaxError: Unexpected token 'export'

The same is with import situation.

Here is a simple example of component basic on typescript:

<template>
  <div>

  </div>
</template>

<script lang="ts">
  import Vue from 'vue'
  export default Vue.extend({
    data: () => ({
      ...
    }) 
  })
</script>

And here is the example of simple test for it:

import { mount } from '@vue/test-utils'
import Example from '@components/Example.vue';

describe('example', () => {
    it('should be rendered', () => {
        const wrapper = mount(Example);

        expect(wrapper.isVueInstance()).toBeTruthy();
    })
})

While test execution, i get message, you've seen before:

 path\to\my\project\node_modules\vue\dist\vue.esm.js:11993
    export default Vue;
    ^^^^^^

    SyntaxError: Unexpected token 'export'

      at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1085:14)
      at Object.<anonymous> (node_modules/@vue/test-utils/dist/vue-test-utils.js:7:27)

tsconfig.json

{
    "compilerOptions": {
        "sourceMap": true,
        "noImplicitAny": false,
        "module": "commonjs",
        "target": "es6",
        "baseUrl": ".",
        "allowJs": true,
        "lib": [
            "es2015",
            "es2017",
            "dom",
            "es2018.promise"
        ],
        "paths": {
            "@components/*": ["../path/to/Components/*"],
            "vue$": ["vue/dist/vue.esm.js"]
        },
        "removeComments": true
    },
    "compileOnSave": false,
    "exclude": [ "node_modules" ]
}

jest.config.js:

module.exports = {
    verbose: true,
    testRegex: ".+[.]test[.](ts|js)$",
    moduleNameMapper: {
        "^@components/(.*)$": "<rootDir>/../path/to/Components/$1",
        "vue$": 'vue/dist/vue.esm.js'
    },
    moduleFileExtensions: [
        "ts", "js", "json", "vue"
    ],
    transform: {
        "^.+\\tsx?$": "ts-jest",
        "^.+\\.jsx?$": "babel-jest",
        "^.+\\.js$": "babel-jest",
        ".*\\.(vue)$": "vue-jest"
    },
    preset: 'ts-jest/presets/js-with-ts',
    transformIgnorePatterns: [
        'node_modules/(?!(@babel)/)',
        "/node_modules/(?!(bootstrap-vue)/)",
        "/node_modules/(?!vue)"
    ],
    testURL: "http://localhost/"
}

part of webpack.config.js in main ui project:

module: {
        rules: [
            {
                test: /\.vue$/,
                loader: 'vue-loader'
            },
            {
                test: /\.tsx?$/,
                exclude: /node_modules/,
                use: [
                    { loader: 'babel-loader' },
                    { loader: 'ts-loader', options: { appendTsSuffixTo: [/\.vue$/] } },
                ]
            },
            {
                test: /\.js$/,
                exclude: /node_modules/,
                loader:"babel-loader"
            },
            {
                test: /\.css$/,
                use: [
                    'vue-style-loader',
                    'css-loader'
                ]
            },
            {
                test: /\.less$/,
                use: [
                    'vue-style-loader',
                    'css-loader',
                    'less-loader'
                ]
            }
        ]
    },
    resolve: {
        extensions: ['.ts', '.js', '.vue'],
        alias: {
            'vue$': 'vue/dist/vue.esm.js',
            '@components': path.resolve('path/to/components')
        }
    },
    plugins: [
        new VueLoaderPlugin()
    ]

and here is .babelrc for addition:

{
    "presets": [
        [
            "@babel/preset-env",
            {
                "targets": {
                    "browsers": ["> 1%", "last 2 versions", "ie >= 10"]
                },
                "corejs": 3,
                "modules" : "commonjs"
            }
        ]
    ]
}

If i change vue/dist/vue.esm.js to vue/dist/vue.js, i should change all Vue.extend to export default Vue, and Vue.use() to mixins:[Mixin], what is difficult to testing. + i will not be able to use 'new Vue'.

Somebody knows, how to correctly include ES6 vue npm module (vue.esm.js) into ts testing project? Please

P.S there is no webpack in test project.

Upvotes: 1

Views: 2650

Answers (1)

Ilya Gubanov
Ilya Gubanov

Reputation: 31

Okay, i solved this by adding "allowJs": true and "esModuleInterop": true to tsconfig

Upvotes: 2

Related Questions