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

Multiple Jest projects bleed module file extension resolution between environments #5597

Closed
paularmstrong opened this issue Feb 17, 2018 · 15 comments · Fixed by #5862
Closed

Comments

@paularmstrong
Copy link

Do you want to request a feature or report a bug?

Bug

What is the current behavior?

I've created a test-case repo that illustrates this behavior: paularmstrong/jest-project-bleed.


In some cases, we want to have code that is defined differently for a node.js environment than a browser/DOM environment. We do this to avoid needing to polyfill node.js's url module in the browser when we already have access to a powerful window.URL API in a browser (which is not available in node.js).

To do this, we set up our build environment to build server-side code with moduleFileExtensions to resolve *.node.js files before *.js files.

In Jest, we create two separate project configurations: config/jest/node.js and config/jest/web.js. These run the tests in the appropriate environment (node and jsdom, respectively).

If the current behavior is a bug, please provide the steps to reproduce and
either a repl.it demo through https://repl.it/languages/jest or a minimal
repository on GitHub that we can yarn install and yarn test.

I've created a test-case repo that illustrates this behavior: paularmstrong/jest-project-bleed.

What is the expected behavior?

I expect all tests to pass, given their environment and correct module file resolution.

Please provide your exact Jest configuration and mention your Jest, node,
yarn/npm version and operating system.

Please see the repo test case: paularmstrong/jest-project-bleed.

  • yarn 0.27.5
  • node 8.9.0
  "devDependencies": {
    "babel-core": "^6.26.0",
    "babel-jest": "^22.2.2",
    "babel-preset-env": "^1.6.1",
    "jest": "^22.3.0"
  },
@SimenB
Copy link
Member

SimenB commented Feb 17, 2018

FWIW node has whatwg url, const {URL} = require('url');.

This issue is still very much valid of course 🙂

@cpojer is this known?

@paularmstrong
Copy link
Author

paularmstrong commented Feb 17, 2018

FWIW node has whatwg url, const {URL} = require('url');.

Yep, separate issue that comes down to webpack polyfilling url.js in client-side code still, which we don't want. This was just a quick example that I already had on-hand.

@cpojer
Copy link
Member

cpojer commented Feb 17, 2018

Yeah that's a bug.

@paularmstrong
Copy link
Author

@cpojer @SimenB Either of you have any guidance on where to start looking for a way to fix this bug? Happy to give it a shot, but am lost at where to start.

@mkubilayk
Copy link
Contributor

I checked out the repository but couldn't reproduce this. Are still seeing the issue?

21:43:02 | mkubilayk@agloe | ~/Developer/jest-project-bleed (master) 
$ yarn --version
0.27.5
21:43:20 | mkubilayk@agloe | ~/Developer/jest-project-bleed (master) 
$ node --version
v8.9.0
21:43:38 | mkubilayk@agloe | ~/Developer/jest-project-bleed (master) 
$ yarn jest -- --no-cache
yarn jest v0.27.5
$ "/Users/mkubilayk/Developer/jest-project-bleed/node_modules/.bin/jest" "--no-cache"
 PASS   node  src/__tests__/bar.test.js
 PASS   node  src/__tests__/url.test.js
 PASS   node  src/__tests__/foo.test.js
 PASS   web  src/__tests__/foo.test.js
 PASS   web  src/__tests__/url.test.js
 PASS   web  src/__tests__/bar.test.js

Test Suites: 6 passed, 6 total
Tests:       24 passed, 24 total
Snapshots:   0 total
Time:        1.581s
Ran all test suites in 2 projects.
Done in 2.30s.

@paularmstrong
Copy link
Author

@mkubilayk It's dependent on which tests run first. If the node tests run first, it'll pass. If web runs first, the node tests will fail. In your case, notice that node ran first.

@SimenB
Copy link
Member

SimenB commented Feb 24, 2018

@paularmstrong I'm not really sure where the best place to start looking is, but I'd take a look at _modulePathCache in jest-resolve here: https://github.com/facebook/jest/blob/64cbf36eb1c34f8839e484ae0da355e5edcf4ec2/packages/jest-resolve/src/index.js

Might be that the resolver is reused across projects, while it should not

@paularmstrong
Copy link
Author

Might be that the resolver is reused across projects, while it should not

The resolver itself does not have any shared cache between instances, so that sounds like a reasonable suspicion.

However, It appears that a new hastemap and resolver are created within the jest-cli package for each project config [jest-cli/src/cli/index.js#L308](https://github.com/facebook/jest/blob/master/packages/jest-cli/src/cli/index.js#L308

@cbelsole
Copy link
Contributor

I was able to repro this bug and I noticed when I printed out the project configs that they had the same md5 hash name which is what jest uses to pick out the right resolver. I found that in the normalizer if the name is not set it will set a name.

After fiddling around with the normalizer I came up with this code:

const normalizeMissingOptions = (options: InitialOptions): InitialOptions => {
  if (!options.name) {
    options.name = crypto
      .createHash('md5')
      .update(options.rootDir)
      .digest('hex');
  }

  options.projects = (options.projects || []).map(project => {
    if (!project.name) {
      project.name =
        crypto
          .createHash('md5')
          .update(project.rootDir)
          .digest('hex') || '';
    }
    return project;
  });

  if (!options.setupFiles) {
    options.setupFiles = [];
  }

  return options;
};

Now if the names on the projects were not set they would have their own unique name. This fixed the error since by having a unique name the right resolver was chosen.

@paularmstrong
Copy link
Author

@cbelsole Thanks! Adding an explicit name to the project config at least fixes the issue in our repo and lets me remove a bunch of stuff to run them in sync. I can look into adding your fix in the next couple of weeks, unless you are already on it.

@cbelsole
Copy link
Contributor

@paularmstrong I put together a PR with tests but I could use some help on the types. I don't have any experience with flow.

@paularmstrong
Copy link
Author

@cbelsole I can help with that today. What's the easiest way to collaborate and get the typings on your branch?

@cbelsole
Copy link
Contributor

@paularmstrong I made you a collaborator on my fork. You should be able to push to the repo.

@paularmstrong
Copy link
Author

🎉I'm on it @cbelsole

@github-actions
Copy link

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 12, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants