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

require.main undefined with createRequire() #10479

Closed
sguillia opened this issue Sep 4, 2020 · 20 comments · Fixed by #10610
Closed

require.main undefined with createRequire() #10479

sguillia opened this issue Sep 4, 2020 · 20 comments · Fixed by #10610

Comments

@sguillia
Copy link

sguillia commented Sep 4, 2020

🐛 Bug Report

The require.main of modules that are required from within a test file is undefined, when:

  • those modules were required with a require created with createRequire
  • createRequire was given another module than the current one (observe how parent2.js works as expected)
  • the test file is run with Jest, not Node

Tested with Jest 26.4.2, Node v12.4.0

Why it's an issue

  • I want to use require.main.filename to get the name of the requiring file, as it would work in a node context.

Link to repl or repo (highly encouraged)

https://github.com/sguillia/jest-createRequire-repro

Expected behavior

All files are in the demo repo

child.js

console.log(require.main && require.main.filename)

parent2.js

const Module = require('module')

require = Module.createRequire(__filename)

// Node: Prints path of parent2.js
// Jest: Prints path of parent2.js
require('./child')

parent3.js

const Module = require('module')
const path = require('path')

require = Module.createRequire(path.resolve('./subfolder/sub.js')) // sub.js is empty file

// Node: Prints path of parent3.js
// Jest: Prints null
require('./child')
$ node parent2.js
<path>

$ jest parent2.js
<path>
$ node parent3.js
<path>

$ jest parent3.js
<path>

Actual behavior

$ node parent2.js
<path>

$ jest parent2.js
<path>
$ node parent3.js
<path>

$ jest parent3.js
null

envinfo

  System:
    OS: Linux 4.15 Ubuntu 16.04.7 LTS (Xenial Xerus)
    CPU: (12) x64 Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
  Binaries:
    Node: 12.4.0 - ~/.nvm/versions/node/v12.4.0/bin/node
    Yarn: 1.22.4 - ~/.nvm/versions/node/v12.4.0/bin/yarn
    npm: 6.14.8 - ~/.nvm/versions/node/v12.4.0/bin/npm
@jeysal
Copy link
Contributor

jeysal commented Sep 7, 2020

Happy to take a PR fixing this! Might be just a matter of adding a parent in here?

@mohamedsgap
Copy link
Contributor

hey @jeysal, Can I try to fill a PR for this ?

@jeysal
Copy link
Contributor

jeysal commented Sep 9, 2020

@mohamedsgap sure!

@flozender
Copy link
Contributor

@jeysal I'd love to give it a shot! May I go ahead?

@jeysal
Copy link
Contributor

jeysal commented Oct 6, 2020

Yep!

@flozender
Copy link
Contributor

I'm trying to add a parent key to the object you suggested here however I get this message saying parent is deprecated:
@deprecated — since 14.6.0 Please use require.main and module.children instead. Should I continue?

@jeysal
Copy link
Contributor

jeysal commented Oct 7, 2020

@flozender Is that a TypeScript warning? If so, that should be fine.

@flozender
Copy link
Contributor

flozender commented Oct 7, 2020

@jeysal Yes, it is a TypeScript error. My approach is to create a parent module, assign the keys manually, and attach it to the object since the only parameter available to me is modulePath inside of the createRequire function. Is this a viable approach? Thanks for your support.

@jeysal
Copy link
Contributor

jeysal commented Oct 7, 2020

Hmm, looking at it again, it doesn't seem so simple anymore. createRequire has absolutely no context at the moment, so I'm not sure where to derive either a parent or a main from ... I wonder how Node does this

@flozender
Copy link
Contributor

@jeysal I will try to find out, but if you come across something please let me know. :)

@jeysal
Copy link
Contributor

jeysal commented Oct 7, 2020

It seems they are 'cheating' with an effectively global variable process.mainModule

@flozender
Copy link
Contributor

How do you suggest I go about this? Should I try to emulate what they're doing?

@jeysal
Copy link
Contributor

jeysal commented Oct 7, 2020

So for us that would mean dropping the current main in logic jest-runtime that traverses parents, and instead somehow get the module of the test file currently being executed. I'm not yet sure how to figure that out ...

@jeysal
Copy link
Contributor

jeysal commented Oct 7, 2020

The currently executing test file is in the environment options, but the environment doesn't expose it.
It's in the cacheFS as the only initial entry, but that's "conincidence".
We could throw it on process in jest-runner like Node does.
We could pass it into the runtime in jest-runner.

None of those seem like great options. @SimenB ideas?

@SimenB
Copy link
Member

SimenB commented Oct 7, 2020

I'm down with passing it in in jest-runner when instantiating the runtime. Getting rid of the current recursion for parent would be nice as well.

require.main is the same regardless of being "normal" require or as the result of createRequire?

We should probably populate process.mainModule as well, fwiw

@flozender
Copy link
Contributor

I'd like to help with this, what would be a good starting point?

@jeysal
Copy link
Contributor

jeysal commented Oct 7, 2020

Other than the jest-runtime index.ts you've already looked at, the place where jest-runner instantiates a new Runtime will be affected :) you can start from those places and should be able to see what changes need to be made 🙃

@SimenB
Copy link
Member

SimenB commented Oct 8, 2020

You wanna pass the path fo the test file (https://github.com/facebook/jest/blob/c808901f5ddfcbf8be924c850bd757d3ae720876/packages/jest-runner/src/runTest.ts#L79) into the runtime here: https://github.com/facebook/jest/blob/c808901f5ddfcbf8be924c850bd757d3ae720876/packages/jest-runner/src/runTest.ts#L154-L162

then store it on the instance of the runtime, and use that as main

@sguillia
Copy link
Author

Thanks!

@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 11, 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