Jest: Can moduleNameMapper [object<string, string>] support moduleNameMapper [object<string, function>]?

Created on 2 Aug 2018  路  12Comments  路  Source: facebook/jest

馃殌 Feature Proposal

Can moduleNameMapper [object] support moduleNameMapper [object]

Motivation

Because our project is multi-country, we need to import different component according to environment variable.

Example

It can be configured like this:

'^@src(.*)$': function (path){ },

Pitch

Why does this feature belong in the Jest core platform?

Common feature proposals that do not typically make it to core:

  • New matchers (see jest-extended)
  • Changes to the default reporter (use custom reporters instead)
  • Changes to node/jsdom test environments (use custom environments instead)

Most helpful comment

Or actually, you should be good with https://jestjs.io/docs/en/configuration#modulefileextensions-array-string

All 12 comments

Is this really necessary? What's your example that you cannot do with string regex?

Suppose we have a React component as below, it has 4 version for different country:

  index.en.js
  index.ch.js
  index.th.js
  index.default.js

In other component, it will import like this:

import Button from './Button/'

When we build our project, we will set a environment 'COUNTRY=en' and we will use webpack NormalModuleReplacementPlugin to help us to subsititute the './Button' to './Button/index.en.js'. But in jest, it cannot handle it.

Of course you can. Jest supports JS configs, so you can pass env variable to it and use it in your mapping fn

But we need to decide if the component has the specific version, if not we will import index.default.js:

  index.default.js

The component above just has one version, so when we set "COUNTRY=en", we need to decide if ./Button1/index.en.js exist. Actually not, so we will subsititue the import path with ./Button1/index.default.js

Hello @thymikee !

Since only few of our files have muti-country versions, we want to decide which version to use according to the FileSystem.

For example, there are 4 probabilities for paths of import payment from 'api/payment':

  1. api/payment.js
  2. api/payment.[env.country].js
  3. api/payment/index.js
  4. api/payment/index.[env.country].js

We wish to use fs.existsSync to decide which file to load.
So we can write our code without hardcode any global variable representing current country, like __APP_COUNTRY__ or anything else.

Looks like you need a custom resolver, not a module mapper

Or actually, you should be good with https://jestjs.io/docs/en/configuration#modulefileextensions-array-string

Thanks, we will try to make a custom resolver suit for us :)

@thymikee I'd like to hijack this issue to ask if there is a way for me to do something like

{
    "moduleNameMapper": {
        "\\$directory$": ["<rootDir>/directory", "<rootDir>/../directory]
    }
}

Which would try to look for a file first in <rootDir>/directory and, if not found, in <rooDir>/../directory. (And if not found, throw an error like by default).

My project uses module-alias which, according to this issue (https://github.com/ilearnio/module-alias/issues/46) can't work with Jest.

@Telokis no there isn't. Feel free to send a feature request, where we can discuss why to support such use case

@thymikee Is this possible to automatically map paths like 'components/atoms/Icon' to 'components/atoms/Icon/Icon'?
Is there any option to catch some variable in this mapper?

@lukaszkalemba yup, you have a few examples listed here: https://jestjs.io/docs/en/configuration#modulenamemapper-objectstring-string--arraystring

Was this page helpful?
0 / 5 - 0 ratings

Related issues

withinboredom picture withinboredom  路  3Comments

hramos picture hramos  路  3Comments

StephanBijzitter picture StephanBijzitter  路  3Comments

ianp picture ianp  路  3Comments

stephenlautier picture stephenlautier  路  3Comments