Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jest encountered an unexpected token #937

Closed
mohsinulhaq opened this issue Jan 5, 2019 · 36 comments
Closed

Jest encountered an unexpected token #937

mohsinulhaq opened this issue Jan 5, 2019 · 36 comments

Comments

@mohsinulhaq
Copy link

mohsinulhaq commented Jan 5, 2019

Issue :

I am using ts-jest to test my typescript library. When I run jest, I get the following 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.

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

    Details:

    /Users/mohsinulhaq/Documents/react-popper-tooltip/tests/TooltipTrigger.spec.tsx:9
    const BasicTooltipTrigger = ({ tooltip, children, hideArrow, ...props }) => (<src_1.default {...props} tooltip={({ getTooltipProps, getArrowProps, placement }) => (<div {...getTooltipProps({
                                                                                 ^

    SyntaxError: Unexpected token <

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

Here is my jest.config.js:

module.exports = {
  preset: 'ts-jest',
  globals: {
    'ts-jest': {
      diagnostics: false
    }
  }
};

and my babel.config.js:

module.exports = {
  presets: ['@babel/typescript', ['@babel/env', {loose: true}], '@babel/react'],
  plugins: [['@babel/proposal-class-properties', {loose: true}]]
};

In my package.json, I do have jest, ts-jest, babel-jest and babel-core@7.0.0-bridge.0 installed.
Please help.
Thanks.

EDIT: I get the same output with the babel config file removed. Looks like ts-jest is not picking the babel config file up.

@mohsinulhaq
Copy link
Author

I have since switched to babel-jest + @babel/preset-typescript, which seems to be a much better and well-supported alternative.

@cgilmore
Copy link

I was having this same problem, and this seems to work:

// jest.config.js

module.exports = {
  preset: 'ts-jest',
  transform: {
    '^.+\\.tsx?$': 'babel-jest',
  },
}

@ahnpnl
Copy link
Collaborator

ahnpnl commented Jan 22, 2019

Jest expects module in your tsconfig.spec.ts to set to commonjs. After setting it to commonjs, you have to run jest --clearCache and then run your tests again

@jimishshah
Copy link

jimishshah commented Jan 23, 2019

I am having same issue.
@sikthought I tried your suggestion but now I get follow error.

import React from "react";
           ^^^^^

    SyntaxError: Unexpected identifier

@jimishshah
Copy link

@mohsinulhaq I was able to fix the error similiar to yours by changing jsx property of tsconfig.json. I changed "jsx": "preserve" -> "jsx": "react"
So my tsconfig.json looks like this

{
  "compilerOptions": {
    "allowJs": true,
    "allowSyntheticDefaultImports": true,
    "jsx": "react",
    "lib": ["dom", "es2017"],
    "module": "esnext",
    "moduleResolution": "node",
    "noEmit": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "preserveConstEnums": true,
    "removeComments": false,
    "skipLibCheck": true,
    "sourceMap": true,
    "strict": true,
    "target": "esnext",
  },
  "include": [
    "**/*.ts",
    "**/*.tsx"
  ],
}

jest.config.js

module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'node',
  testMatch: ["**/__tests__/**/*.ts?(x)", "**/?(*.)+(test).ts?(x)"]
};

@mohsinulhaq
Copy link
Author

I think it's much better now to rely on babel for compiling typescript after babel 7, no ts-jest needed as there is an official typescript babel preset (https://babeljs.io/docs/en/babel-preset-typescript). You can wire it to jest using babel-jest like you would normally do for non-ts projects.

@jimishshah
Copy link

@mohsinulhaq can you share your working jest.config.js file ?

@mohsinulhaq
Copy link
Author

https://github.com/mohsinulhaq/react-popper-tooltip
here my repository where I use the above config

@kulshekhar
Copy link
Owner

closing as there's no minimal repo and because this isn't required by the OP any more

@zishe
Copy link

zishe commented Jun 26, 2019

The only issue, when I run a project it changes jsx back to preserve

@avivash
Copy link

avivash commented Jul 9, 2019

The only issue, when I run a project it changes jsx back to preserve

@zishe i was seeing the same issue. I ended up creating a tsconfig.json and a tsconfig.test.json. the latter extends tsconfig.json and changes compilerOptions.jsx to be react.

then i added this to my jest config:

   globals: {
      'ts-jest': {
        tsConfig: 'tsconfig.test.json'
      }
    }

@kevinlucero
Copy link

The only issue, when I run a project it changes jsx back to preserve

@zishe i was seeing the same issue. I ended up creating a tsconfig.json and a tsconfig.test.json. the latter extends tsconfig.json and changes compilerOptions.jsx to be react.

then i added this to my jest config:

   globals: {
      'ts-jest': {
        tsConfig: 'tsconfig.test.json'
      }
    }

thanks, this worked for me.

@KurganskySergey
Copy link

I have since switched to babel-jest + @babel/preset-typescript, which seems to be a much better and well-supported alternative.

yeah if you haven't got any mind blowing issues with that stack go ahead. Looks like TypeORM doesn't want to work with babel stack.

@harjis
Copy link

harjis commented Sep 18, 2019

I had a similar problem. Exact problem was this:

    Details:

    SyntaxError: useHover_test.tsx: Unexpected token (8:53)


       6 | 
       7 | const DummyComponent: React.FC = props => {
    >  8 |   const [ref, isHovering] = useHover<HTMLDivElement>();
         |                                                      ^
       9 |   return <div ref={ref}>{isHovering && props.children}</div>;
      10 | };
      11 | describe('useHover', () => {

I'm using babel 7 and jest 24.9. Changing .babelrc to babel.config.js didn't resolve the problem. Content of the file was:

module.exports = function(api) {
  api.cache(true);
  return {
    presets: [
      [
        '@babel/preset-env',
        {
          targets: {
            browsers: [
              'last 2 Chrome versions',
              'last 2 Edge versions',
              'last 2 Firefox versions',
              'last 2 Safari versions',
              'IE 11',
            ],
          },
          loose: true,
          modules: false,
          useBuiltIns: 'usage',
          corejs: {
            version: 3,
            proposals: true,
          },
        },
      ],
      '@babel/preset-react',
      '@babel/preset-flow',
    ],
    plugins: [
      '@babel/plugin-transform-spread',
      '@babel/plugin-syntax-dynamic-import',
      [
        '@babel/plugin-proposal-class-properties',
        {
          loose: false,
        },
      ],
    ],
    ignore: ['node_modules'],
    overrides: [
      {
        test: ['./src/**/*.ts', './src/**/*.tsx'],
        presets: [
          '@babel/preset-typescript',
          [
            '@babel/preset-env',
            {
              targets: {
                node: 'current',
              },
            },
          ],
          '@babel/preset-react',
        ],
      },
    ],
    env: {
      test: {
        plugins: ['babel-plugin-rewire-ts'],
        presets: ['@babel/preset-env', '@babel/preset-react'],
      },
    },
  };
};

The problem in it was missing @babel/preset-typescript in env. I changed it to

    env: {
      test: {
        plugins: ['babel-plugin-rewire-ts'],
        presets: ['@babel/preset-typescript', '@babel/preset-env', '@babel/preset-react'],
      },
    },

@skurgansky-sugarcrm
Copy link

you should have used ts-jest transformer. If you use babe-jest in transform config you don't use ts-jest so you don't need it in your dependencies

@ziazon
Copy link

ziazon commented Apr 9, 2020

all I had to do to fix this was create a file jest.config.js with the contents of:

module.exports = {
  preset: 'ts-jest'
};

while having also installed ts-jest

@Gibbo3771
Copy link

@jubairsaidi I just want to add onto this, if you have anything in the transform object, remove it.
I originally had this which was causing problems with `preset: "ts--jest"

  transform: {
    // "^.+\\.(js|ts|jsx|tsx)$": "<rootDir>/node_modules/ts-jest", << removed
    "^.+\\.css$": "<rootDir>/config/jest/cssTransform.ts",
  },

@danReynolds
Copy link

danReynolds commented May 8, 2020

I was able to get the JS node module with the offending import statement transpiled by doing:

and use the js-with-ts preset:

module.exports = {
  testEnvironment: "node",
  preset: "ts-jest/presets/js-with-ts",
  transformIgnorePatterns: [ "/node_modules/(?!MODULE_NAME_HERE).+\\.js$"],
};

@Link631
Copy link

Link631 commented May 13, 2020

same error again in another project

node_modules\jest-config\build\readConfigFileAndSetRootDir.js:110
const importedConfig = await import(configUrl.href);

SyntaxError: Unexpected token import
at new Script (vm.js:51:7)
at createScript (vm.js:136:10)
at Object.runInThisContext (vm.js:197:10)
at Module._compile (module.js:613:28)
at Object.Module._extensions..js (module.js:660:10)
at Module.load (module.js:561:32)
at tryModuleLoad (module.js:501:12)
at Function.Module._load (module.js:493:3)
at Module.require (module.js:593:17)
at require (internal/module.js:11:18)
npm ERR! Test failed. See above for more details.

:-(

Cant get it running with typescript and different presets....

@aromakh
Copy link

aromakh commented May 20, 2020

same error again in another project

node_modules\jest-config\build\readConfigFileAndSetRootDir.js:110
const importedConfig = await import(configUrl.href);

SyntaxError: Unexpected token import
at new Script (vm.js:51:7)
at createScript (vm.js:136:10)
at Object.runInThisContext (vm.js:197:10)
at Module._compile (module.js:613:28)
at Object.Module._extensions..js (module.js:660:10)
at Module.load (module.js:561:32)
at tryModuleLoad (module.js:501:12)
at Function.Module._load (module.js:493:3)
at Module.require (module.js:593:17)
at require (internal/module.js:11:18)
npm ERR! Test failed. See above for more details.

:-(

Cant get it running with typescript and different presets....

I had the same error with 9.11.2 node version.
Was able to resolve it by update to 13.1.0.

@omarryhan
Copy link

For anyone still getting this error after reading all the responses above, this helped fix it for me.
I'm only using ts-jest, without any babel dependencies whatsoever in my package.json.

  1. Copy your tsconfig.json to tsconfig.test.json

  2. Add this line to your jest.config.js:

  globals: {
    "ts-jest": {
      tsConfig: "tsconfig.test.json"
    }
  }
  1. Paste this to your tsconfig.test.json
{
  "compilerOptions": {
    "jsx": "react",
    "allowJs": true,
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "noImplicitAny": true,
    "sourceMap": true,
    "target": "es5"
  }
}

@bengrunfeld
Copy link

bengrunfeld commented Sep 1, 2020

So I came across this solution in my Google travels. It worked for me. If it is incorrect, please explain my mistake.

.babelrc

"env": {
    "test": {
        "presets": ["next/babel"]
    }
}

@arteforme
Copy link

Wrestled with this error and finally got ts-jest to work in my project. To do so, I created a bare bones repo, got it working there, and then applied what I learned to my project. To summarize:

  • In tsconfig.json, I had to change "jsx": "preserve" to "jsx": "react"
  • After I made that change, I had to run yarn jest --clearCache as @ahnpnl mentioned. Without this step, it the unexpected token error would still to occur whenever I ran tests.

Here is the bare bones repo for anyone that's interested. It's using testing-library/react, but it should work with other packages. Also note, it doesn't rely on babel.

@lucamjj
Copy link

lucamjj commented Oct 29, 2020

Thank you very much @arteforme !!!!!!!!!!!

@joshuarobs
Copy link

Any reason why this bug still exists? I tried everything and its still not working, I can't get ts-jest to work at all, if I import another typescript repo. Jest really needs to have TypeScript support out of the box, with 0 configuration. At this points its just as difficult to setup like Mocha/Chai

@ahnpnl
Copy link
Collaborator

ahnpnl commented Dec 9, 2020

@joshuarobs jest does support TypeScript out of the box via babel. It is just create-react-app making it hard to adjust. If you setup jest from scratch on a project not using any frameworks, it's pretty easy and straight forward.

You can also check my repo for the setup https://github.com/ahnpnl/react-ts-jest-babel with React.

@joshuarobs
Copy link

@ahnpnl
I tried your repo and tried importing another of my private typescript module and it worked fine, but I can't make it work with Create React App. I'm not sure if I'm meant to use ts-jest or babel to make it work with CRA, or if its even possible in the first place to make CRA work with typescript and jest (and external typescript library imports)

@ahnpnl
Copy link
Collaborator

ahnpnl commented Dec 9, 2020

@joshuarobs I dont know how to setup for create-react-app without ejecting the project. My repo is create-react-app after ejecting. If you don't want to eject your project, it's better you ask in React community or Jest community Discord.

@moimikey
Copy link

this works for mine:

module.exports = {
  verbose: true,
  preset: 'ts-jest',
  testEnvironment: 'node',
  collectCoverageFrom: ['**/*.{js,jsx,ts,tsx}'],
  setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
  testPathIgnorePatterns: [
    '<rootDir>/.cache/',
    '<rootDir>/.github/',
    '<rootDir>/.husky/',
    '<rootDir>/.next/',
    '<rootDir>/.vscode/',
    '<rootDir>/.yarn/',
    '<rootDir>/dist/',
    '<rootDir>/generated/',
    '<rootDir>/prisma/',
  ],
};
module.exports = function config(api) {
  return {
    presets: [
      [
        require.resolve('@babel/preset-env'),
        {
          targets: {
            browsers: ['last 2 versions', 'ie >= 11'],
            node: 'current',
          },
          corejs: '3.1.3',
        },
      ],
      require.resolve('@babel/preset-typescript'),
      ...

@1927344728
Copy link

same issue and it works for mine:

  1. execute jest --init, create jest.config.ts
  2. edit jest.config.ts:
export default {
  ...
  "transform": {
    "^.+\\.(js|ts|tsx)$": "ts-jest"
  },
  ...
}

antonyoneill added a commit to antonyoneill/next-js-todo-ssr that referenced this issue Feb 9, 2021
Next.js requires that jsx is set to preserve in order to provide a
"optimized" jsx transformation.

However, Jest needs jsx to be transformed by the ts compiler.

See
* kulshekhar/ts-jest#937
* https://stackoverflow.com/questions/61973940/next-js-typescript-and-tsconfig-json-jsx-property-being-overwritten

This isn't particularly well publicised by Next from what I can see
* vercel/next.js#11216
* vercel/next.js#19155
@ehxxn
Copy link

ehxxn commented Feb 14, 2021

for me adding "js" to transform fixed the issue

This is before

"transform": {
-       "^.+\\.(ts|tsx)$": "ts-jest"
}

This is after

"transform": {
+        "^.+\\.(ts|tsx|js)$": "ts-jest"
 }

@xinliuleo
Copy link

For whom having this issue in typescript 4.1 or later, and have explicitly set 'jsxImportSource' option in tsconfig.json file, you could probably try setting 'jsx' to 'react-jsx', as 'react' mode would make 'jsxImportSource' yelling.

e.g.

{
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "@emotion/react",
}
}

@CowDotDev
Copy link

CowDotDev commented Sep 21, 2021

For whom having this issue in typescript 4.1 or later, and have explicitly set 'jsxImportSource' option in tsconfig.json file, you could probably try setting 'jsx' to 'react-jsx', as 'react' mode would make 'jsxImportSource' yelling.

e.g.

{
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "@emotion/react",
}
}

Confirmed that this gets me past the error of unexpected token, and then the added error of React refers to a UMD global if you were to update jsx to react. Just as a note, I did not add the jsxImportSource property, I only updated the jsx property from preserver to react-jsx.

Just for others in this same discovery, after this fix if your application specifies custom module paths in your tsconfig.json, such as:

"paths": {
      "@components/*": ["src/components/*"],
      "@hooks/*": ["src/hooks/*"],
      "@lib/*": ["src/lib/*"],
      "@context/*": ["src/context/*"],
      "@models/*": ["src/models/*"],
      "@pages/*": ["src/pages/*"],
      "@services/*": ["src/services/*"],
      "@utils/*": ["src/utils/*"],
      "@constants/*": ["src/constants/*"],
      "@server/*": ["src/server/*"],
      "@/*": ["./*"]
}

Then you also need to add to your jest.config.js a moduleNameMapper for each of your custom paths:

moduleNameMapper: {
    '@components/(.*)': '<rootDir>/src/components/$1',
    '@hooks/(.*)': '<rootDir>/src/hooks/$1',
    '@lib/(.*)': '<rootDir>/src/lib/$1',
    '@context/(.*)': '<rootDir>/src/context/$1',
    '@models/(.*)': '<rootDir>/src/models/$1',
    '@pages/(.*)': '<rootDir>/src/pages/$1',
    '@services/(.*)': '<rootDir>/src/services/$1',
    '@utils/(.*)': '<rootDir>/src/utils/$1',
    '@constants/(.*)': '<rootDir>/src/constants/$1',
    '@server/(.*)': '<rootDir>/src/server/$1',
    '@/(.*)': '<rootDir>/./$1'
}

https://stackoverflow.com/questions/50171412/jest-typescript-absolute-paths-baseurl-gives-error-cannot-find-module

@cubuspl42
Copy link

cubuspl42 commented Oct 5, 2021

For me the error occured in a non-React project, and the cause was simple: I've run npx ts-jest config:init in a subdirectory (by accident) instead of the root folder where tsconfig.json resides. Moving jest.config.js file up the tree fixed the problem.

@charneykaye
Copy link

The best solution is to give up on writing tests in JavaScript. Come back in another ten years.

@zbw-zbw
Copy link

zbw-zbw commented Oct 18, 2023

it can work when tsconfig.json file add "jsxFactory": "React.createElement".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests