Jest v24 crashes with "getVersion" is not defined.
See source code.
Jest does not crash.
This line requires cli
.
But cli
itself requires jest
here. Clearly, getVersion
is not exported at this point.
npx envinfo --preset jest
Paste the results here:
System:
OS: Windows 10
CPU: (12) x64 Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
Binaries:
Yarn: 1.10.1 - C:\Program Files (x86)\Yarn\bin\yarn.CMD
npm: 6.4.1 - C:\Program Files\nodejs\npm.CMD
I can't repro the error. Can you share what you executed when it crashed?
Not sure what's happening, but one thing that's bitten me before is mismatching jest
installations.
Make sure to not have both jest
and jest-cli
installed at the same time (you just need jest
), and that you're not using CRA (CRA ships with its own version of Jest, so you shouldn't update it yourself 馃檪)
Our setup is somewhat complex, I basically ran jest --config our-config.js
, and our-config.js
loads typescript using ts-node
, I can try to further simplify that to understand where the issue comes from.
But regardless of how I ran it and what my setup is, why should it work at all? What breaks the cyclic reference between jest.js
and cli/index.js
?
getVersion
is a function (which is not invoked until later), and node handles cyclic require
s
I 100% agree it's not ideal, of course 馃檪
@SimenB stepping through the transpiled code, it seems like nodejs is first executing jest/jest.js
until there:
'use strict';
var _package = require('../package.json');
var _SearchSource = _interopRequireDefault(require('./SearchSource'));
var _TestScheduler = _interopRequireDefault(require('./TestScheduler'));
var _TestWatcher = _interopRequireDefault(require('./TestWatcher'));
var _cli = require('./cli'); // === here ===
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : {default: obj};
}
/**
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
// === this is not executed yet ===
module.exports = {
SearchSource: _SearchSource.default,
TestScheduler: _TestScheduler.default,
TestWatcher: _TestWatcher.default,
getVersion: () => _package.version,
run: _cli.run,
runCLI: _cli.runCLI
};
Where it then descends into jest/cli/index.js
:
function _asyncToGenerator(fn) {
return function() {
var self = this,
args = arguments;
return new Promise(function(resolve, reject) {
var gen = fn.apply(self, args);
function _next(value) {
asyncGeneratorStep(gen, resolve, reject, _next, _throw, 'next', value);
}
function _throw(err) {
asyncGeneratorStep(gen, resolve, reject, _next, _throw, 'throw', err);
}
_next(undefined);
});
};
}
const _require = require('../jest'),
getVersion = _require.getVersion;
// === at this point, `_require` equals `{}`, so getVersion is undefined. ===
function run(_x, _x2) {
return _run2.apply(this, arguments);
}
Clearly, here, it then crashes:
const buildArgv = (maybeArgv, project) => {
const version =
getVersion() + // === getVersion is still undefined ===
(__dirname.includes(`packages${_path().default.sep}jest-cli`)
? '-dev'
: '');
// [...]
Not sure what's going on - I'm unable to reproduce.
$ mkdir 24
$ cd 24
$ yarn init -y
# ...
$ yarn add jest
# ...
$ yarn jest --version
yarn run v1.13.0
$ /Users/simen/24/node_modules/.bin/jest --version
24.0.0
So a reproduction would be awesome!
It might very well be that ts-node
is somewhat buggy and doesn't work in the same way node does. Why do you need ts-node
?
We need ts-node
because our configuration is written in typescript. I try to make it reproducible.
But clearly there is an issue in the transpiled source, isn't it?
However, installing ts-node
still works
$ yarn add ts-node typescript
$ npx ts-node node_modules/.bin/jest --version
24.0.0
Further debugging showed that the issue is the order in which the modules are loaded. If jest/cli/index is loaded first, everything works. If jest/jest.js is loaded first, it crashes due to the described reasons. I am currently investigating why jest/jest.js is loaded before jest/cli/index in our setup.
Anyways, code should not break if it is loaded in a different order than the default case, especially if the order is up to the caller of the API.
For reference: Whatever the circumstances this appears under may be, reason why it started showing in v24 is this PR.
I'm running into this same error but only when running jest programmatically (require('jest').run(argv)
). When I yarn jest
it works fine.
I'm running into this same error but only when running jest programmatically (
require('jest').run(argv)
). When Iyarn jest
it works fine.
Thank you, we also run it programmatically. That seems to be it.
Ah, ok. We need #7696 馃槄
I'll put together a PR
@SimenB thank you for your help :)
@SimenB Is there a workaround for 24 or is this likely something we won't see until 25 or 24.1?
Sounds good. Thanks!
Does anyone know why it breaks when running it like that though? Don't think I've seen something like this happening because of cyclic dependencies before
It breaks when build/jest
is loaded first, not build/cli/index
@jeysal see my in-detail explanation above what happens and why it breaks. require
loads modules if they have not been cached before (i.e. loaded before) and creates an empty cache object for it, otherwise they use the cached module.
So cyclic require calls are handled without indefinitely recursing, but module could be empty as in this case.
Oh I see now...
Looks like this happened because #7582 landed after the short-lived ESM migration (#7548) and it had to be converted to CommonJS in #7602, which it wasn't really compatible with
https://github.com/facebook/jest/pull/7602/files#diff-281a28872bb5a78b747f7cd3d114a0ed
@eliw00d @hediet workaround before new release:
// Preload `cli` to avoid cyclical dependency
require('jest-cli/build/cli');
require('jest').run(...);
@SimenB it doesn't even work with a workaround 馃槩
> node scripts/test.js
TypeError: getVersion is not a function
at buildArgv (~\node_modules\jest\node_modules\jest-cli\build\cli\index.js:399:5)
at Object.<anonymous> (~\node_modules\jest\node_modules\jest-cli\build\cli\index.js:243:20)
at Generator.next (<anonymous>)
at asyncGeneratorStep (~\node_modules\jest\node_modules\jest-cli\build\cli\index.js:202:24)
at _next (~\node_modules\jest\node_modules\jest-cli\build\cli\index.js:222:9)
at ~\node_modules\jest\node_modules\jest-cli\build\cli\index.js:227:7
at new Promise (<anonymous>)
at Object.<anonymous> (~\node_modules\jest\node_modules\jest-cli\build\cli\index.js:219:12)
at Object._run2 (~\node_modules\jest\node_modules\jest-cli\build\cli\index.js:265:16)
at Object.run (~\node_modules\jest\node_modules\jest-cli\build\cli\index.js:236:16)
Weird. The workaround worked fine for me.
@bricss what does scripts/test.js
look like?
@SimenB technically, as I know, it was created by create-react-app version ~2.x.x
, and never touched by anyone.
P.S.: Node.js - v11.8.0 is used.
How are you applying the workaround then, if you haven't updated the file?
@SimenB I meant it wasn't touched by anyone before me. I placed imports exact in same order as was suggested.
Hey @SimenB, is this released as part of 24.0.0
https://github.com/facebook/jest/pull/7707 ?
Also, I can confirm that https://github.com/facebook/jest/issues/7704#issuecomment-457699687 worked for me
The fix #7707 is not yet released.
I kinda don't wanna rush anyone, but maybe it's time to let it go with version 24.0.1
馃浉
Battlefield news: 馃摪
I have managed to start _Jest_ by adding those lines into the scripts/test.js
:
// jest v24.0 workaround
require('jest/node_modules/jest-cli/build/cli');
require('jest').run(argv);
After, when I'm start _Jest_ to run all over the tests, it shows this:
No tests found, exiting with code 1
Run with `--passWithNoTests` to exit with code 0
In C:\<projectPath>
49 files checked.
testMatch: <projectPath>/src/**\?(*.)(spec|test).{js,jsx,ts,tsx} - 0 matches
testPathIgnorePatterns: \\node_modules\\ - 49 matches
testRegex: - 49 matches
Pattern: - 0 matches
Unable to locate any of the test files. 馃攳
I had the same experience as @bricss. require('jest-cli/build/cli');
did not work for me, but require('jest/node_modules/jest-cli/build/cli');
did. Former CRA app, latest version, ejected quite recently.
To break the dependency cycle, we can delete the module cache and require it again
in scripts/test.js
:
delete require.cache[require.resolve('jest-cli/build/cli/index.js')];
const cli = require('jest-cli/build/cli/index.js');
24.1.0 is released
Most helpful comment
@eliw00d @hediet workaround before new release: