Sorry, I'll add more details later. Just getting this down now so I don't forget what I've learned so far before I wrap up for the weekend.
I have a custom transform that uses babel-jest to create a transformer based on a certain babel config that does not exist in the typical place (this is for a toolkit where the config resides inside a package, not in the project).
Steps to reproduce the behavior:
I'll create a reproduction repo next week.
In jest-runtime/build/ScriptTransformer.js in _getTransformer I'm getting:
TypeError: Jest: a transform must export a `process` function
Adding some console logs around shows me that it goes through that function twice with the same file (my custom transform). Here's an outline of where the code gets to:
if (transformPath) {
const transformer = this._transformCache.get(transformPath);
if (transformer != null) {
return transformer;
} // $FlowFixMe
transform = require(transformPath); // 1锔忊儯 gets to this line the first time
// following the code path here actually creates a module in the require.cache
// but in the process of actually loading the module, this function is
// called and run again!
// which means that the second time when we try to require `transformPath`
// a second time it comes back with a module that has a module.exports of `{}`
if (typeof transform.createTransformer === 'function') {
transform = transform.createTransformer();
}
if (typeof transform.process !== 'function') {
// 2锔忊儯 gets to this line the second time
throw new TypeError(
`Jest: a transform must export a \`process\` function`
);
}
this._transformCache.set(transformPath, transform);
}
This is pretty unusual I think. It's not entirely clear to me why the _getTransform function is getting called twice, but my assumption is that Jest is attempting to transform the transform file. Efforts to configure jest to ignore the transform file failed so I'm missing something else.
I'll try to add something next week.
npx envinfo --preset jestPaste the results here:
System:
OS: macOS 10.14.3
CPU: (8) x64 Intel(R) Core(TM) i7-4980HQ CPU @ 2.80GHz
Binaries:
Node: 8.15.0 - ~/code/paypal/paypal-scripts/node_modules/.bin/node
Yarn: 1.12.3 - /usr/local/bin/yarn
npm: 6.5.0 - ~/n/bin/npm
npmPackages:
jest: 24.0.0 => 24.0.0
Thanks! Looking forward to upgrading!
Do you use globalSetup/globalTeardown? If so, this might come from #7562. In that case, it should work to say transformIgnorePatterns: ['/node_modules/', '/my-custom-transform/']
Yes, we are using globalSetup but from my testing that file wasn't the one causing the trouble. I'll try to make a reproduction today (unless that PR will be released soon in which case I'd prefer to just wait and see if it magically fixes my problems 馃槄).
Ok, yep, I was able to reproduce this: https://github.com/kentcdodds/jest-transform-self-transform-bug
So the key here is that you have both globalSetup and transform. If you comment either of those out of the config then things work fine.
So my guess is that #7562 solves this. Any ideas as to when that'll be released? I've not learned how to locally link a bunch of lerna packages so I'm not sure of the best way to test that current master solves the problem. But it does seem related.
That PR _has_ been released, that's what's causing your issue. 馃檪 You need to include your setup or teardown in transformIgnorePattern.
This should be documented somewhere, not sure where's the best fit, though
Ooooh! I see 馃槄 Hmmm... Interesting. So it's just a limitation or something? I feel like this is something that jest should be able to detect and prevent? Maybe I'm misunderstanding what's going on though.
When you mentioned transformIgnorePattern before, I thought you were saying I should include my custom transform in that pattern, but indeed including the global setup in the pattern fixes the issue! Thanks @SimenB!
I'd be willing to contribute the docs, though it's still unclear to me why this is happening and why it's not a bug that should be fixed instead 馃
Not sure if it's functionally a bug, but we should definitely provide a better error.
The real fix is to preload all transformers, and then install the require hook. It would still possibly break if there are lazy requires inside the transform function or something, but that's way less likely to happen
Doing this should fix it, as it will make sure to load and cache the transformer before installing require hooks:
diff --git i/packages/jest-cli/src/runGlobalHook.js w/packages/jest-cli/src/runGlobalHook.js
index cd5a4ff06..4c6b3ed0d 100644
--- i/packages/jest-cli/src/runGlobalHook.js
+++ w/packages/jest-cli/src/runGlobalHook.js
@@ -49,6 +49,10 @@ export default ({
const transformer = new Runtime.ScriptTransformer(projectConfig);
+ // Load the transformer to avoid a cycle where we need to load a
+ // transformer in order to transform it in the require hooks
+ transformer._getTransformer(modulePath);
+
const revertHook = addHook(
(code, filename) =>
transformer.transformSource(filename, code, false).code || code,
transformer._getTransformer will load the transformer matching the filename, and stick it in a cache (it's the function that throws the error in the OP).
Of course, that calls a private API, so we should make a non-private one. But that should fix the issue.
@kentcdodds, can you provide your final version of jest config please, because I've followed all instructions above and I'm still getting this error. 馃槙
This branch has the fix: https://github.com/kentcdodds/jest-transform-self-transform-bug/tree/context-issue
Though there was a new bug in watch mode that this revealed as well (https://github.com/facebook/jest/issues/7740) which has been fixed but not yet released.
Most helpful comment
Doing this should fix it, as it will make sure to load and cache the transformer before installing
requirehooks:transformer._getTransformerwill load the transformer matching the filename, and stick it in a cache (it's the function that throws the error in the OP).Of course, that calls a private API, so we should make a non-private one. But that should fix the issue.
https://github.com/facebook/jest/blob/d7ca8b23acf2fdd1d070496efb2b2709644a6f4f/packages/jest-runtime/src/ScriptTransformer.js#L144