esm
esm copied to clipboard
jest transform support
I'm collecting some esm + jest + react + enzyme "real world" issues as I'm going here: https://github.com/kenotron/esm-jest/
- On https://github.com/standard-things/esm/blob/33ee0ac7e8c7aec7db176143f833560f7a09f069/esm.js#L178, _runResult can be undefined it seems, so add a conditional there will help
- A package like
domutils
that is used byjsdom
&htmlparser2
will do silly things like this: https://github.com/fb55/domutils/blob/master/index.js where they loop through all the object keys and start calling ".bind" because they didn't expect something else to inject properties into the object (could be a jest + domutils goober? not necessarily esm??)
Anyway, it's almost there with jest as far as I can tell! If I just hack-patch this stuff conditional around the problematic code, jest works with esm!
What we shipped in v3.1.0 is the beginnings of support.
You can use esm
as a Jest transform
with --no-cache
to run simple ESM test files. I need to abstract our Jest wiring into a hook to allow it to tap more cleanly into the exposed transform
method of process()
and getCacheKey()
.
Thanks so much for working on this tirelessly. I'll try out that --no-cache and report some findings here. I think what I want to do is to create several examples of jest test suites to test out just how "simple" we need to get with our tests.
@jdalton Does it work now?))
Hi @TrySound!
Not yet. The v3.1.1 had to be released sooner to address more critical bugs that shook out after the v3.1.0 release. I'm still going to work on wrapping up Jest support soon though :)
I noticed 3.1.4 is out, but didn't see any commits relating to this in the git history. I guess you'll update this issue when it's ready @jdalton. Thanks for your amazing work on this!
Thanks for all your great work @jdalton.
Should anyone else be curious, I can confirm we're still not quite there yet. My testing with [email protected]
and [email protected]
commonly yields the following errors:
TypeError: _.a(...) is not a constructor
TypeError: Cannot read property 'next' of undefined
Same result as @kellengreen here, any news?
Maybe just wait till finished?
Thanks for the interest y'all! I'll be sure to update this issue when support 🚢
Not sure if the following is a known issue in terms of the work remaining required for jest compatibility (so feel free to ignore this if it is known @jdalton):
The globals defined in jest.config.js
are not available in the tests when using esm
as a transform
in jest ([email protected]
and [email protected]
)
Does the v12 release make this work any easier? What would be the recommended way to use Jest with ESM now?
Any updates?
@dandv
Does the v12 release make this work any easier?
It does not unfortunately.
@dandv @chungchi300
What would be the recommended way to use Jest with ESM now?
Continuing to use Babel is the way at the moment until I can get to making esm
work.
If that's any help here's how I made it work in the build tool I maintain for work.
I created a small transformer which has only the job of converting import/export, and tries to do so only if needed : https://github.com/swissquote/crafty/blob/master/packages/crafty-preset-jest/src/esm-transformer.js
Which is then added as a jest transform (https://github.com/swissquote/crafty/blob/master/packages/crafty-preset-jest/src/index.js#L50) So I guess you could use that in your own projects by installing:
yarn add @swissquote/crafty-preset-jest
And adding this to your Jest configuration:
{
"transformIgnorePatterns": [],
"transform": {
"[/\\\\]node_modules[/\\\\].+\\.m?js$": "@swissquote/crafty-preset-jest/src/esm-transformer"
}
}
@onigoetz Awesome, thanks for posting this! I had a small issue with some of the checks that were in your file (I think it had to do with the version of Babel I was using?), so I stripped it all back to just parse everything. Works well for my use case, but probably not so well for others.
I've credited you here: https://github.com/ActuallyACat/jest-esm-transformer
@ActuallyACat cool :) You didn't specify the dependencies in the package.json, maybe add at least peerDependencies so that yarn PNP is happy
The reason I added the checks is that Babel has a cost for processing that is quite high if you have to run it on all the files you require from node_modules (for example trying to change all imports in React ... which has none)
@jdalton is the following statement still valid?
You can use esm as a Jest transform with --no-cache to run simple ESM test files. I need to abstract our Jest wiring into a hook to allow it to tap more cleanly into the exposed transform method of process() and getCacheKey().
I'm trying to run a simple spec with:
npx -n '-r esm' jest func.spec.js
and transforms: {}
in my package.json jest
section but the:
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import func from './func.js';
^^^^
SyntaxError: Unexpected identifier
is still afflicting me xD
I tried to use esm with jest as a loader. I had the following problems, maybe it will help for the next steps.
You can find a minimal reproducible case on that repo.
- Due to the following error:
TypeError: Jest: a transform must export a `process` function.
I had to downgrade from [email protected] to [email protected].
- Then I encountered the following error:
TypeError: Cannot read property 'next' of undefined
at Object.n.(anonymous function) (node_modules/esm/esm.js:1:1796)
Which might be due to the fact that might be due to the fact that the src/common.js
file is being imported:
- directly in one of the tests
- indirectly by the components I'm testing in the 2 other tests
Those are basic tests (add
, sub
, concat
), only for example. See topheman/jest-esm-experiments
It is fixable if I use babel-jest
as a loader (which I did on the original project where I spotted the bug)
A salute to the brave people in this thread. It's amazing/unfortunate that this giant thread (with associated repositories and whatnot) exists, and yet using the amazing esm
module with Mocha is trivial.
I just don't understand why the Jest people won't simply add a --require
arg ... but since they won't, personally I'm going back to Mocha.
@jdalton
Continuing to use Babel is the way at the moment until I can get to making
esm
work.
Is this still the recommendation? jest is the last barrier between converting our entire code base to esm...
If I understand this correctly, this "issue" is not anymore existing with the newest Node version which enables ESM modules?
The latest version of node now implemented the new module loader. Does it work on Jest?
From my scans of GitHub threads, it seems like jest has its own require implementation so even on the new experimental module system in node it wasn’t working, but I don’t know for sure and that’s why I was hoping @jdalton might update this thread :)
Node's ES modules don't solve it at all (they require package.json with "type": "module", require explicit extensions in imports, and they don't allow interop between CJS and ES6 modules).
I'm cheering for this to be added @jdalton Maybe you could publish some simplified (or slow) implementation in the meantime?
@sheerun instead of the "type": "modules"
entry in package.json
you can also use the .mjs
extension :scream: :scream_cat: ... you know, instead of the .js
extension which we've all used, and which has worked just great for over two decades :wink:
Seriously, why does the Node org hate us all so much? Thank god for @jdalton.
Yeah Node guys are definitely making a mess.
We won't have ESM working for years because of the incompatibility and exports
/type
requirement.
But I trust those guys so it was probably inevitable.
The only choice nowadays is ESM, thanks @jdalton.
What's the suggested solution to work with jest and esm in its current state?
@bencondon the solution is using jasmine and wait for better times 😂
I've been adding this to the top of my jest test files and it works great:
const esmImport = require('esm')(module);
const moduleBeingTested = esmImport('../src/module');
E.G.
// ./src/add.js
export function add (a,b) {
return a + b;
}
// ./test/add.test.js
const esmImport = require('esm')(module);
const add = esmImport('../src/add).add;
describe('add', () => {
it('works as expected', () => {
expect(add(1,1).toBe(2);
});
)};
See also the Native support for ES Modules.