Jest: Unexpected token import (babel-eslint not available from tested file, symlink env)

Created on 8 Feb 2017  ยท  12Comments  ยท  Source: facebook/jest

Do you want to request a feature or report a bug?

feature to solve a bug?

What is the current behavior?

Hi,

I'm having trouble integrating unit tests in a particular folder of my project.

My architecture is as follows:
|_ shared
|_ job-board
|_ admin-panel

job_board and admin-panel each contain a _symlink_ pointing to shared, at ./client/src/shared, and each contain a node_modules folder with babel-eslint installed. shared does NOT contain a node_modules folder, and relies on the 2 other folder's node_modules.

With this architecture, I've managed to configure all the tools I'm using (Webpack, eslint, eslint-loader, ... but Jest).

The problem is, when I create a *.test.js file in job_board/* or admin_panel/*, babel-jest is applied correctly on this file, but when I create this file in shared/*, babel-jest isn't applied (as babel-jest is not available in shared), as the following error proves:

 FAIL  ..\shared\utils\tests\StringUtils.test.js
  โ— Test suite failed to run

    SyntaxError: Unexpected token import

Here is my jest-config.json file:

{
  "moduleFileExtensions": [
    "js"
  ],
  "moduleNameMapper": {
    "\\.(css|scss)$": "identity-obj-proxy"
  },
  "modulePaths": [
    "<rootDir>/client"
  ],
  "testPathDirs": [
    "<rootDir>",
    "<rootDir>/../shared"
  ],
  "testRegex": "(\\.|/)test\\.jsx?$"
}

(Note that I had to add "<rootDir>/../shared" to testPathDirs so that *.test.js files could be found)

And my .babelrc file:

{
  "plugins": [
    "transform-decorators-legacy",
    "transform-object-rest-spread"
  ],
  "presets": [
    ["es2015", { "modules": false }],
    "react",
    "stage-0"
  ],
  "env": {
    "development": {
      "presets": [
        "react-hmre"
      ]
    },
    "test": {
      "plugins": ["transform-es2015-modules-commonjs"]
    }
  }
}

Finally, I run my tests with: node --harmony_proxies node_modules/jest-cli/bin/jest.js --config ./jest-config.json

Am I missing something out, or is this really a lack of a feature giving the ability to provide a "root" for babel-eslint or something?

If the current behavior is a bug, please provide the steps to reproduce and either a repl.it demo through https://repl.it/languages/jest or a minimal repository on GitHub that we can yarn install and yarn test.

What is the expected behavior?

I would expect being able to use babel-eslint from the rootDirectory and not from the location of my test file.

Please provide your exact Jest configuration and mention your Jest, node, yarn/npm version and operating system.

Jest configuration pasted above.
jest-cli: 18.1.0
node: 5.6.0
npm: 3.6.0
OS: Windows 10

Most helpful comment

Hi, you have to specify a test environment in your .babelrc, following the docs: https://facebook.github.io/jest/docs/webpack.html#using-with-webpack-2

That should do the trick for you!

All 12 comments

This doesn't seem like a Jest issue. This is not a help forum. Please ask on stack overflow.

Check transformIgnorePatterns, you may need to customize that.

I read all the issues concerning 'Unexpected token import', and transformIgnorePatterns is not the issue.

This is not a help forum, but I'm asking for a feature so that babel-jest, a package you're maintaining, is resolved based on the <rootDirectory> and not on the directory of the test file...

You're saying here: https://github.com/facebook/jest/issues/770 that babel-jest must be available from the rootDir, and it is. So why doesn't it work when it is not available from the directory of test file?
capture

The problem then might be that you are trying to run tests outside of your rootDir, which is not advised. Note that testPathDirs will be renamed to roots in the next release, because that is what it actually is. I recommend you to set your rootDir to something one level up and simplify your config by limiting what "testPathDirs" looks at.

When I change my config file like this:

{
  "moduleFileExtensions": [
    "js"
  ],
  "moduleNameMapper": {
    "\\.(css|scss)$": "identity-obj-proxy"
  },
  "modulePaths": [
    "<rootDir>/client"
  ],
  "rootDir": "<rootDir>/..",
  "testPathDirs": [
    "<rootDir>"
  ],
  "testRegex": "(\\.|/)test\\.jsx?$"
}

It doesn't find my test file in shared

Edit: and like this:

{
  "moduleFileExtensions": [
    "js"
  ],
  "moduleNameMapper": {
    "\\.(css|scss)$": "identity-obj-proxy"
  },
  "modulePaths": [
    "<rootDir>/admin-panel/client"
  ],
  "rootDir": "../",
  "testPathDirs": [
    "<rootDir>/admin-panel",
    "<rootDir>/shared"
  ],
  "testRegex": "(\\.|/)test\\.jsx?$"
}

It finds all of my test but I have Unexpected token import in all of them, and hence all fail.

How can Jest find it if you omit it in modulePaths? I think you should include it:

  "modulePaths": [
    "<rootDir>",
    "<rootDir>/client",
    "<rootDir>/shared"
  ]

First version didn't resolve rootDir correctly, I found it out thanks to --debug.
Tried in second version, but still no luck... Import error in all tests.
I guess that is because lifting my rootDir to the same level as job-board, admin-panel and shared still doesn't give access to babel-jest (that is no longer accessible from rootDir).

Edit: also explicitly tried to write down the path to babel-jest:

"transform": {
    "\\.jsx?$": "<rootDir>/node_modules/babel-jest"
  },

But still tests in shared can't resolve it.
In context:

{
  "moduleFileExtensions": ["js"],
  "moduleNameMapper": {"\\.(css|scss)$": "identity-obj-proxy"},
  "modulePaths": ["<rootDir>/client"],
  "transform": {"\\.js$": "<rootDir>/node_modules/babel-jest"},
  "testPathDirs": [
    "<rootDir>",
    "<rootDir>/../shared"
  ],
  "testRegex": "(\\.|/)test\\.js$"
}

Edit2: also tried to map babel-jest to its path:

"moduleNameMapper": {
    "\\.(css|scss)$": "identity-obj-proxy",
    "babel-jest": "<rootDir>/node_modules/babel-jest"
  },

Again, no luck. That sort of thing works well with other tools of the Javascript ecosystem, I think there really is a feature missing here.

For those interested by a workaround, I came up with a solution while going through the source files of babel-jest. Just create a .babelrc at the common root of your repos, extending the real one. So in my case:

{
  "extends": "./admin-panel/.babelrc"
}

@thymikee @cpojer
Hello there, I'm not sure if I should create a new issue of if this is an expected behaviour but I had an issue similar to op's one.
With the following .babelrc jest doesn't work correctly (it doesn't use babel at all: SyntaxError: Unexpected token import):

{
  "presets": [
    ["es2015", { "modules": false } ],
    "stage-0",
    "react"
  ],
  "plugins": [
    "babel-plugin-transform-decorators-legacy",
    ["module-resolver", { "alias": { "src": "./src" } }]
  ],
  "env": {
    "development": {
      "plugins": ["react-hot-loader/babel"]
    },
    "production": {
      "plugins": []
    }
  }
}

Removing { "modules": false } from the es2015 preset makes it work correctly though.
Is this a known thing?

P.S.: I'm using webpack 2, but here is my package.json for reference:

{
  "name": "airmedia-client",
  "version": "1.0.0",
  "private": true,
  "engines": {
    "node": "6.9.1"
  },
  "scripts": {
    "postinstall": "npm run build",
    "start": "NODE_ENV=production node config/server.js",
    "develop": "NODE_ENV=development webpack-dev-server --config config/webpack.config.dev.js --progress",
    "reset": "rm -rf node_modules/ && npm cache clean && npm prune",
    "build": "NODE_ENV=production webpack --config config/webpack.config.prod.js --progress",
    "lint": "eslint src config test --ext .js",
    "flow": "flow src",
    "test": "jest",
    "test:watch": "npm run test -- --watch",
    "test:coverage": "npm run test -- --coverage",
    "storybook": "start-storybook -p 6006",
    "build-storybook": "build-storybook"
  },
  "devDependencies": {
    "@kadira/storybook": "^2.21.0",
    "eslint": "3.15.0",
    "eslint-import-resolver-babel-module": "3.0.0",
    "eslint-plugin-prettier": "2.0.0",
    "eslint-plugin-react-app": "1.0.2",
    "flow-bin": "0.39.0",
    "jest": "18.1.0",
    "prettier": "0.16.0",
    "webpack-dev-server": "2.3.0"
  },
  "dependencies": {
    "babel-core": "6.22.1",
    "babel-eslint": "7.1.1",
    "babel-jest": "18.0.0",
    "babel-loader": "6.2.10",
    "babel-plugin-module-resolver": "2.5.0",
    "babel-plugin-transform-decorators-legacy": "1.3.4",
    "babel-polyfill": "6.22.0",
    "babel-preset-es2015": "6.22.0",
    "babel-preset-react": "6.22.0",
    "babel-preset-stage-0": "6.22.0",
    "base-64": "0.1.0",
    "copy-webpack-plugin": "4.0.1",
    "css-loader": "0.26.1",
    "dotenv": "4.0.0",
    "express": "4.14.1",
    "extract-text-webpack-plugin": "2.0.0-rc.3",
    "file-loader": "0.10.0",
    "history": "3.0.0",
    "html-webpack-plugin": "2.28.0",
    "lodash": "4.17.4",
    "object-assign": "4.1.1",
    "parse": "1.9.2",
    "parse-utils": "2.12.1",
    "postcss-cssnext": "2.9.0",
    "postcss-import": "9.1.0",
    "postcss-loader": "1.2.2",
    "promise": "7.1.1",
    "react": "15.4.2",
    "react-addons-css-transition-group": "15.4.2",
    "react-addons-test-utils": "15.4.2",
    "react-css-modules": "4.1.0",
    "react-dev-utils": "0.5.0",
    "react-dom": "15.4.2",
    "react-hot-loader": "3.0.0-beta.6",
    "react-redux": "5.0.2",
    "react-router": "3.0.0",
    "react-router-redux": "4.0.7",
    "redux": "3.6.0",
    "redux-form": "6.5.0",
    "redux-logger": "2.8.1",
    "style-loader": "0.13.1",
    "uuid": "3.0.1",
    "webpack": "2.2.1",
    "webpack-manifest-plugin": "1.1.0",
    "whatwg-fetch": "2.0.2"
  }
}

Hi, you have to specify a test environment in your .babelrc, following the docs: https://facebook.github.io/jest/docs/webpack.html#using-with-webpack-2

That should do the trick for you!

Ha!
Thanks @Zephir77167, it did the trick :)

Was this page helpful?
0 / 5 - 0 ratings