最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Jest encountered an unexpected token when testing a Vue single file component - Stack Overflow

programmeradmin9浏览0评论

I have a vue application with single file components and i want to add unit tests to test the components. I'm trying to use jest like described here but i keep getting the error "Jest encountered an unexpected token" with the following details:

/some_path/MyRecipe.vue:1
<template>
^

SyntaxError: Unexpected token <

  1 | import { shallowMount } from "@vue/test-utils"
> 2 | import MyRecipe from "../src/components/MyRecipe.vue"
    | ^
  3 | 
  4 | describe('MyRecipe', () => {
  5 |   test('is a Vue instance', () => {

  at Runtime._execModule (node_modules/jest-runtime/build/index.js:1166:56)
  at Object.<anonymous> (__tests__/MyRecipe.test.js:2:1)

After some research (e.g. from here) I gather that this is probably due to jest expecting a .js file, but the .vue single file components have html, javascript and css in them, usually dealt with by webpack and vue-loader. I've tried to follow jest configurations from various tutorials to make jest use vue-jest to transform .vue files, but the error persists. This is my package.json file (unnecessary parts removed):

{
  "name": "all-recipes ",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    // ...
    "test": "jest"
  },
  "dependencies": {
    // ...
    "core-js": "^3.4.3",
    "vue": "^2.6.10"
    // ...
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "^4.1.0",
    "@vue/cli-plugin-eslint": "^4.1.0",
    "@vue/cli-service": "^4.1.0",
    "@vue/test-utils": "^1.0.3",
    "babel-core": "^7.0.0-bridge.0",
    "babel-eslint": "^10.0.3",
    "babel-jest": "^26.0.1",
    // ...
    "jest": "^26.0.1",
    "jest-serializer-vue": "^2.0.2",
    "vue-jest": "^3.0.5",
    "vue-template-compiler": "^2.6.10",
    "vue-test-utils": "^1.0.0-beta.11"
  },
  // ...
  "jest": {
    "moduleFileExtensions": [
      "js",
      "json",
      "vue"
    ],
    "transform": {
      ".*\\.,(vue)$": "vue-jest",
      "^.+\\.js$": "babel-jest"
    },
    "snapshotSerializers": [
      "jest-serializer-vue"
    ]
  }
}

Any idea what might be wrong, or some tips on how to debug this?

EDIT: I have looked into this question and I don't believe the answer there would solve my problem since what I am trying to import is a .vue file and not an .html file.

EDIT 2: I have a feeling that jest is somehow just not picking up the transforms, because removing them from package.json doesn't change anything.

EDIT 3: No, jest is correctly using vue-jest for transforming. If I uninstall vue-jest and try running the test again, jest complains that vue-jest is missing.

I have a vue application with single file components and i want to add unit tests to test the components. I'm trying to use jest like described here but i keep getting the error "Jest encountered an unexpected token" with the following details:

/some_path/MyRecipe.vue:1
<template>
^

SyntaxError: Unexpected token <

  1 | import { shallowMount } from "@vue/test-utils"
> 2 | import MyRecipe from "../src/components/MyRecipe.vue"
    | ^
  3 | 
  4 | describe('MyRecipe', () => {
  5 |   test('is a Vue instance', () => {

  at Runtime._execModule (node_modules/jest-runtime/build/index.js:1166:56)
  at Object.<anonymous> (__tests__/MyRecipe.test.js:2:1)

After some research (e.g. from here) I gather that this is probably due to jest expecting a .js file, but the .vue single file components have html, javascript and css in them, usually dealt with by webpack and vue-loader. I've tried to follow jest configurations from various tutorials to make jest use vue-jest to transform .vue files, but the error persists. This is my package.json file (unnecessary parts removed):

{
  "name": "all-recipes ",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    // ...
    "test": "jest"
  },
  "dependencies": {
    // ...
    "core-js": "^3.4.3",
    "vue": "^2.6.10"
    // ...
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "^4.1.0",
    "@vue/cli-plugin-eslint": "^4.1.0",
    "@vue/cli-service": "^4.1.0",
    "@vue/test-utils": "^1.0.3",
    "babel-core": "^7.0.0-bridge.0",
    "babel-eslint": "^10.0.3",
    "babel-jest": "^26.0.1",
    // ...
    "jest": "^26.0.1",
    "jest-serializer-vue": "^2.0.2",
    "vue-jest": "^3.0.5",
    "vue-template-compiler": "^2.6.10",
    "vue-test-utils": "^1.0.0-beta.11"
  },
  // ...
  "jest": {
    "moduleFileExtensions": [
      "js",
      "json",
      "vue"
    ],
    "transform": {
      ".*\\.,(vue)$": "vue-jest",
      "^.+\\.js$": "babel-jest"
    },
    "snapshotSerializers": [
      "jest-serializer-vue"
    ]
  }
}

Any idea what might be wrong, or some tips on how to debug this?

EDIT: I have looked into this question and I don't believe the answer there would solve my problem since what I am trying to import is a .vue file and not an .html file.

EDIT 2: I have a feeling that jest is somehow just not picking up the transforms, because removing them from package.json doesn't change anything.

EDIT 3: No, jest is correctly using vue-jest for transforming. If I uninstall vue-jest and try running the test again, jest complains that vue-jest is missing.

Share Improve this question edited May 23, 2020 at 17:50 Nanna asked May 23, 2020 at 14:21 NannaNanna 5752 gold badges10 silver badges28 bronze badges 5
  • Does this answer your question? Jest + Vue - SyntaxError: Unexpected token < – Józef Podlecki Commented May 23, 2020 at 14:25
  • @JózefPodlecki unfortunately, no. In the question you reference, the error comes when trying to import an .html file. I don't believe creating a custom html-loader would solve this problem since the .vue files contain javascript and css as well. – Nanna Commented May 23, 2020 at 14:30
  • 1 any reason you have ".*\\.,(vue)$": "<rootDir>/node_modules/vue-jest" and not just simply ".*\\.(vue)$": "vue-jest" as is stated in the docs? – feihcsim Commented May 23, 2020 at 17:09
  • It was a suggestion from one of the other tutorials I followed, something I tried after initially trying "vue-jest". I just tried changing it back now, in case something had changed in between now and then, but unfortunately that didn't do the trick. – Nanna Commented May 23, 2020 at 17:16
  • 1 To troubleshoot, I would generate a new Vue CLI project, including Jest (which does not have this issue), and figure out the difference from there (e.g., diff it with your project). – tony19 Commented May 23, 2020 at 20:27
Add a comment  | 

5 Answers 5

Reset to default 5

The solution to my problem turns out to be a bit anti-climatic.

The problem was that my regexp string to recognize .vue files was wrong and didn't pick up my MyRecipe.vue file. Therefore, vue-jest wasn't used to transform it for jest to interpret, hence the trouble understanding that the file in question started with a very non-js line; <template>. The regexp that works is ^[^.]+.vue$, so the transform section of my package.json file becomes

{
  // ...
  "jest": {
    // ...
    "transform": {
      "^[^.]+.vue$": "vue-jest",
      "^.+\\.js$": "babel-jest"
    },
    // ...
  }
}

Met same issuesome time ago. What i found.

The problem was in the short note of template v-slot

template(v-slot:body)

It works to compile, but Jest throws an error

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.

There was two ways i fount to solve this:

  1. Edit my jest.config.js, like this
globals: {
  'vue-jest': {
    pug: {
      doctype: 'html',
    },
  },
},
  1. Write a full note like this template(v-slot:body="")

What worked for me was changing the transform of the vue-jest to what is shown in the documentation. https://github.com/vuejs/vue-jest

so try using "^.+\\.vue$": "vue-jest" instead of "^[^.]+.vue$": "vue-jest" full config might look like this

{
  "jest": {
    "moduleFileExtensions": ["js", "json", "vue"],
    "transform": {
      "^.+\\.js$": "babel-jest",
      "^.+\\.vue$": "vue-jest"
     }
   }
}

I faced same issues tried many solution but none of them work ..below is following workaround in my case

  1. Check package json has following dev dependency entries and jest configurations

     "devDependencies": {
         "babel-jest": "^23.6.0",
         "@vue/cli-plugin-babel": "~4.5.0",
         "@vue/cli-plugin-eslint": "~4.5.0",
         "@vue/cli-plugin-unit-jest": "~4.5.0",
         "@vue/cli-service": "~4.5.0",
         "@vue/eslint-config-airbnb": "^5.0.2",
         "@vue/test-utils": "^1.0.3",
         "babel-eslint": "^10.1.0",
         "eslint": "^6.7.2",
         "eslint-plugin-import": "^2.20.2",
         "eslint-plugin-vue": "^6.2.2",
           },
    
      "jest": {
         "moduleFileExtensions": [
         "js",
         "jsx",
         "json",
         "vue"
        ],
      "transform": {
        "^.+\\.vue$": "vue-jest"
        },
     "moduleNameMapper": {
       "^@/(.*)$": "<rootDir>/src/$1"
      },
    "snapshotSerializers": [
       "jest-serializer-vue"
     ],
    "testMatch": [
       "**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*. 
    (js|jsx|ts|tsx)"
     ],
     "testURL": "http://localhost/"
     }
    
  1. Check babel.config.js

      module.exports = {
        presets: [
        '@vue/cli-plugin-babel/preset',
      ],
     };
    
  2. check jest.config.js

      module.exports = {
       preset: '@vue/cli-plugin-unit-jest',
      };
    

You need to install vue-jest (https://github.com/vuejs/vue-jest) with

npm install -D @vue/vue3-jest

Here are the available versions and their corresponding vue and jest versions

Vue version Jest Version Package
Vue 2 Jest <= 26 vue-jest@4
Vue 3 Jest <= 26 vue-jest@5
Vue 2 Jest 27 @vue/vue2-jest
Vue 3 Jest 27 @vue/vue3-jest

Then, you'll just have to update your jest configuration (in jest.config.ts for example) and add a transform section

"transform": {
    "^.+\\.vue$": "@vue/vue3-jest"
}

Warning: be sure to update the npm install and the jest.config.ts with the vue-jest package that match your need!

发布评论

评论列表(0)

  1. 暂无评论