Heather Roberts
Heather Roberts

Reputation: 2158

Jest transformIgnorePatterns not working

I have spent a long time looking at other questions about this and looking at other projects on Github but none of the answers seem to work for me.

I am loading a third party library in my project, and when running Jest tests I get the error

export default portalCommunication;
^^^^^^

SyntaxError: Unexpected token export

> 1 | import portalCommunication from 'mathletics-portal-communication-service';

I have tried updating my Jest config in many ways to get it to transpile this library but I always get the same error.

This is my current jest.config.js file:

module.exports = {
    moduleNameMapper: {
        '\\.(css|scss)$': 'identity-obj-proxy',
        '\\.svg$': '<rootDir>/test/mocks/svg-mock.js'
    },
    setupFiles: ['./test/test-setup.js'],
    transformIgnorePatterns: [
        '<rootDir>/node_modules/(?!mathletics-portal-communication-service)'
    ]
};

I have also tried adding the transform property to run babel-jest against this mathletics-portal-communication-service directory.

Please help!

Upvotes: 48

Views: 50645

Answers (7)

Fernando Gabrieli
Fernando Gabrieli

Reputation: 1010

This is what I found after reading your answers from here and the link provided by @NJCodeMonkey

The error I was getting was this one:

Test suite failed to run
 
Jest encountered an unexpected token

Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.

Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration.

By default "node_modules" folder is ignored by transformers.

Here's what you can do:
 • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it.
 • If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript
 • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
 • If you need a custom transformation specify a "transform" option in your config.
 • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/configuration
For information about custom transformations, see:
https://jestjs.io/docs/code-transformation

Details:

/Users/fgabriel/nx-5/node_modules/flat/index.js:12
export function flatten (target, opts) {
^^^^^^

SyntaxError: Unexpected token 'export'

  2 | import { RouterModule } from '@angular/router';
  3 | import { NxWelcomeComponent } from './nx-welcome.component';
> 4 | import { flatten } from 'flat'
    | ^
  5 |
  6 | @Component({
  7 |   imports: [NxWelcomeComponent, RouterModule],

  at Runtime.createScriptFromCode (../../node_modules/jest-runtime/build/index.js:1505:14)
  at Object.<anonymous> (src/app/app.component.ts:4:1)
  at Object.<anonymous> (src/app/app.component.spec.ts:2:1)

Now, first of all I would like to say that this started happening when I migrated to Nx latest version, to the moment when I'm writing this comment: 20.4.0

My previous setup was working and it stop working when upgrading Nx (this is just for context)

So I cloned the jest repo and looked into how they handle the transformIgnorePatterns:

return new RegExp(config.transformIgnorePatterns.join('|'));

For anyone wanting to check if the regex added in transformIgnorePatterns is correct, you can use the above code

This helped me to understand that the Regex was not the issue, so something had to be failing when the the transformer (alias transpiler) was trying to transpile this flat/index.js to be used in my tests

So, I took the babel path this time and the following configuration worked:

Files:

nx-workspace/apps/nx-5/babel.config.js
nx-workspace/apps/nx-5/jest.config.ts

Here is my babel.config.js:

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

and my jest.config.ts from a recently created Nx workspace for reproduction:

const config = {
  displayName: 'nx-5',
  preset: '../../jest.preset.js',
  setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
  coverageDirectory: '../../coverage/apps/nx-5',
  transform: {
    '^.+\\.js$': 'babel-jest', <---------
    '^.+\\.(ts|html|mjs)$': [
      'jest-preset-angular',   <---------
      {
        tsconfig: '<rootDir>/tsconfig.spec.json',
        stringifyContentPathRegex: '\\.(html|svg)$',
      },
    ],
    // '^.+\\.(ts|mjs|js|html)$': [
  },
  transformIgnorePatterns: [
    'node_modules/(?!(.*\\.mjs$)|(flat/index\\.js$))', <----
  ],
  snapshotSerializers: [
    'jest-preset-angular/build/serializers/no-ng-attributes',
    'jest-preset-angular/build/serializers/ng-snapshot',
    'jest-preset-angular/build/serializers/html-comment',
  ],
};

export default config;

It was very helpful to me to create a new Nx workspace to work on something smaller where I could reproduce and fix it

Upvotes: 0

stanhope
stanhope

Reputation: 356

It's worth noting if you're using Next.js that you might be affected by this issue. next/jest.js makes it hard to transpile modules in node_modules, but you can modify the baked config in jest.config.mjs like this:

import nextJest from 'next/jest.js'
const createJestConfig = nextJest({
    dir: './',
})

// add any custom config to be passed to Jest
/** @type {import('jest').Config} */
const config = {
  ...
  // setting `transformIgnorePatterns` in here does not work
}

// work around https://github.com/vercel/next.js/issues/35634
async function hackJestConfig() {
    // createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
    const nextJestConfig = await createJestConfig(config)();
    // /node_modules/ is the first pattern, so overwrite it with the correct version
    nextJestConfig.transformIgnorePatterns[0] = '/node_modules/(?!(micromark-extension-gfm))/';
    return nextJestConfig;
}

export default hackJestConfig

Upvotes: 2

NJCodeMonkey
NJCodeMonkey

Reputation: 921

The transformIgnorePatterns didn't work for me until I changed my .babelrc to babel.config.js, like this:

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

as seen on this comment: https://github.com/facebook/jest/issues/6229#issuecomment-403539460

Upvotes: 65

Rohan Bagchi
Rohan Bagchi

Reputation: 711

Another team at my org added some common module. This was not transpiled and so the issue.

I followed this: https://babeljs.io/docs/en/configuration#whats-your-use-case

  1. Converted my .babelrc to babel.config.json
  2. in jest config added this: transformIgnorePatterns: ['/node_modules/(?!(@companyName)/).*/'],

This solved my problem.

Upvotes: 13

Raz Luvaton
Raz Luvaton

Reputation: 3790

Adding trailing slash fix this for me:

{
    // ...
    transformIgnorePatterns: [
        '<rootDir>/node_modules/(?!mathletics-portal-communication-service/)'
    ]
};

Upvotes: 6

Yorkshireman
Yorkshireman

Reputation: 2343

It might be your use of rootDir. Try:

    "transformIgnorePatterns": [
      "node_modules/(?!(mathletics-portal-communication-service))"
    ]

Upvotes: -4

Heather Roberts
Heather Roberts

Reputation: 2158

As a workaround for now I have changed my config to use the moduleNameMapper option to load a mock class for that library instead. I would have preferred to use transformIgnorePatterns instead so would still appreciate any ideas.

New config:

module.exports = {
    moduleNameMapper: {
        '\\.(css|scss)$': 'identity-obj-proxy',
        '\\.svg$': '<rootDir>/test/mocks/svg-mock.js',
        'mathletics-portal-communication-service': '<rootDir>/test/mocks/mathletics-portal-communication-service-mock.js'
    },
    setupFiles: ['./test/test-setup.js']
};

Upvotes: 6

Related Questions