Search code examples
javascripttypescriptunit-testingjestjsts-jest

jest moduleNameMapper fixes unexpected token 'export' now breaks relative module import


I'm using create-react-app, with ts-jest and I'm trying to use the microsoft-cognitiveservices-speech-sdk npm package. The error I get is:

Test suite failed to run

Jest encountered an unexpected token

/node_modules/microsoft-cognitiveservices-speech-sdk/node_modules/uuid/dist/esm-browser/index.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){export { default as v1 } from './v1.js';

SyntaxError: Unexpected token 'export'

      at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1449:14)
      at Object.<anonymous> (node_modules/microsoft-cognitiveservices-speech-sdk/distrib/lib/src/common/src/common/Guid.ts:4:1)
      at Object.<anonymous> (node_modules/microsoft-cognitiveservices-speech-sdk/distrib/lib/src/common/src/common/PlatformEvent.ts:4:1)
      at Object.<anonymous> (node_modules/microsoft-cognitiveservices-speech-sdk/distrib/lib/src/common/AudioSourceEvents.js:20:23)
      at Object.<anonymous> (node_modules/microsoft-cognitiveservices-speech-sdk/distrib/lib/src/common/Exports.js:15:14)
      at Object.<anonymous> (node_modules/microsoft-cognitiveservices-speech-sdk/distrib/lib/src/sdk/src/sdk/LogLevel.ts:4:1)
      at Object.<anonymous> (node_modules/microsoft-cognitiveservices-speech-sdk/distrib/lib/src/common.browser/src/common.browser/ConsoleLoggingListener.ts:6:1)
      at Object.<anonymous> (node_modules/microsoft-cognitiveservices-speech-sdk/distrib/lib/src/common.browser/Exports.js:15:14)
      at Object.<anonymous> (node_modules/microsoft-cognitiveservices-speech-sdk/distrib/lib/microsoft.cognitiveservices.speech.sdk.ts:3:1)
      at Object.<anonymous> (src/components/<component-name>.tsx:1:1)

I can solve this error, as supplied by this answer https://stackoverflow.com/a/73203803

    moduleNameMapper: {
        "uuid": require.resolve('uuid'),
    },

However it looks like @mswjs is erroring because it has a reference to a utils/uuid.ts and that is getting mapped by the root module mapper.

TypeError: uuid_1.uuidv4 is not a function
          at new IsomorphicRequest (<root>/node_modules/@mswjs/interceptors/src/IsomorphicRequest.ts:40:15)

Does this mean I can't use @mswjs? Is there a configuration I can update to allow for this to work? I'm not totally clear no steps forward, any guidance would be helpful.

I've tried a number of jest.config permutations

    moduleNameMapper: {
        // this file has to https://stackoverflow.com/a/73203803
        "uuid": require.resolve('uuid'),
    },
    transformIgnorePatterns: ["node_modules/(?!@mswjs)/"],

Here's my current .jest.config.cjs

module.exports = {
    extensionsToTreatAsEsm: [".ts", ".tsx"],
    transform: {
        ".(ts|tsx)": "ts-jest",
        // ".(js|jsx)": "babel-jest",
    },
    // transformIgnorePatterns: ["node_modules/(?!@mswjs)/"],
    moduleNameMapper: {
        // this file has to https://stackoverflow.com/a/73203803
        "uuid": require.resolve('uuid'),
    },
    setupFilesAfterEnv: ["<rootDir>/src/setupTests.js"],
    moduleFileExtensions: ["ts", "tsx", "js", "jsx"],
    collectCoverageFrom: [
        "**/*.ts",
        "**/*.tsx",
        "!**/*.d.ts",
    ],
};

Solution

  • Try this:

    module.exports = {
      // other config options...
      transformIgnorePatterns: [
        "/node_modules/(?!uuid).+\\.js$"
      ],
      moduleNameMapper: {
        "^uuid$": "uuid/dist/esm-browser/index.js"
      },
      transform: {
        "^.+\\.(js|jsx|ts|tsx)$": "ts-jest",
        "^.+\\.js$": "babel-jest"
      }
    };
    

    This configuration tells Jest to:

    1. Ignore transforming all JS files in the “node_modules” directory, except for the “uuid” package.
    2. Map the “uuid” package to its ESM code, so that Jest can recognize its “export” statements.
    3. Transform all JS files (except for “uuid”) using Babel, which will convert the ESM code into CJS code.