How to use jest with webpack?

前端 未结 12 2555
抹茶落季
抹茶落季 2020-12-08 06:00

I use webpack to develop a React component. Here is a simple version of it:

\'use strict\';

require(\'./MyComponent.less\');

var React = require(\'react\')         


        
相关标签:
12条回答
  • 2020-12-08 06:39

    From Jest docs:

    // in terminal, add new dependency: identity-obj-proxy
    npm install --save-dev identity-obj-proxy
    
    // package.json (for CSS Modules)
    {
      "jest": {
        "moduleNameMapper": {
          "\\.(css|less)$": "identity-obj-proxy"
        }
      }
    }
    

    The snippet above will route all .less files to the new dependency identity-obj-proxy, which will return a string with the classname when invoked, e.g. 'styleName' for styles.styleName.

    0 讨论(0)
  • 2020-12-08 06:40

    It has been 5 years since this question asked, yet its still very confusing for me, I can't believe that its so hard to make jest and webpack works, until I tried this:

    Add babel-jest and babel preset:

    yarn add --dev babel-jest @babel/preset-env
    

    Add babel config:

    // babel.config.js
    module.exports = {
      presets: ["@babel/preset-env"]
    };
    

    This may or may not work for you, since the question title only refers to jest and webpack, people may stumble upon this article just like me that's clueless how to make jest works with webpack, and I hope at least my answer helped them if this doesn't help you.

    0 讨论(0)
  • 2020-12-08 06:45

    We had a similar problem with CSS files. As you mentioned before jest-webpack solves this problem fine. You won't have to mock or use any module mappers either. For us we replaced our npm test command from jest to jest-webpack and it just worked.

    0 讨论(0)
  • 2020-12-08 06:48

    The cleanest solution I found for ignoring a required module is to use the moduleNameMapper config (works on the latest version 0.9.2)

    The documentation is hard to follow. I hope the following will help.

    Add moduleNameMapper key to your packages.json config. The key for an item should be a regex of the required string. Example with '.less' files:

    "moduleNameMapper": { "^.*[.](less|LESS)$": "EmptyModule" },
    

    Add a EmptyModule.js to your root folder:

    /**
     * @providesModule EmptyModule
     */
    module.exports = '';
    

    The comment is important since the moduleNameMapper use EmptyModule as alias to this module (read more about providesModule).

    Now each require reference that matches the regex will be replaced with an empty string.

    If you use the moduleFileExtensions configuration with a 'js' file, then make sure you also add the EmptyModule to your 'unmockedModulePathPatterns'.

    Here is the jest configuration I ended up with:

    "jest": {
      "scriptPreprocessor": "<rootDir>/node_modules/babel-jest",
      "moduleFileExtensions": ["js", "json","jsx" ],
      "moduleNameMapper": {
        "^.*[.](jpg|JPG|gif|GIF|png|PNG|less|LESS|css|CSS)$": "EmptyModule"
      },
      "preprocessorIgnorePatterns": [ "/node_modules/" ],
      "unmockedModulePathPatterns": [
        "<rootDir>/node_modules/react",
        "<rootDir>/node_modules/react-dom",
        "<rootDir>/node_modules/react-addons-test-utils",
        "<rootDir>/EmptyModule.js"
      ]
    }
    
    0 讨论(0)
  • 2020-12-08 06:50

    I ended up with the following hack:

    // package.json
    
    "jest": {
      "scriptPreprocessor": "<rootDir>/jest-script-preprocessor",
      ...
    }
    
    
    // jest-script-preprocessor.js
    var babelJest = require("babel-jest");
    
    module.exports = {
      process: function(src, filename) {
        return babelJest.process(src, filename)
          .replace(/^require.*\.less.*;$/gm, '');
      }
    };
    

    But, I'm still wondering what is the right solution to this problem.

    0 讨论(0)
  • 2020-12-08 06:52

    If you're using babel, you can strip unwanted imports during the babel transform using something like https://github.com/Shyp/babel-plugin-import-noop and configuring your .babelrc test env to use the plugin, like so:

    {
      "env": {
        "development": {
          ...
        },
        "test": {
          "presets": [ ... ],
          "plugins": [
            ["import-noop", {
              "extensions": ["scss", "css"]
            }]
          ]
        }
      }
    }
    
    0 讨论(0)
提交回复
热议问题