vuejs / vue-cli

🛠️ webpack-based tooling for Vue.js Development
https://cli.vuejs.org/
MIT License
29.76k stars 6.33k forks source link

Jest tests can't process import statement #1584

Open ijdickinson opened 6 years ago

ijdickinson commented 6 years ago

Version

3.0.0-rc.2

Reproduction link

https://github.com/ijdickinson/vue-cli-jest-problem

Steps to reproduce

This is a similar problem to 1475, but I can't find a way to resolve it. I created a new app with vue-cli, selecting Jest tests. I added a simple POJO (src/models/model.js) and a test for it (tests/model.spec.js).

To repro the problem, just npm run test:unit

What is expected?

Tests to pass, or at least run

What is actually happening?

$ npm run test:unit

> test-application@0.1.0 test:unit /home/ian/workspace/project/test-application
> vue-cli-service test:unit

 FAIL  tests/unit/model.spec.js
  ● Test suite failed to run

    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.

    You'll find more details and examples of these config options in the docs:
    https://facebook.github.io/jest/docs/en/configuration.html

    Details:

    /home/ian/workspace/project/test-application/tests/unit/model.spec.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import "core-js/modules/es6.promise";
                                                                                             ^^^^^^

    SyntaxError: Unexpected token import

      at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:402:17)

 PASS  tests/unit/HelloWorld.spec.js

Test Suites: 1 failed, 1 passed, 2 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        1.427s
Ran all test suites.
 ERROR  jest exited with code 1.
minorgod commented 6 years ago

I was able to fix this issue by adding the following to the jest.config.js transform section:

'^.+\\.js$': 'babel-jest',
ijdickinson commented 6 years ago

@minorgod Thanks, I confirm that this does indeed fix my problem.

So, should it be added to the standard template for jest.config.js? Or is it something that just needs to be mentioned in the docs?

Akryum commented 6 years ago

This looks like a bug, since it's done here.

marlonbarcarol commented 6 years ago

Adding '^.+\\.js$': 'babel-jest' does fixes it, I was facing the same problem with vue-cli: 3.0.0-rc.3. Just a reminder that it should be placed in the end of the transform object, right after '^.+\\.tsx?$': 'ts-jest', otherwise it won't work.

Update: I've started to get the same thing again, so I had to run node node_modules/.bin/jest --clearCache to solve it.

onigunn commented 6 years ago

Adding '^.+\\.js$': 'babel-jest' was not enough for me. Tests run only on empty cache once and started throwing Unexpected token errors on change. As mentioned here I also had to add transformIgnorePatterns ['<rootDir>/node_modules/'] to my jest.config.js

Full jest.config.js

module.exports = {
  moduleFileExtensions: ['js', 'jsx', 'json', 'vue'],
  transform: {
    '^.+\\.vue$': 'vue-jest',
    '.+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$':
      'jest-transform-stub',
    '^.+\\.(js|jsx)?$': 'babel-jest'
  },
  moduleNameMapper: {
    '^@/(.*)$': '<rootDir>/src/$1'
  },
  snapshotSerializers: ['jest-serializer-vue'],
  testMatch: [
    '<rootDir>/(tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx))'
  ],
  transformIgnorePatterns: ['<rootDir>/node_modules/']
};

For now everything seems to be good.

tinchox5 commented 6 years ago

Same issue. None of the proposed solutions works for me

hajarrashidi commented 6 years ago

+1

beey-keey commented 6 years ago

Same issue about my tests.. Again none of the solutions worked for me..

rahulakurati commented 6 years ago

+1

marcusnunes commented 6 years ago

Is everyone here using windows? I didn't reproduce the error on mac.

Akryum commented 6 years ago

Note: I can't reproduce on the dev environment.

ijdickinson commented 6 years ago

Is everyone here using windows?

I'm using Ubuntu 18.04

joebartels commented 6 years ago

Reproduced on mac here. For me it occurred after manually incremented all the @vue/* packages to rc.3 from one of the betas (beta.16 I think). I did a rm -rf node_modules && npm cache clean --force && npm install

^ began erroring.

What ended up working for me was globally installing the latest @vue/vue-cli (rc.3) and starting a new project. This also installed all rc.3 @vue/* packages but for some reason it no longer errored.

zhangfaliang commented 6 years ago

npm i -D jest babel-jest babel-preset-es2015 babel-preset-react react-test-renderer

onekiloparsec commented 6 years ago

I did a full clean as proposed by @joebartels above, and I also updated (through the UI) to RC3, but to no avail. Same errors.

It seems to appear only in my tests involving vuex.

rahulakurati commented 6 years ago

I’m running on Mac. I configured this for vuejs. And it worked for me.

Akryum commented 6 years ago

I can't reproduce the issue on Windows 10 & Node 10.4.1:

k-funk commented 6 years ago

For anyone that this may be able to help, I ran into this issue because my IDE auto-imported a library the wrong way: import { put, ... } from 'redux-saga/es/effects'; vs import { put, ... } from 'redux-saga';

onekiloparsec commented 6 years ago

That's it ? Closed ? Well, I am on a Mac, with RC3, and still have the exact same errors. I tried everything that is suggested in this thread. For the archive, here is my latest jest.config.js:

module.exports = {
  moduleFileExtensions: [
    'js',
    'jsx',
    'json',
    'vue'
  ],
  transform: {
    '^.+\\.vue$': 'vue-jest',
    '.+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub',
    '^.+\\.js$': 'babel-jest'
  },
  moduleNameMapper: {
    '^@/(.*)$': '<rootDir>/src/$1'
  },
  snapshotSerializers: [
    'jest-serializer-vue'
  ],
  testMatch: [
    '<rootDir>/(tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx))'
  ],
  transformIgnorePatterns: ['<rootDir>/node_modules/']
}
onekiloparsec commented 6 years ago

Since it was failing on my newly created test file, I decided to remove it. But after 2 min, not happy with this situation, I wanted to retry, so I put it back. And all green ! Tested again, all green.

There must be something fishy with a cache somewhere, no?

joebartels commented 6 years ago

@onekiloparsec that loosely resembles what happened to me. However, instead of removing the file and placing it back, I started a new project with latest vue-cli (@vue/vue-cli (rc.3)) and one-by-one copied files from the "broken" directory into the new one...

epiphone commented 6 years ago

I had a similar problem importing a plain JS vuejs-datepicker locale file, adding the following two fields in my jest config helped:

"transform": {
  "^.+\\.js$": "babel-jest",
  ...
},
"transformIgnorePatterns": ["node_modules/(?!(vuejs-datepicker/dist)/)"],
...

I also ran jest --clearCache afterwards, and naturally added babel-jest to my dependencies.

wangzhanpeng commented 6 years ago

i have the same problem. when i change the jest.config.js like below, is worked. it seem that we nedd trasform vue frist ,then transform js. transform: { '^.+\.vue$': 'vue-jest', '^.+\.js$': 'babel-jest' },

grierson commented 6 years ago

Steps vue create foobar

npm install npm run test:unit

Error SyntaxError: Unexpected token import

System Windows 10 Vue-Cli 3.0.0

onekiloparsec commented 6 years ago

Steps vue create foobar

cd foobar npm run test:unit

PASS  tests/unit/HelloWorld.spec.js
  HelloWorld.vue
    ✓ renders props.msg when passed (37ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        3.91s
Ran all test suites.

System macOS 10.14 Beta Vue-Cli 3.0.0

phmngocnghia commented 5 years ago

+1

gokatz commented 5 years ago

Speaking w.r.t. an existing project. I had the same issue. I resolved it by following the steps done by Vue-CLI (3.0) scaffolding for new projects.

deps added:

    "@vue/cli-plugin-unit-jest": "^3.0.1",
    "@vue/test-utils": "^1.0.0-beta.20",
    "babel-core": "7.0.0-bridge.0",
    "babel-jest": "^23.0.1",

script added:

    "test:unit": "vue-cli-service test:unit",

jest.config.js

module.exports = {
  moduleFileExtensions: [
    'js',
    'jsx',
    'json',
    'vue'
  ],
  transform: {
    '^.+\\.vue$': 'vue-jest',
    '.+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub',
    '^.+\\.jsx?$': 'babel-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/'
}

No specific changes to babel configuration.

morkro commented 5 years ago

I have the exact same issue after it has been working the entire time. Even the suggested solution doesn't fix it for me, I also haven't changed anything besides updating to latest vue-cli dependencies.

LinusBorg commented 5 years ago

I had a quick encounter with this as well, but for me it was something different:

I was using lodash-es, which uses ES6 modules - and since jest won't transform anything from /node_modules by default, this meant I was getting code with import and export statements into my tests, which of course broke.

When I added the following to my jest config, it worked:

transformIgnorePatterns: [
  '<rootDir>/node_modules/(?!lodash-es)'
],

Maybe it helps someone. Took me forever to think about lodash-es being the culprit.


And about this happening with a fresh project: I haven't been able to reproduce it in any way, unfortunately.

znck commented 5 years ago

It is happening in a fresh project. Error is in .spec.js file.

It has something to do with using babel.config.js instead of .babelrc.

morkro commented 5 years ago

I haven't been able to resolve this issue, but there is a discussion in the Jest repository which seems related.

LinusBorg commented 5 years ago

@znck k funnily enough, after I messed with a bunch of package versions in my current small project and resorted to wipe yarn.lock and reinstall everything, my tests now break as well. :/

@morkro Thanks. That issue seems to be related more to transformIgnorePatterns not working though, which shouldn't be the issue if the default test files themselves are not tranformed?

LinusBorg commented 5 years ago

@wangzhanpeng may be on to something

This didn't work in my project, created with 3.0.1:

transform: {
    '^.+\\.jsx?$': 'babel-jest',
    '^.+\\.vue$': 'vue-jest',
    '.+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$':
      'jest-transform-stub',
  },

this works:

  transform:  {
    '^.+\\.vue$': 'vue-jest',
    '^.+\\.jsx?$': 'babel-jest',
    '.+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$':
      'jest-transform-stub',
  },

The order of this array can break transforms, it seems.

However, I wasn't able to replicate this with a fresh project created with vue-cli 3.0.1 just now.

This is all pretty weird...

sdvg commented 5 years ago

I "fixed" this problem for my project by adding the .vue extension to the imports in tests. Hope this helps.

-import Component from './Component';
+import Component from './Component.vue';
davidqqq commented 5 years ago

Hi all, after attempting all the above solution such as transform, clear cache etc and still could not get it to work, I restarted my laptop and magically everything work now. At least for me it obviously has something to do with caching. If you have came across the same issue, restart now might help you save 2 precious hours.

morkro commented 5 years ago

I was unable to resolve the issue with all the solutions offered here, and ended up just moving the project folder to a temporary location. This fixed the issue for me. So my guess is also related to caching.

danipv commented 5 years ago

Seems to be a problem with babel integration in Jest. After trying all suggestions in this thread without success I read this Jest doc page and finally I solved it.

I did the next changes in my config files:

package.json:

+"@babel/core": "*",
+"@babel/preset-env": "*",
+"babel-core": "7.0.0-bridge.0",
+"babel-jest": "*",

babel.config.js:

module.exports = {
  presets: [
+  '@babel/preset-env',
    @vue/app',
  ],
};

Before the changes I execute these commands in order to start the installation of dependencies as clean as possible, not sure if they are needed:

rm -rf node_modules && rm -rf ~/.npm/ && npm cache clean --force && npm install

Thanks to @mmtr for the clue of babel. Hope this solution works for all of you.

LinusBorg commented 5 years ago

Hm that would be weird. All of these dependencies are already installed directly or indirectly, and @vue/preset-app includes @babel/preset-app, so adding that shouldn't make a difference either.

danipv commented 5 years ago

Hi Linus, thanks for your response.

I can reproduce the problem moving the babel-jest dependency to the 23.4.2 version, you are right, I don't need to define the babel preset and the @babel dependencies explicitly.

If I move the babel-jest to the 23.6.0 version, the problem is solved and all test goes green.

So this reduce the solution to:

-"babel-jest": "23.4.2",
+"babel-jest": "23.6.0",

I'm removing the package-lock.json before installing the dependencies, remove .npm folder or clean the cache seems to have no effect.

imdugud commented 5 years ago

i have the same problem. when i change the jest.config.js like below, is worked. it seem that we nedd trasform vue frist ,then transform js. transform: { '^.+.vue$': 'vue-jest', '^.+.js$': 'babel-jest' },

Thanks, that solved my problem! :+1: :+1: I never guessed it.

komali2 commented 5 years ago

I have tried all variations of the above solutions, on ubuntu 18.04, none work. I cleared cache after every attempt, and have restarted my computer several times.

package.json

    "transform": {
      "^.+\\.vue$": "vue-jest",
      "^.+\\.js$": "babel-jest",
      "^.+\\.jsx?$": "babel-jest",
      ".+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$": "jest-transform-stub"
    },

example.spec.js

import { shallowMount } from '@vue/test-utils'
import HelloWorld from '@/components/HelloWorld.vue'

describe('HelloWorld.vue', () => {
    it('renders props.msg when passed', () => {
        const msg = 'new message'
        const wrapper = shallowMount(HelloWorld, {
            propsData: { msg }
        })
        expect(wrapper.text()).toMatch(msg)
    })
})

Error:


    SyntaxError: Unexpected token import

      at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:403:17)
morkro commented 5 years ago

@komali2 Have you tried checking out the repository in a new location?

JeremyWalters commented 5 years ago

Also having the same issue with a newly created project. I also believe it is some caching issue, because it work once sometime after changes.

module.exports = {
  moduleFileExtensions: ["vue", "js", "jsx", "json", "ts", "tsx"],
  transform: {
    "^.+\\.vue$": "vue-jest",
    "^.+\\.tsx?$": "ts-jest",
    "^.+.js$": "babel-jest",
    ".+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$":
      "jest-transform-stub"
  },
  moduleNameMapper: {
    "^@/(.*)$": "<rootDir>/src/$1"
  },
  snapshotSerializers: ["jest-serializer-vue"],
  testMatch: [
    "**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)"
  ],
  testURL: "http://localhost/"
};

Babel config name : babel.config.js Jest Config name: jest.config.js Test file under tests/unit/*.spec.ts

komali2 commented 5 years ago

@komali2 Have you tried checking out the repository in a new location?

Can you clarify what you mean? Do you mean do a full project tear down? Not yet, I can try if necessary. I have wiped out node_modules, that should take care of caching, is that what you suspect?

morkro commented 5 years ago

@komali2 Sure, I meant doing a fresh git clone of the repository in a different location, e.g. a parent folder. In my case this was the only solution, I suspect it is related to some caching issue.

komali2 commented 5 years ago

@morkro That didn't work. The babel-jest people are saying something about converting a .babelrc to a .babel.config.js, but as I use vue-cli, I don't have a .babelrc.

marlonbarcarol commented 5 years ago

@komali2 Have you tried to delete the node_modules folder and consequently to install again your dependencies? You can delete the folder running on your terminal rm -rf node_modules

komali2 commented 5 years ago

@marlonbarcarol Yes, I've done this.

LinusBorg commented 5 years ago

I'm a bit out of things to recommend. Just to make sure: you are running vue-cli-service test: unit command, not jest directly, right?

komali2 commented 5 years ago

@LinusBorg Cheers, correct. Here's the whole package.json:

{
  "name": "example",
  "version": "1.0.0",
  "private": true,
  "description": "example",
  "main": "build/index.js",
  "scripts": {
    "build": "npm run build:ui && npm run build:api",
    "build:api": "tsc && rsync -a --include '*/' --include '*.txt' --exclude '*' lib/ build/",
    "lint": "tslint 'lib/**/*.ts' && eslint --ext .js,.vue client/src",
    "lint:api": "tslint lib/**/*.ts",
    "pretest": "find build -name '*.integration.*' -delete && ./scripts/check_nodejs_version.sh && tsc",
    "start": "node build/index.js",
    "test": "NODE_ENV=test nyc mocha",
    "serve:ui": "vue-cli-service serve client/src/main.js",
    "build:ui": "vue-cli-service build --dest build/public/ client/src/main.js",
    "lint:ui": "vue-cli-service lint",
    "test:unit:ui": "vue-cli-service test:unit"
  },
  "dependencies": {
    "@types/bcrypt": "^1.0.0",
    "@types/bunyan": "^1.8.4",
    "@types/config": "0.0.33",
    "@types/handlebars": "^4.0.38",
    "@types/ioredis": "^3.2.11",
    "@types/koa": "^2.0.46",
    "@types/koa-bodyparser": "^3.0.20",
    "@types/koa-router": "^7.0.30",
    "@types/koa-send": "^4.1.0",
    "@types/node": "^8.10.25",
    "@types/nodemailer": "^4.6.2",
    "aws-sdk": "^2.268.1",
    "axios": "^0.17.1",
    "bcrypt": "^1.0.3",
    "bluebird": "^3.5.1",
    "bull": "^3.4.7",
    "bunyan": "^1.8.12",
    "bunyan-syslog": "git+ssh://git@github.com/jdubjdub/node-bunyan-syslog.git",
    "config": "^1.30.0",
    "d3": "^4.12.0",
    "font-awesome-webpack": "^0.0.5-beta.2",
    "handlebars": "^4.0.11",
    "ioredis": "^3.2.2",
    "jquery": "^3.2.1",
    "koa": "^2.0.0",
    "koa-bodyparser": "^3.1.0",
    "koa-router": "^7.0.1",
    "koa-send": "^4.1.2",
    "materialize-css": "^0.100.2",
    "md5": "^2.2.1",
    "mjml": "^4.1.0",
    "moment": "^2.22.2",
    "nodemailer": "^4.6.7",
    "otplib": "^10.0.1",
    "pg-promise": "^7.3.1",
    "vue": "^2.5.12",
    "vue-resource": "^1.3.5",
    "vue-router": "^3.0.1",
    "vue2-ace-editor": "0.0.3",
    "webpack": "^4.20.2"
  },
  "devDependencies": {
    "@types/bluebird": "^3.5.21",
    "@types/bull": "^3.3.19",
    "@types/chai": "^4.1.4",
    "@types/mjml": "^4.0.0",
    "@types/mocha": "^2.2.33",
    "@types/uuid": "^3.4.3",
    "@vue/cli-plugin-babel": "^3.0.4",
    "@vue/cli-plugin-eslint": "^3.0.4",
    "@vue/cli-plugin-unit-jest": "^3.0.4",
    "@vue/cli-service": "^3.0.4",
    "@vue/eslint-config-standard": "^3.0.4",
    "@vue/test-utils": "^1.0.0-beta.20",
    "autoprefixer": "^7.2.3",
    "babel-eslint": "^8.2.5",
    "babel-jest": "^23.6.0",
    "babel-loader": "^7.1.5",
    "babel-plugin-istanbul": "^4.1.5",
    "babel-plugin-transform-runtime": "^6.23.0",
    "babel-preset-env": "^1.6.1",
    "babel-preset-stage-2": "^6.24.1",
    "babel-register": "^6.26.0",
    "chai": "^4.2.0",
    "cross-env": "^5.2.0",
    "cross-spawn": "^5.1.0",
    "css-loader": "^0.28.7",
    "eslint": "^4.13.1",
    "eslint-friendly-formatter": "^3.0.0",
    "eslint-loader": "^1.9.0",
    "eslint-plugin-html": "^4.0.5",
    "inject-loader": "^3.0.1",
    "karma": "^3.0.0",
    "karma-coverage": "^1.1.1",
    "karma-mocha": "^1.3.0",
    "karma-phantomjs-launcher": "^1.0.2",
    "karma-phantomjs-shim": "^1.4.0",
    "karma-sinon-chai": "^1.3.1",
    "karma-sourcemap-loader": "^0.3.7",
    "karma-spec-reporter": "0.0.31",
    "karma-webpack": "^2.0.2",
    "madge": "^3.2.0",
    "mocha": "^4.0.1",
    "mocha-typescript": "^1.1.16",
    "nightwatch": "^1.0.6",
    "node-notifier": "^5.1.2",
    "nyc": "^13.0.0",
    "optimize-css-assets-webpack-plugin": "^3.2.0",
    "ora": "^1.2.0",
    "phantomjs-prebuilt": "^2.1.14",
    "portfinder": "^1.0.13",
    "postcss-import": "^11.0.0",
    "postcss-loader": "^2.0.9",
    "rimraf": "^2.6.2",
    "selenium-server": "^3.13.0",
    "semver": "^5.4.1",
    "shelljs": "^0.7.8",
    "sinon": "^4.0.0",
    "sinon-chai": "^2.8.0",
    "source-map-support": "*",
    "ts-node": "^3.3.0",
    "tslint": "^5.10.0",
    "typescript": "^2.9.2",
    "uglifyjs-webpack-plugin": "^1.2.7",
    "uuid": "^3.3.2",
    "vue-loader": "^15.4.2",
    "vue-style-loader": "^3.0.3",
    "vue-template-compiler": "^2.5.12",
    "webpack-bundle-analyzer": "^2.13.1",
    "webpack-dev-server": "^3.1.9",
    "webpack-merge": "^4.1.3"
  },
  "nyc": {
    "check-coverage": true,
    "lines": 0,
    "statements": 0,
    "functions": 0,
    "branches": 0,
    "include": [
      "build/api/**/*.js"
    ],
    "exclude": [
      "test/**/*.js"
    ],
    "reporter": [
      "lcov",
      "text-summary"
    ],
    "all": true
  },
  "engines": {
    "node": ">= 8.11.0",
    "npm": ">= 5.6.0"
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not ie <= 8"
  ],
  "postcss": {
    "plugins": {
      "autoprefixer": {}
    }
  },
  "jest": {
    "moduleFileExtensions": [
      "js",
      "jsx",
      "json",
      "vue"
    ],
    "transform": {
      "^.+\\.vue$": "vue-jest",
      "^.+\\.js$": "babel-jest",
      "^.+\\.jsx?$": "babel-jest",
      ".+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$": "jest-transform-stub"
    },
    "moduleNameMapper": {
      "^@/(.*)$": "<rootDir>/src/$1"
    },
    "snapshotSerializers": [
      "jest-serializer-vue"
    ],
    "testMatch": [
      "**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)"
    ],
    "testURL": "http://localhost/"
  }
}