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/globals] Identifier 'jest' has already been declared #9920

Closed
stropho opened this issue Apr 29, 2020 · 13 comments
Closed

[@jest/globals] Identifier 'jest' has already been declared #9920

stropho opened this issue Apr 29, 2020 · 13 comments

Comments

@stropho
Copy link

stropho commented Apr 29, 2020

🐛 Bug Report

I, and probably many other people, love the idea of @jest/globals. Thanks again 👍
Obviously, I just tried :)
The FE part, ES modules transpiled with babel, seems to be just fine.
The BE part is probably not expecting to import/require jest variable from @jest/globals

To Reproduce

const {jest} = require('@jest/globals')

Run the test

Error: SyntaxError: Identifier 'jest' has already been declared

Expected behavior

The test will pass the same way as without @jest/globals

Link to repl or repo

see the test file in
https://repl.it/repls/LastingRepentantRuntimes

@SimenB
Copy link
Member

SimenB commented Apr 29, 2020

Ah, didn't think about this case... It probably works for the transpiled case as the identifier will be named differently. We inject jest as an argument into the module function (it's different for each file, not actually a global), and your identifier inside the function clashes.

You can do const {jest: requiredJest} = require('@jest/globals'); as a workaround.

The problem would go away if we introduced some sort of "no globals" mode, but ideally I'd like these to work together.

@jeysal @thymikee any good ideas here? I guess we could do some weird stuff with the babel plugin, but I don't think the babel plugin should be required

@jeysal
Copy link
Contributor

jeysal commented Apr 29, 2020

If I understand this correctly, the same would happen with the test file:

const jest = 42;

If so, this is a way more general bug? We should inject things into a higher scope than the program scope of the file. Maybe we need to wrap in another function?

@SimenB
Copy link
Member

SimenB commented Apr 29, 2020

If I understand this correctly, the same would happen with the test file

Yup. Same in plain node

// file.js
const require = 42;
$ node file.js
/Users/simen/repos/infra/file.js:1
const require = 42
      ^

SyntaxError: Identifier 'require' has already been declared

Maybe we need to wrap in another function?

We've stopped manually wrapping it in a function, which solves so many issues with source maps and code coverage (there's no offset) - we use vm.compileFunction instead. Or rather, we use it when available falling back to manual wrapper and vm.Script, and I'm planning to remove vm.Script in Jest 26. I'd really prefer some solution that didn't require an extra function wrapper

@jeysal
Copy link
Contributor

jeysal commented Apr 29, 2020

Oh. Hmm, then allowing to declare jest actually seems quite inconsistent, I would consider the jest global to be quite similar to require, taking into account their file-specific properties.
But I also understand that declaring it as jest would be very nice to have.
Although now exposing jest as a 'global' like expect, test, describe etc., which it is not, which is why we already had to write hacks to enable it, feels even less like a good idea as much as people have been requesting it...

@stropho
Copy link
Author

stropho commented Apr 30, 2020

The problem would go away if we introduced some sort of "no globals" mode

If this happens any time soon and it solves the issue, then the workaround is sufficient for now. On the other hand, the documentation mentions jest.fn() , jest.mock() etc., so using another name for the jest object could be confusing.

FYI, another workaround that could help somebody is to use a scoped variable, e.g.

const {
  describe, 
} = require('@jest/globals')

describe('suite', () => {
  const {jest} = require('@jest/globals')
})

@phiter
Copy link

phiter commented May 6, 2020

Hey guys, I don't know if this is necessarily related to this issue but I'm coming across an issue.
I'm getting this error:

Cannot find module '@jest/globals' from 'file.spec.js'

This only happens if I call jest.mock

image

@stropho
Copy link
Author

stropho commented May 7, 2020

Encountered something similar. Moving jest.mock somewhere to beforeAll solved it for me.

@SimenB
Copy link
Member

SimenB commented May 7, 2020

Oh, interesting! That's probably a bug in the new implementation in the babel plugin. Can you open up an issue with a reproduction?

@phiter
Copy link

phiter commented May 7, 2020

@SimenB I'll see if I can reproduce it in a new project with a setup similar to mine. It indeed started happening after I updated babel-plugin.

@SimenB
Copy link
Member

SimenB commented May 7, 2020

We rewrote the plugin in order to support import {jest} from '@jest/globals' in #9806, pretty sure some regression was introduced there.

@SimenB
Copy link
Member

SimenB commented Mar 14, 2021

Circling back to this issue, we now have a --inject-globals false flag which should solve the immediate issue

@stropho
Copy link
Author

stropho commented Mar 15, 2021

Great 🎉 , seems to work, thanks!!!

@stropho stropho closed this as completed Mar 15, 2021
@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 10, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants