60

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.

skyboyer
  • 22,209
  • 7
  • 57
  • 64
Neini Amanda
  • 679
  • 1
  • 5
  • 12

5 Answers5

101

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.

James Hibbard
  • 16,490
  • 14
  • 62
  • 74
  • 2
    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. – Ryan Sep 24 '20 at 15:25
  • 5
    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 } – Alejo Dev Oct 07 '20 at 20:39
  • 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 };` – Ryan Jan 23 '21 at 00:29
  • (That fix needs to go in `web\jest.config.js`, which then needs to end with `module.exports = configWithEditedModuleNameMapper;`.) – Ryan Jan 23 '21 at 00:30
  • 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. – mlsamuelson Sep 12 '21 at 21:55
29

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';
Cat Perry
  • 944
  • 1
  • 11
  • 15
  • 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? – J. Hesters Dec 06 '20 at 14:08
  • hmm not sure about this one, sorry – Cat Perry Dec 11 '20 at 16:34
  • 1
    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. – Lomky Mar 17 '21 at 15:16
  • Worked for react@17.0.2. Thank you! – Greg Jun 10 '21 at 17:22
  • @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. – need_to_know_now Jun 07 '22 at 11:54
26

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
Chitra
  • 1,294
  • 2
  • 13
  • 28
6

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"]
}
Aga
  • 1,019
  • 1
  • 11
  • 16
1

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',
},
EasyGem
  • 111
  • 3