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

/scss/ in preprocessorIgnorePatterns has no effect #870

Closed
doque opened this issue Apr 7, 2016 · 17 comments
Closed

/scss/ in preprocessorIgnorePatterns has no effect #870

doque opened this issue Apr 7, 2016 · 17 comments

Comments

@doque
Copy link
Contributor

doque commented Apr 7, 2016

We're using CSS modules in our React components, which are importing .scss files, like this:

import styles from './ReviewFeedItem.scss';

To ignore them when running jest, I've excluded /scss/ from the module loader (or so I think):

// package.json

"preprocessorIgnorePatterns": [
  "/scss/"
],

However, when running the tests, the module loader still tries (and fails) to parse the .scss file as javascript and yields this error:

Runtime Error
SyntaxError: Unexpected token ILLEGAL in file 'src/components/navigation/Navigation.scss'.

Make sure your preprocessor is set up correctly and ensure your 'preprocessorIgnorePatterns' configuration is correct: http://facebook.github.io/jest/docs/api.html#config-preprocessorignorepatterns-array-string
If you are currently setting up Jest or modifying your preprocessor, try `jest --no-cache`.
Preprocessor: jest-preprocessor.js.
Jest tried to the execute the following preprocessed code:
body { height: 0; }

Any variation of the exclude Pattern, such as \\.scss, scss and so forth has no effect.
We're using babel-jest as the scriptPreprocessor (so no specific entry for that in package.json)

@syrusakbary
Copy link

Any updates on this?

@cpojer
Copy link
Member

cpojer commented Apr 28, 2016

This doesn't work because ignoring scss from the preprocessor just means that it will not be run through babel-jest. Jest will then try to require the scss file directly and then fail because it isn't valid JavaScript.

There are two solutions:

Use the moduleNameMapper option and a stub file:

Jest config:

"moduleNameMapper": {
  "\.scss$": "path/to/SCSSStub.js"
}

SCSSStub.js:

module.exports = {}; // Or other stub data for all SCSS modules.

Build your own preprocessor using node-sass.

I'm not entirely sure what webpack does to export scss files as JavaScript, but basically you'll want to wrap babel-jest and do something like this:

module.exports = function(src, filename) {
  if (fileName.endsWith('.scss')) {
    return processSass(src);
  }
  return babelJest.process(src, filename);
}

where the processSass would use node-sass and whatever the webpack loaders do :)

I hope one of these is a satisfying solution. If you do build a preprocessor that wraps babel-jest, I'd be happy to add it to Jest as an officially supported package.

@cpojer cpojer closed this as completed Apr 28, 2016
@nfarina
Copy link
Contributor

nfarina commented Apr 28, 2016

The moduleNameMapper solution worked great for me. Here's what I used (took me a while to figure out the magic that would make all imports for SCSS files load the same stub):

    "moduleNameMapper": {
      "^.*\\.scss$": "./src/shared/test/SCSSStub.js"
    }

Now requiring SCSS in Jest works exactly like requiring CSS.

@cpojer
Copy link
Member

cpojer commented Apr 29, 2016

that's great!

@rbalicki2
Copy link

rbalicki2 commented May 13, 2016

preprocessorIgnorePatterns does not need slashes around the entries. It should work with .scss$, although to @cpojer 's point that won't fix your problem.

I worked around that by having my preprocessor return an empty string if the filename ends in css|less|etc

@iam-peekay
Copy link

@cpojer I just tried upgrading to v16.0.1 (from v14.1.0) and all our tests now fail because it complains about syntax errors related scss files. We have moduleNameMapper set up and the setup worked fine with v14.1.0. Wondering if you have any thoughts on what might be the issue?

jest setup:

"jest": {
    "moduleFileExtensions": [
      "",
      "js",
      "json"
    ],
    "modulePaths": [
      "./src"
    ],
    "moduleDirectories": [
      "node_modules"
    ],
    "testRegex": "/.*\\-snapshot\\.js$",
    "moduleNameMapper": {
      "^testUtils": "./src/utils/tests.js",
      "^.+\\.(s?css|less)$": "./src/utils/styleMock.js",
      "^.+\\.(gif|ttf|eot|svg)$": "./src/utils/fileMock.js"
    },
    "setupFiles": [
      "./src/utils/setupJest.js"
    ]
  },

styleMock.js

// Return an object to emulate css modules
import idObj from 'identity-obj-proxy';

export default idObj;

Example of an error:
screen shot 2016-10-06 at 11 37 51 am

@andrewdushane
Copy link

andrewdushane commented Oct 17, 2016

@iam-peekay I was getting the same error due to sass imports. Following the instructions in the Jest webpack tutorial resolved the issue for me - specifically adding the moduleNameMapper for files and styles, and the mocks they reference.
I also had to add md to the mapped file extensions as I'm importing markdown content in the project.
Edit - looked at your setup and I see you have a styleMock - maybe try just using an empty object instead of the idObj.

@afraser
Copy link

afraser commented Mar 14, 2017

Took me a while to get this to work for me because I thought the path was relative to the project.

Below works for me:

  "jest": {
    "modulePaths": [
      "v2/app"
    ],
    "moduleNameMapper": {
      ".scss$": "SassStub.js"  // <-- lives in v2/app
    },
    "testPathIgnorePatterns": [
      "/node_modules/",
      "/build/"
    ]
  }

SassStub.js

module.exports = {}

@leongaban
Copy link

Hi guys, I'm running into this problem too. What is a SassStub.js file? What goes inside it? Can't find anything about it.

@hoosierhuy
Copy link

@leongaban Try this solution: https://stackoverflow.com/questions/41040269/syntax-error-when-test-component-with-sass-file-imported

@doque
Copy link
Contributor Author

doque commented Jul 11, 2017

@leongaban See #870 (comment):

SassStub.js

module.exports = {}

@emileber
Copy link
Contributor

emileber commented Jan 5, 2018

Just a note for future readers, the moduleNameMapper ordering is important.

I wanted to stub style imported in modules, something like:

// module.js
import Style from '@/path/to/style.scss';
import App from './App';

So I created a style stub file:

// test/unit/stubs/style.js
module.exports = '.style-stub{color:red;}';

After messing around with the following jest.conf.js:

moduleNameMapper: {
    '^@/(.*)$': '<rootDir>/src/$1', // '@' alias
    '^.*\\.scss$': '<rootDir>/test/unit/stubs/style.js',
}

The @ alias rule was resolving before my .scss rule, so the style file was loaded as a normal module and would crash the test.

The solution was to put specific rules first.

moduleNameMapper: {
    '^.*\\.scss$': '<rootDir>/test/unit/stubs/style.js',
    '^@/(.*)$': '<rootDir>/src/$1',
}

@thymikee
Copy link
Collaborator

thymikee commented Jan 5, 2018

@emileber it's generally advised to have as moduleNameMapper regexes as specific as possible, to avoid such problems and confusion to consumers.

@emileber
Copy link
Contributor

emileber commented Jan 5, 2018

@thymikee Regexes are a maintenance nightmare, so keeping them as simple as possible is best in my opinion.

I feel like it's much more likely that any confusion in this regard comes from the missing documentation rather than under-specific regexes.

@thymikee
Copy link
Collaborator

thymikee commented Jan 6, 2018

@emileber interested in contributing to docs? 🙂 Patterns are indeed checked one-by-one until they fit and then bailout.

@sekoyo
Copy link

sekoyo commented Mar 15, 2018

Struggling to get this to work, I have:

"jest": {
  "transform": {
    "^.+\\.jsx?$": "babel-jest"
  },
  "collectCoverageFrom": [
    "src/**/*.{js,jsx}"
  ],
  "moduleNameMapper": {
    "^.*[.](jpe?g|gif|png|less|css)$": "./emptyTestModule.js"
  },
  "setupFiles": [
    "<rootDir>/setupTests.js"
  ]
}

And I'm not exactly sure where to put the emptyTestModule, I've tried both the root and src/ but I get:

 Test suite failed to run

    Configuration error:

    Could not locate module ag-grid/dist/styles/ag-grid.css (mapped as emptyTestModule.js)

    Please check:

    "moduleNameMapper": {
      "/^.*[.](jpe?g|gif|png|less|css)$/": "./emptyTestModule.js"
    },
    "resolver": undefined

Edit: I fixed this by using rootDir: "^.*[.](jpe?g|gif|png|less|css)$": "<rootDir>/emptyTestModule.js"

@github-actions
Copy link

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 12, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests