-
-
Notifications
You must be signed in to change notification settings - Fork 6.5k
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
Invalid variable access _jsxFileName #10690
Comments
PR welcome 👍 Error is in |
That said, I'm not 100% certain what the solution is. We could add it to the whitelist, but that feels like it's addressing the symptom rather than the cause. @nicolo-ribaudo what do you think? |
@SimenB For sure ... Will work on this one 👍 |
I was thinking doing that (adding into the whitelist), do you have other solution? |
Currently the whitelist is globals and known symbols that jest controls, just adding stuff that "random" babel plugins inject seems like a slippery slope. I'm hoping we can solve it more generically via some babel magic. Might not be possible though! @rickhanlonii on the react team is gonna take a look, so let's wait and see what he says 🙂 If it proves difficult we should just add it to the whitelist to unblock, tho 👍 |
Would (yet) another configuration option make sense? Today is React who needs this variable, tomorrow may be framework x that needs another one. |
Right, which is why I wanna solve it more generically than adding to the whitelist, and hopefully without the user having to specify any config |
Makes sense. Agreed
Sure. Thanks! |
Alternatively the plugin could also allow variables prefixed by an underscore ( Meanwhile, anybody with the same problem can use this patch with diff --git a/node_modules/babel-plugin-jest-hoist/build/index.js b/node_modules/babel-plugin-jest-hoist/build/index.js
index 6128021..46f2824 100644
--- a/node_modules/babel-plugin-jest-hoist/build/index.js
+++ b/node_modules/babel-plugin-jest-hoist/build/index.js
@@ -141,7 +141,8 @@ FUNCTIONS.mock = args => {
if (!found) {
const isAllowedIdentifier =
(scope.hasGlobal(name) && ALLOWED_IDENTIFIERS.has(name)) ||
- /^mock/i.test(name) || // Allow istanbul's coverage variable to pass.
+ /^mock/i.test(name) ||
+ /^_/i.test(name) || // Allow istanbul's coverage variable to pass.
/^(?:__)?cov/.test(name);
if (!isAllowedIdentifier) {
|
If this plugin ran before the React plugin then I would expect this to work because the injected React functions would be in scope. Is there a repro repo I can test on? |
@rickhanlonii I will reproduce that in a public repo and get back to you |
@rickhanlonii you can reproduce using CRA $ npx create-react-app my-app
$ cd my-app
$ git apply mock.patch
$ npm test
ReferenceError: /Users/simen/repos/my-app/src/App.test.js: The module factory of `jest.mock()` is not allowed to reference any out-of-scope variables.
Invalid variable access: _jsxFileName
diff --git i/src/App.test.js w/src/App.test.js
index 1f03afe..ba15b2b 100644
--- i/src/App.test.js
+++ w/src/App.test.js
@@ -1,6 +1,8 @@
import { render, screen } from '@testing-library/react';
import App from './App';
+jest.mock('./MyComponent', () => () => <div id="my-component" />, { virtual: true })
+
test('renders learn react link', () => {
render(<App />);
const linkElement = screen.getByText(/learn react/i); |
@SimenB is this specific to CRA? |
Testing locally - it only happens with the dev mode transform, not the "normal" (prod?) transform. I.e. passing See #10723 for a failing test |
So a workaround is to somehow disable "dev" mode for the transform when running Jest. However, I'd say it's still a bug even if CRA were to work around it. |
One other thing to note is that it's not enough to add it to the whitelist for us, since the Would need to add it to the whole condition (similar to #10690 (comment)) |
Maybe if a mock relies on a constant pure variable in the outer scope, that variable can be hoisted to the top of the file? |
That sounds reasonable @nicolo-ribaudo. We'd do that in our hoist plugin, right? Seems reasonable. Any idea on how to achieve that? |
In the logic which throws about variables in the outer scope, you can do something like this: const binding = scope.bindings[name];
if (binding.constant && scope.isPure(binding.path.node.init, true)) {
// hoist binding.path.node
} |
Which
Something like this (I've ignored whitespace since I've changed to an early return rather than keeping track via diff --git i/packages/babel-plugin-jest-hoist/src/index.ts w/packages/babel-plugin-jest-hoist/src/index.ts
index 8fbab87dc0..15b412c594 100644
--- i/packages/babel-plugin-jest-hoist/src/index.ts
+++ w/packages/babel-plugin-jest-hoist/src/index.ts
@@ -117,19 +117,28 @@ FUNCTIONS.mock = args => {
moduleFactory.traverse(IDVisitor, {ids});
for (const id of ids) {
const {name} = id.node;
- let found = false;
let scope = id.scope;
while (scope !== parentScope) {
if (scope.bindings[name]) {
- found = true;
- break;
+ return true;
}
scope = scope.parent;
}
- if (!found) {
+ const binding = parentScope.bindings[name];
+
+ if (
+ binding?.constant &&
+ parentScope.isPure(binding.path.node.init, true)
+ ) {
+ // @ts-expect-error: private, magical property
+ binding.path.node._blockHoist = Infinity;
+
+ return true;
+ }
+
const isAllowedIdentifier =
(scope.hasGlobal(name) && ALLOWED_IDENTIFIERS.has(name)) ||
/^mock/i.test(name) ||
@@ -153,7 +162,6 @@ FUNCTIONS.mock = args => {
);
}
}
- }
return true;
}
The test I put together in #10723 passes with this change, fwiw. As an aside, |
Fix released in https://github.com/facebook/jest/releases/tag/v26.6.2. Many thanks to @nicolo-ribaudo for helping out with this 🙏 |
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. |
🐛 Bug Report
After upgrading to new JSX transform, started to receive an error in my mocks that's returning a React Component/Element, saying about the
_jsxFileName
variable being outside of scope and could not be accessed.To Reproduce
Just mock a React Component/Element and start using the new JSX Transform
The text was updated successfully, but these errors were encountered: