Search code examples
javascriptunit-testingreactjswebpackjestjs

How to pass externals from webpack to jest?


I've got this webpack config as part of my grunt building process:

module.exports = {
options: {
    output: {
        path: path.resolve('../ui/static/js'),
        filename: '[name].js',
        chunkFilename: '[id].[name].js',
        libraryTarget: 'amd',
        library: '[name]'
    },

    externals: [
        'jquery',
        'lodash',
        'backbone',
        'backbone.layoutmanager',
        'moment',
        'spin',
        'lib/select2.min',
        'dispatcher'
    ],
    resolve: {
        root: path.resolve('../ui'),
        alias: {
            'jst': 'static/jst'
        }
    }

We are moving to react now, and I need to import some files in my test files, where this dependencies included, but jest can not find them:

Cannot find module 'lib/select2.min' from 'helpers.js'
Cannot find module 'jst/templates_jst' from 'base-view.js

What is the right way to resolve this issue?


Solution

  • Here's what works today with [email protected] and [email protected]. Assuming this is your externals webpack config:

    externals: {
      react: {
        root: 'React',
        commonjs2: 'react',
        commonjs: 'react',
        amd: 'react',
      },
    }
    

    You'll need to map each external library to be properly resolved in your jest config like so:

    moduleNameMapper: {
      "^./react": path.resolve(__dirname, 'node_modules/react'),
    }
    

    While debugging your issue, be sure to check what your built component file looks like. You want to be sure that you see something like:

    !function(e,t){if("object"==typeof exports&&"object"==typeof module)
    module.exports=t(require("react"));
    else if("function"==typeof define&&define.amd)define(["react"],t);
    else{var n="object"==typeof exports?t(require("react")):t(e.React);
    

    Important bit being react for commonjs and amd, and React for the browser.