Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

jest-haste-map: TypeError: dupMap.get is not a function #9021

Open
cameracker opened this issue Oct 8, 2019 · 40 comments
Open

jest-haste-map: TypeError: dupMap.get is not a function #9021

cameracker opened this issue Oct 8, 2019 · 40 comments

Comments

@cameracker
Copy link

cameracker commented Oct 8, 2019

🐛 Bug Report

Running a jest test results in a test build failure:

TypeError: dupMap.get is not a function
at ModuleMap._getModuleMetadata (node_modules/jest-haste-map/build/ModuleMap.js:231:14)

When console logging dupMap at the source location, dupMap is undefined. I don't see a control flow where this is possible because when dupMap is declared, it is set to EMPTY_MAP if it's value would be undefined.

The error is also bound to a material-ui style object, which doesn't make much sense.

To Reproduce

Steps to reproduce the behavior:

I'm afraid I don't have a reproduction. I'm using lerna and material-ui in jest. The library I'm experiencing the issue with is dependent on another library in my mono repo.

Expected behavior

The test runs without problems

Link to repl or repo (highly encouraged)

Unavailable, sorry

envinfo


  System:
    OS: Linux 5.0 Ubuntu 18.04.2 LTS (Bionic Beaver)
    CPU: (12) x64 Intel(R) Core(TM) i7-8700 CPU @ 3.20GHz
  Binaries:
    Node: 10.16.0 - /usr/local/bin/node
    Yarn: 1.17.3 - /usr/bin/yarn
    npm: 6.9.0 - /usr/local/bin/npm
  npmPackages:
    jest: ^24.9.0 => 24.9.0 

My jest config:


  "jest": {
    "collectCoverageFrom": [
      "packages/**/*.{js,jsx,mjs}",
      "!packages/**/common/icons/components/*",
      "!packages/**/*.stories.{js,jsx,ts,tsx}",
      "!packages/**/**/story/**/*.{js,jsx,ts,tsx}"
    ],
    "moduleDirectories": [
      "node_modules"
    ],
    "setupFilesAfterEnv": [
      "<rootDir>/config/jest/setup.js"
    ],
    "setupFiles": [
      "<rootDir>/config/polyfills.js"
    ],
    "testMatch": [
      "<rootDir>/packages/**/?(*.)(spec|test).{js,jsx,mjs}"
    ],
    "testEnvironment": "jsdom",
    "testURL": "http://localhost",
    "transform": {
      "^.+\\.(js|jsx|mjs)$": "<rootDir>/node_modules/babel-jest",
      "^.+\\.css$": "<rootDir>/config/jest/cssTransform.js",
      "^(?!.*\\.(js|jsx|mjs|css|json)$)": "<rootDir>/config/jest/fileTransform.js"
    },
    "transformIgnorePatterns": [
      "[/\\\\]node_modules[/\\\\].+\\.(js|jsx|mjs)$"
    ],
    "moduleFileExtensions": [
      "web.js",
      "js",
      "json",
      "web.jsx",
      "jsx",
      "node",
      "mjs",
      "ts",
      "tsx"
    ]
@cameracker
Copy link
Author

Hi! I managed to figure it out by reading over your lovely example project :)

I was missing these properties:

    "modulePathIgnorePatterns": [
      "packages/.*/build"
    ],
    "projects": ["<rootDir>/packages/*"],

Thanks!!

@nellyk
Copy link

nellyk commented Nov 20, 2019

@CameronAckermanSEL i'm getting this at the moment. Might you know why the solution above worked? and what might have caused this, this solution doesn't seem work for me. I'm on lerna v2

@0fprod
Copy link

0fprod commented Nov 20, 2019

@CameronAckermanSEL I get that error too but it happens when I import a module from a custom library

> jest --no-cache

jest-haste-map: Haste module naming collision: my-lib
  The following files share their name; please adjust your hasteImpl:
    * <rootDir>\dist\my-lib\package.json
    * <rootDir>\projects\my-lib\package.json

PASS src/app/services/test.service.spec.ts
PASS projects/my-lib/src/lib/components/button/button.component.spec.ts
FAIL src/app/app.component.spec.ts
  ● Test suite failed to run

    TypeError: dupMap.get is not a function

      3 | import { TestService } from './services/test.service';
      4 | import { of } from 'rxjs';
    > 5 | import { MyLibModule } from 'my-lib';
        | ^
      6 |
      7 | jest.mock("./services/test.service");
      8 |

      at ModuleMap._getModuleMetadata (node_modules/jest-haste-map/build/ModuleMap.js:231:14)
      at Object.<anonymous> (src/app/app.component.spec.ts:5:1)

Test Suites: 1 failed, 2 passed, 3 total
Tests:       3 passed, 3 total
Snapshots:   0 total
Time:        6.013s


This is the .spec.ts file

import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { AppComponent } from './app.component';
import { TestService } from './services/test.service';
import { of } from 'rxjs';
import { MyLibModule } from 'my-lib';

jest.mock("./services/test.service");

describe('AppComponent', () => {
  let component: AppComponent;
  let fixture: ComponentFixture<AppComponent>;
  let testService: TestService;
  
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [AppComponent],
      imports : [MyLibModule],
      providers: [TestService]
    })
      .compileComponents();
  }));

  beforeEach(() => {
    testService = TestBed.get(testService);

    jest.spyOn(testService, "getResource").mockReturnValue(
      of({
        username: 'Brent'
      })
    );
    
    fixture = TestBed.createComponent(AppComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

@isumeetk
Copy link

Facing the same issue, I have my own custom library as shared project on angular. I have all necessary things like moduleNameMapper but still the issue is there.

@nellyk
Copy link

nellyk commented Nov 27, 2019

think i might have found what caused this. If you make any updates to package-lock this happens 😕 , when i removed any changes on my parent package lock. This error got resolved

@SimenB
Copy link
Member

SimenB commented Nov 27, 2019

We should never have TypeErrors internally, no matter what your config is. Can anyone provide a full, minimal reproduction we can clone and run locally to see the error?

@SimenB SimenB reopened this Nov 27, 2019
@isumeetk
Copy link

  1. Create a library project along with normal angular application
    ng new my-workspace --createApplication="false"
    cd my-workspace
    ng generate application my-app
    ng generate library my-lib

  2. Output path for library project will be dist/my-lib and for application it should dist/my-app

  3. In main tsconfig.json "paths": { "@custom/my-lib": [ "dist/my-lib" ], "@custom/my-lib/*": [ "dist/my-lib/*" ] }

  4. In jest.config.js add configuration for path mapper as moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths || {}, { prefix: '<rootDir>/' })

  5. And in one of the spec/test file use the library as import { Something} from '@custom/my-lib'

This fails at the above import with the error as dupMap.get is not a function.
PS: Jasmine framework works fine for same test

@joshua-honig
Copy link

I have encountered this too in a mixed TypeScript and JavaScript project that uses Vue. As with the other posters, this happens when importing a class from another custom library that is included as a git submodule, referenced from package.json using file: syntax. The error occurs several layers deep in the import hierarchy, not from an import from the .spec file itself. So the import hierarchy is:

  • thing.spec.ts
  • --> import { MyComponent } from 'MyComponent.vue'
  • --> import { SomeModel } from '@my-org/package-name'
  • --> import { AnotherModel } from './local_file'
  • --> import { Utility } from '@my-org/another-package'

The error is raised at the fourth level down, when importing Utility from @my-org/another-package:

TypeError: dupMap.get is not a function

> 1 | import { Utility } from '@my-org/another-package'
    | ^

at ModuleMap._getModuleMetadata (node_modules/jest-haste-map/build/ModuleMap.js:231:14)
at Object.<anonymous> (--redacted local path--.js:1:1)

@SimenB
Copy link
Member

SimenB commented Dec 3, 2019

@isumeetk thanks, but could you do those steps in a repo and publish that? I tried to follow your steps but step 3 is unclear (paths is already in the file - should I replace or add to it?), step 4 is unclear (should I create this file? What is pathsToModuleNameMapper?) and step 5 is unclear since I don't know which file to make the change.

I could probably figure out these things if I spent some time on it, but it's a higher barrier than need be here. Either a repo I can clone, or a repl.it/codesandbox would be ideal. Ideally I should be able to clone, install, and run to see the error

PS: Jasmine framework works fine for same test

Not sure what this means - jasmine instead of jest, or using jest-jasmine (which is the default test runner within jest)?

@isumeetk
Copy link

isumeetk commented Dec 10, 2019

Well this is interesting, while creating a repo to reproduce something made it work, both in reproducing repo and the my main repo. Still for people who want to go through the working structure here is the repo https://github.com/isumeetk/jest-angular-sample

@hadanin
Copy link

hadanin commented Jan 26, 2020

I have the same issue when I import a module from a custom library, just like @franjpr.
Any solution?

@SimenB
Copy link
Member

SimenB commented Jan 26, 2020

For the umpteenth time, if you want it fixed somebody needs to put together a repository, or some other reproduction, where we can see the error.

https://www.snoyman.com/blog/2017/10/effective-ways-help-from-maintainers

@jonathanong-houzz
Copy link

jonathanong-houzz commented Apr 3, 2020

not sure if this will help, but i am seeing this issue on a lerna repo i'm setting up. it seems to be an issue with symlinks and copies (still figuring it out since i inherited the code). deleted some symlinks/copies before running tests made this issue go away.

main issue is that the dupMap object is not a Map instance. here's what it looks like for me:

[
  [
    "g",
    [
      [
        "packages/components/lib/utils/package.json",
        1
      ],
      [
        "packages/utils/package.json",
        1
      ]
    ]
  ]
]

i'm guessing something isn't creating a Map object in this._raw.duplicates.get(name) properly?

@WilliamChelman
Copy link

WilliamChelman commented Apr 7, 2020

Hi all,

Here is a minimal repository where this bug is reproduced: https://github.com/WilliamChelman/angular-jest-bug-repro

How-to:

  • npm ci
  • npm t
    • This fails with something like this

Cannot find module '@me/lib-a' from 'lib-b.component.ts'
Require stack:
projects/me/lib-b/src/lib/lib-b.component.ts
projects/me/lib-b/src/lib/lib-b.component.spec.ts

  • This is expected since in our tsconfig.json we have the paths that point to a built version of the package in dist/
  • npm run build-all
  • npm t
    • This fails with

The name @me/lib-a was looked up in the Haste module map. It cannot be resolved, because there exists several different files, or packages, that provide a module for that
particular name and platform. The platform is generic (no extension). You must delete or blacklist files until there remains only one of these:
* /home/william/Dev/other/angular-jest-bug/dist/me/lib-a/package.json (package)
* /home/william/Dev/other/angular-jest-bug/projects/me/lib-a/package.json (package)

Some of the leads that were explored to fix this, but to no avail and usually end up with the "dupMap.get is not a function" error:

  • moduleDirectories: ['node_modules', 'dist']
  • modulePathIgnorePatterns: ['/projects']
  • modyfing paths in tsconfig to point to src/public-api of @me/lib-a instead of built version in dist

Solution that did work but felt dirty: change projects/me/lib-a/ng-package.json to

{
  "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
  "dest": "../../../node_modules/@me/lib-a", // here
  "lib": {
    "entryFile": "src/public-api.ts"
  }
}

So that the build is put in the node_modules directly, so then it's considered as any other external lib when tests are launched.

To whoever read this, have a great day 😄

EDIT: doesn't really reproduce the dupMap.get error unfortunately, but leaving this at least for the ng-package.json hack that might help someone.

@SimenB
Copy link
Member

SimenB commented Apr 7, 2020

@WilliamChelman I'm unable to reproduce. I get the haste errors you note, but

  1. moduleDirectories: ['node_modules', 'dist'] makes no difference
  2. modulePathIgnorePatterns: ['/projects'] makes it find no tests
  3. I don't know what modyfing paths in tsconfig entails so I didn't touch that part.

I haven't done any angular since v1, so there might be some detail I'm missing.

Could you add a commit to that repo so that I can run npm cit and get the dupMap.get is not a function error?

@WilliamChelman
Copy link

For some reason I'm currently unable to reproduce the dupMap.get error, even if it was that same error that brought me here... But now that I think of it (after sleeping a bit), it seems like the issue I have might be more for ts-jest in fact, since it looks like it is the tsconfig file that doesn't bode well with module resolution in this context. I'll see to create an issue on their side instead, thank you for your time @SimenB .

@SimenB
Copy link
Member

SimenB commented Apr 7, 2020

I still think this is a bug in Jest somehow, if nothing else we should provide a better error. So if you figure out why you get the error please report back so we can improve things 👍

@nickhudkins
Copy link

@SimenB just ran into this same problem, and it appears that I needed to ignore my output folders as @CameronAckermanSEL mentioned.
modulePathIgnorePatterns: ["packages/*/dist"] for me, as I have a mono-repo where all package sources are in packages/**/src/* and packages/**/dist is where they build to.

Hopefully someone else will find this helpful :)

@yaacovCR
Copy link

I was able to get rid of this error by calling jest --clearCache, probably because I had fixed one of the other causes listed above, but the cache retained the error?

@minato-namikaze
Copy link

minato-namikaze commented Apr 29, 2020

I'm working in an Angular CLI project with an application and a library.
It get it working by:

  1. Update the ng-package.json file like @WilliamChelman mentioned
    ... "dest": "../../node_modules/@my-domain/my-library", ...
  2. In the tsconfig.spec.json of the application, I added a configuration entry for the path resolution such as:
    "paths": { "@my-domain/my-library": [ "../node_modules/@my-domain/my-library" ] }

@justerest
Copy link

I just resolved same problem with angular project by this config:

// jest.config.js
module.exports = {
	preset: 'jest-preset-angular',
	setupFilesAfterEnv: ['<rootDir>/src/setupJest.ts'],
	testRegex: ...,
	roots: ['<rootDir>/src'],
	modulePaths: ['<rootDir>/dist'],
};

More at Medium

@vilvai
Copy link

vilvai commented Jul 29, 2020

I ran into this same issue today. For me the issue was related to using yalc to develop multiple dependent repos.

The problem disappeared after I removed all yalc installations (yalc remove --all in every repo and then verified that yalc installations show was empty)

@dirkluijk
Copy link

dirkluijk commented Sep 1, 2020

I have the same issue in my Angular project. For some reason, when I remove package.json in (projects/my-project, not the one in my root), the error is gone.

I got this error when I added a path mapping to my project from my tsconfig.spec.json:

{
    "compilerOptions": {
        "paths": {
            "my-project": ["projects/my-project/src/public-api.ts"]
        }
    }
}

And, my jest.config.js:

module.exports = {
    moduleNameMapper: {
        "my-project": "<rootDir>/projects/my-project/src/public-api.ts"
    },
};

However, I need my package.json there because it is the one that gets packaged by Angular.

My workaround was to rename the path mapping of my-project to my-project-api, which fixed the issue.

@SimenB
Copy link
Member

SimenB commented Sep 2, 2020

Can you put together a reproduction? I'd like to fix this so people don't need any workarounds (or at least give a clearer/actionable error)

@GasimGasimzada
Copy link

GasimGasimzada commented Sep 9, 2020

I have found the issue. I will describe it here and post a reproducible demo in a bit. Here is what happens:

/my-app -> Installs @myproject/my-library and mocks some of the functions of the library in tests
/my-library -> After building CJS and ESM modules, it copies package.json to build directory (e.g dist/).

Case 1: If I run npm test from root, everything will pass without issues.
Case 2: Build library using npm run build in <monorepo-root>/my-library. Then, run tests from root. This will give dupMap.get error.

Jest version: ^24.9.0

@huruji
Copy link

huruji commented Dec 20, 2020

have the same issue

@bingtimren
Copy link

I encountered this issue today and packed it as a reproduction. I'm building my own typescript project template. I uses ts-jest. What I'm doing is trying to test the packed package. So my run script uses 'npm pack' to pack the package, extract it in a directory, 'npm link' from there, then install it back locally. Then I run a test that import my package using an absolute path as if from 'npm install'.

To reproduce the issue:

git clone https://github.com/bingtimren/ts-proj-template.git
cd ts-proj-template/
git checkout jest-issue-9021 
npm install
npm run build
npm run test

image

@jorroll
Copy link

jorroll commented Apr 23, 2021

After running into this issue myself, I encountered this helpful PR from the "isomorphic git" repo where they fixed this problem. While the PR doesn't contain much of an explanation, looking at it's very simple change was enough for me to identify the fix in my own repo. In my case, I have a monorepo using yarn workspaces and lerna where package B imported package A. I had failed to configure the jest modulePathIgnorePatterns to include the build output of package A. When I added the build output of package A to modulePathIgnorePatterns, this error goes away. If I remove the build output of package A from modulePathIgnorePatterns, this error re-appears.

The error only appears for package B's tests. My assumption is that, somehow, when a package B test is attempting to locally import package A (again, this is a monorepo using lerna), jest is getting confused by the presence of the package A build in the package A source folder. I don't have a reproduction to share at this time, unfortunately.

The diff from the "isomorphic git" fix which helped me solve this issue looks like:

module.exports = {
+  modulePathIgnorePatterns: ['<rootDir>/website'],
  testRegex: '/__tests__/(server-only\\.)?test-[^\\/]+\\.js',
  moduleNameMapper: {
    '^isomorphic-git$': '<rootDir>/src'

cc @SimenB

@SimenB
Copy link
Member

SimenB commented Apr 23, 2021

Interesting stuff. Thanks for the reproduction @bingtimren, sorry I missed it when you posted it!

If I run the tests with -i (i.e. forcing not to use workers) we get the correct error

    The name `@bingsjs/ts-proj-template` was looked up in the Haste module map. It cannot be resolved, because there exists several different files, or packages, that provide a module for that particular name and platform. The platform is generic (no extension). You must delete or exclude files until there remains only one of these:

      * `/Users/simen/repos/ts-proj-template/build/pack/package/package.json` (package)
      * `/Users/simen/repos/ts-proj-template/package.json` (package)

So there's something wrong with (de)serialization of the Maps between workers. Will dig some more into this, but for people encountering this - running with -i (short for --run-in-band) should help you debug

@SimenB
Copy link
Member

SimenB commented Apr 23, 2021

Reverting the jest-runner parts of #8237 fixes the issue

@ericraio
Copy link

I currently have a lerna project, this issue went away for me after upgrading to jest version 27.4.5.

@tfciw
Copy link

tfciw commented Mar 15, 2022

Error:

TypeError: dupMap.get is not a function

       5 |
       6 | import ua from '@searchfe/user-agent';
    >  7 | import compare from 'versions-compare';

Fix:

i output a log in this file ('node_modules/jest-haste-map/build/ModuleMap.js:209:14')

name === 'versions-compare' && (console.log(name, ...dupMap));
this._assertNoDuplicates(
  name,
  _constants.default.GENERIC_PLATFORM,
  `supportsNativePlatform,`
  dupMap.get(_constants.default.GENERIC_PLATFORM)
);

found array

versions-compare [
  'g',
  [
    [ 'dist/modules/versions-compare/package.json', 1 ],
    [ 'amd_modules/versions-compare/package.json', 1 ]
  ]
]

because it found 2 pacakges, The answer above give me clue #9021 (comment) @cameracker

Fixed 🚀🚀🚀🚀

modulePathIgnorePatterns: [
    "dist"
],

@jk195417
Copy link

Meet this problem on an Angular app with some Angular libs, problem solved after adding moduleNameMapper to root jest.config.js.

see: https://kulshekhar.github.io/ts-jest/docs/getting-started/paths-mapping/

Let's says we have a Angular lib placed at projects/my-lib, your root tsconfig paths may look like this

{
  ...others
  "compilerOptions": {
    "paths": {
      "@my-scope/my-lib": [
        "dist/my-lib/my-scope-my-lib",
        "dist/my-lib"
      ]
    }
  }
}

Your root jest.config.js will need to set

  • roots to ['<rootDir>/src']
  • moduleNameMapper to map @my-scope/my-lib to projects/my-lib/src/public-api
module.exports = {
  roots: ['<rootDir>/src'],
  moduleNameMapper: {
    '@my-scope/my-lib': '<rootDir>/projects/my-lib/src/public-api',
  },
};

And for my-lib jest.config.js set

  • roots to ['<rootDir>/projects/my-lib']
module.exports = {
  roots: ['<rootDir>/projects/my-lib'],
};

@cgomezdev

This comment was marked as spam.

@MisterLuffy
Copy link

MisterLuffy commented Jun 1, 2023

I have the same issue in my Angular project. For some reason, when I remove package.json in (projects/my-project, not the one in my root), the error is gone.

I got this error when I added a path mapping to my project from my tsconfig.spec.json:

{
    "compilerOptions": {
        "paths": {
            "my-project": ["projects/my-project/src/public-api.ts"]
        }
    }
}

And, my jest.config.js:

module.exports = {
    moduleNameMapper: {
        "my-project": "<rootDir>/projects/my-project/src/public-api.ts"
    },
};

However, I need my package.json there because it is the one that gets packaged by Angular.

My workaround was to rename the path mapping of my-project to my-project-api, which fixed the issue.

I met the same problem and the error disappeared after I changed the packageJson.name of the root directory. But I need to keep this root packageJson.name. Any update about this issue?

I'm using jest@29.5.0, and here is my tsconfg and jest config:

"compilerOptions": {
  "baseUrl": ".",
  "paths": {
    "my-root-package": "."
  }
}
modules.exports = {
  rootDir: __dirname,
  roots: [__dirname],
  moduleNameMapper: {
    '^my-root-package$': '<rootDir>'
  }
};

@kriscoleman
Copy link

Error:

TypeError: dupMap.get is not a function

       5 |
       6 | import ua from '@searchfe/user-agent';
    >  7 | import compare from 'versions-compare';

Fix:

i output a log in this file ('node_modules/jest-haste-map/build/ModuleMap.js:209:14')

name === 'versions-compare' && (console.log(name, ...dupMap));
this._assertNoDuplicates(
  name,
  _constants.default.GENERIC_PLATFORM,
  `supportsNativePlatform,`
  dupMap.get(_constants.default.GENERIC_PLATFORM)
);

found array

versions-compare [
  'g',
  [
    [ 'dist/modules/versions-compare/package.json', 1 ],
    [ 'amd_modules/versions-compare/package.json', 1 ]
  ]
]

because it found 2 pacakges, The answer above give me clue #9021 (comment) @cameracker

Fixed 🚀🚀🚀🚀

modulePathIgnorePatterns: [
    "dist"
],

on a gatsbyjs project, this worked for me

@vladyn
Copy link

vladyn commented Feb 29, 2024

Hoiw about adding (for these who are using yalc):
"modulePathIgnorePatterns": ["dist", ".yalc"], ?
This solve the issue for me. If I use yalc remove --all like @vilvai mentioned, I'll loose the dependencies and my project won't run successfully anymore.

@SimenB
Copy link
Member

SimenB commented Feb 29, 2024

I was gonna look into fixing the error in this case now, but the reproduction from #9021 (comment) is unfortunately deleted. Does anybody else have a small reproduction I can test with?

@aelgasser
Copy link

I ran into this same issue today. For me the issue was related to using yalc to develop multiple dependent repos.

The problem disappeared after I removed all yalc installations (yalc remove --all in every repo and then verified that yalc installations show was empty)

@vilvai, almost 4 years later this comment just saved my day!

@aelgasser
Copy link

Hoiw about adding (for these who are using yalc): "modulePathIgnorePatterns": ["dist", ".yalc"], ? This solve the issue for me. If I use yalc remove --all like @vilvai mentioned, I'll loose the dependencies and my project won't run successfully anymore.

@vladyn, this indeed solves it in a cleaner way.

However, in my case, I thought I got rid of the yalc imported dependencies and reverted to the main package as I was done working on it and was about to commit the package depending on it. It seems that I need to go back to yalc's documentation and see how to properly clean up (ie. yalc remove --all) and probably see if a commit hook exists to prevent putting a mess in the repo too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests