76

I got error of SyntaxError: Unexpected token .

in my code

import 'react-dates/lib/css/_datepicker.css'
import 'semantic-ui-css/semantic.min.css'

those isn't in my spec.js but my implementation code, any clue why? I have no problem running my app but jest throw error when I try to run test.

15
  • Try without extension. eg: import 'react-dates/lib/css/_datepicker. Also please see stackoverflow.com/questions/49263429/… could fix your issue Commented Feb 11, 2019 at 9:05
  • nope, I got unresolved module if I remove the .css Commented Feb 11, 2019 at 9:27
  • are you using babel-jest ? It looks like babel-jest is missing among your dependencies. That's why jest is not running babel on your ES6+ code before executing tests. Commented Feb 11, 2019 at 9:30
  • @MebinJoe I did. Commented Feb 11, 2019 at 10:08
  • 1
    See here: stackoverflow.com/a/39434579/1136887 Commented Feb 12, 2019 at 7:26

5 Answers 5

121

The problem is that Jest is hitting these CSS imports and trying to parse them as if they were JavaScript.

The "Unexpected token ." message probably comes because the first line of the file it is choking on is a CSS class declaration, i.e. .datepicker: { ... }.

Anyway, as pointed out in this answer, the way to get around this is to create a file containing a module which exports an empty object. I called mine styleMock.js.

module.exports = {};

Then, you need to create a jest.config.js file in your project root and add:

module.exports = {
  moduleNameMapper: {
    '\\.(css|less)$': '<rootDir>/test/jest/__mocks__/styleMock.js',
  }
};

The moduleNameMapper setting tells Jest how to interpret files with different extensions. In this case we simply need to point it at the empty file we just created. Obviously adjust the path to your file accordingly.

And note that you can expand the regex above for whichever file endings you need. Mine looks like:

moduleNameMapper: {
  '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
    '<rootDir>/test/jest/__mocks__/fileMock.js',
  '\\.(css|less)$': '<rootDir>/test/jest/__mocks__/styleMock.js',
},

where fileMock.js is identical to styleMock.js

Alternatively, you could use a module such as jest-transform-stub, which does the same thing for you.

Sign up to request clarification or add additional context in comments.

5 Comments

Amazing answer! Once I fixed to the file paths to match my project and changed (css|less) to (css|less|scss), it worked for me. Thanks.
I am trying this but i get a configuration error: Could not locate module react-datepicker/dist/react-datepicker.css mapped as: /home/alejo/tecnimaq/tecnilab/frontend/test/jest/__mocks__/styleMock.js. Please check your configuration for these entries: { "moduleNameMapper": { "/\.(css|less)$/": "/home/alejo/tecnimaq/tecnilab/frontend/test/jest/__mocks__/styleMock.js" }, "resolver": undefined }
I'm back and appreciating this answer again. For RedwoodJs, I see that this seems to be the point of @redwoodjs\testing\dist\fileMock.js. Unfortunately it omits scss. My fix: const moduleNameMapper = { ...config.moduleNameMapper, '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga|css|scss|less)$': '@redwoodjs/testing/dist/fileMock.js' }; delete moduleNameMapper['\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga|css)$']; const configWithEditedModuleNameMapper = { ...config, moduleNameMapper: moduleNameMapper };
(That fix needs to go in web\jest.config.js, which then needs to end with module.exports = configWithEditedModuleNameMapper;.)
Spun my wheels with this for 20 minutes before I realized that my scripts in package.json pointed to an external jest.config.js ala "test": "jest --config=./jest.config.js --silent",. Moved the moduleNameMapper config to that file and then it worked.
34

For anyone hitting this question in fall 2020 or later, for an error like SyntaxError: Invalid or unexpected token when Jest parses CSS files: True, the error is due to Jest trying to parse the CSS as JavaScript, which wont work. So the updated way to handle this is 3 steps, per the Jest documentation on handling static assets, but you dont need to add an additional package like identity-obj-proxy as @chitra suggested unless you're using CSS Modules. And to contrast @james-hibbard 's suggestions: the fileMock.js now looks slightly different and you don't need to create a jest.config.js .

1 in your package.json add this

{
  "jest": {
    "moduleNameMapper": {
      "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
      "\\.(css|less)$": "<rootDir>/__mocks__/styleMock.js"
    }
  }
}

2 Then create the following two files:

// __mocks__/styleMock.js

module.exports = {};

3

// __mocks__/fileMock.js

module.exports = 'test-file-stub';

That should fix these specific errors when Jest runs like

SyntaxError: Invalid or unexpected token
> 1 | import '../src/css/console.scss';

5 Comments

Hi Cat Perry, I get the error: ` Could not locate module @reach/tabs/styles.css mapped as: ./src/tests/mocks/styleMock.js.` Do you have any idea what is going on here?
hmm not sure about this one, sorry
This was the solution for me after hours of debugging and comparing to the with-jest example repo. This solution worked with react-16.14 & react-dom-16.14 while the example repo on react-16.12 & react-dom-16.12 was succeeding with the old solution, both on next-10.0.
@J.Hesters For what it's worth 2 years later, that's an issue where you have most likely given the wrong path for the file you're mocking your css as. Check the file path for the styleMock.js again and that should rectify the issue.
Thank you! This works for me when using sass too '\\.(sass)$': 'identity-obj-proxy', e.g import styles from './Something.module.sass
33

Jest doesn't works with JSX which imports CSS.

I solved this by using the moduleNameMapper key in the jest configurations in the package.json file.

{
   "jest":{
        "moduleNameMapper":{
             "\\.(css|less|scss|sass)$": "identity-obj-proxy" 
        }
   }
}

But you will need to install identity-obj-proxy package as a dev dependancy i.e.

yarn add identity-obj-proxy -D

Comments

13

Mocks

First method
You can mock imported css directly in test file.

// Component.test.js

jest.mock('react-dates/lib/css/_datepicker.css', () => '')
describe('', () => {...})

Second method
Or mock it global. Inside [root]/jest-config/mocks create two files: reactDatePicker.js and index.js

// reactDatePicker.js
/* global jest */

export default () => jest.mock('react-dates/lib/css/_datepicker.css', () => '')
// index.js
import reactDatePickerCssMock from './reactDatePicker'

reactDatePickerCssMock()

Then inside package.json

"jest": {
  "setupFilesAfterEnv": ["<rootDir>/jest-config/mocks/index.js"]
}

1 Comment

For those that travelled this far. The first method works if for some reason you have to import a css file from node_modules directly. My case was module federation shared dependencies caused a legacy package's css not to get picked up. import 'react-dual-listbox/lib/react-dual-listbox.css'; in setup file: jest.mock('react-dual-listbox/lib/react-dual-listbox.css', () => ''); Doing it in setup file ensures that it doesn't break any mounted or RTL tests that have the import in a child component down in the tree.
2

If the top answer didn't solve your problem, make sure that you put mapping in the very beginning of the array:

// does not work for CSS paths starting with ~
moduleNameMapper: {
    '^~/(.*)$': '<rootDir>/$1',
    '\\.(css|sass|scss)$': '<rootDir>/test/jest/__mocks__/styleMock.js',
}

// works
moduleNameMapper: {
    '\\.(css|sass|scss)$': '<rootDir>/test/jest/__mocks__/styleMock.js',
    '^~/(.*)$': '<rootDir>/$1',
},

1 Comment

Thank you, thank you, thank you. Only thing that worked for me!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.