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

Support package exports in jest-resolve #9771

Closed
SimenB opened this issue Apr 5, 2020 · 86 comments · Fixed by #11961
Closed

Support package exports in jest-resolve #9771

SimenB opened this issue Apr 5, 2020 · 86 comments · Fixed by #11961

Comments

@SimenB
Copy link
Member

SimenB commented Apr 5, 2020

https://nodejs.org/docs/latest-v12.x/api/packages.html#packages_exports

Hopefully this can be offloaded to resolve. Tracked in browserify/resolve#222

@SimenB
Copy link
Member Author

SimenB commented Apr 8, 2020

I chatted with @ljharb about this, and a future version of resolve will support this. So we don't have to implement anything here. Will just hook it up when resolve is released with support for it 🎉

@cyberwombat
Copy link

cyberwombat commented Jun 5, 2020

@SimenB - in the meantime do you think its possible to mock these modules somehow? like uuid, luxon etc My attempts have not worked but i am not super versed in jest mocks. Would be ideal to have some kind of stub to use in the meantime rather than changing core code all over. To be clearer - not mock but reexport in a format suitable for Jest.

@SimenB
Copy link
Member Author

SimenB commented Aug 20, 2020

As a small update here, Jest 26.4.0 includes #10393 which allows you to specify resolve's packageFilter option, which should allow people to put together custom resolvers and pluck exports out of the package.json. While it's not the native, seamless integration we wanna use, it might possibly unblock people.

EDIT: I also just stumbled over a WIP PR to resolve, so 🤞 we can use that soon: browserify/resolve#224

@akauppi
Copy link

akauppi commented Aug 20, 2020

@SimenB Great! I'll look into those.

One question: in Browserify #222 you mentioned:

I'm currently working on support for ESM natively in Jest, ... (Apr 2020)

Since I'm building code exclusively with native ESM, interested in what's the status with that resolver.

@SimenB
Copy link
Member Author

SimenB commented Aug 20, 2020

Status of the resolver is in that issue. Status of ESM in general is #9430

@akauppi
Copy link

akauppi commented Aug 20, 2020

Made a work-around that someone might find useful: https://github.com/akauppi/firebase-jest-testing/blob/master/sample/hack-jest/self-resolver.cjs

It allows the use of normal import statements, and fetches the mapping from the same library's package.json. "Good enough for now" for me - allows testing that export is likely usable.

@overlookmotel
Copy link
Contributor

Progress in resolve appears to be a bit slow. Would you consider using Webpack's enhanced-resolve in meantime?

Seems like you can create a Node-compatible ESM resolver with:

const enhancedResolve = require('enhanced-resolve');
const resolve = enhancedResolve.create( {
  conditionNames: ['import', 'node', 'default'],
  extensions: []
} );

@SimenB
Copy link
Member Author

SimenB commented Feb 10, 2021

You can plug in your own resolver in Jest, replacing the use of resolve: https://jestjs.io/docs/en/configuration#resolver-string

We're (highly) unlikely to migrate away from resolve, but if you are able to put together a resolver that supports exports (via enhanced-resolve or something else) that'd be a great workaround while we wait for resolve to add support 👍

@akauppi
Copy link

akauppi commented Feb 11, 2021

@overlookmotel I updated the link in my entry above (it was broken). It may help, if you wish to do a custom resolver, though it's purpose is different from a generic ES modules importer.

@piranna
Copy link
Contributor

piranna commented Mar 14, 2021

@akauppi seems like your resolver doesn't support conditional exports. Or are they supported implicitly by options.defaultResolver?

@akauppi
Copy link

akauppi commented Mar 15, 2021

@piranna It likely doesn't. I just needed ES module handling and the resolver is made with the one project in mind - not as a general fix.

@piranna
Copy link
Contributor

piranna commented Mar 15, 2021

@piranna It likely doesn't. I just needed ES module handling and the resolver is made with the one project in mind - not as a general fix.

Fair enought. Not sure if give it a try and improve it, or wait until we have properly support... :-/

What I'm trying to achieve, is to test that a different file is provided for Node.js and for browser. I could do it with with module field in package.json, but I want to do it TheCorrectWay(tm), that now it's using ESM.

@nicolo-ribaudo
Copy link
Contributor

Until this is implemented in resolve, I'm trying to use a custom resolver. Is there a way to know if the file to resolve has been included with require() or import?

@SimenB
Copy link
Member Author

SimenB commented Apr 1, 2021

Currently no. I was gonna wait until resolve added it to figure out what the API should be in Jest. Thoughts on what the API should look like? I guess we should say node or browser based on the env, and then a flag for ESM vs CJS? Only doing the latter first I guess. Should jest be a condition?

@SimenB
Copy link
Member Author

SimenB commented Feb 12, 2022

As mentioned, please open new issues with minimal reproductions.

But yes, the way eslint has defined exports should work

5minpause added a commit to 5minpause/gatsby that referenced this issue Feb 14, 2022
The workaround for gatsby-page-modules seems unneccessary after the issue jestjs/jest#9771 was closed.
marcelgerber added a commit to owid/owid-grapher that referenced this issue Feb 15, 2022
marcelgerber added a commit to owid/owid-grapher that referenced this issue Feb 16, 2022
marcelgerber added a commit to owid/owid-grapher that referenced this issue Feb 17, 2022
@SimenB
Copy link
Member Author

SimenB commented Feb 17, 2022

With https://github.com/facebook/jest/releases/tag/v28.0.0-alpha.3 the implementation of exports was rewritten, and the one known bug (reported by @uriklar above) was fixed. Hopefully I didn't introduce any regressions either 😀

Please test it!

@rmolinamir
Copy link

rmolinamir commented Feb 17, 2022

Upgrading to v28.0.0-alpha.2 worked for me when importing "root" exports, but the resolver seems to still have issues when importing Subpath exports or Subpath patterns. Has anyone else run into this issue?

EDIT: Let me try with v28.0.0-alpha.3, it was release as I was typing this 😄

@rmolinamir
Copy link

@SimenB v28.0.0-alpha.3 seems to have fixed the issue with subpaths as referenced above, works perfectly so far. I will continue to test and will report issues if any.

@SimenB
Copy link
Member Author

SimenB commented Feb 17, 2022

there was an issue if your pattern was "./some-non-existent-dir/*": "./some-existent-dir/*" which was fixed in alpha 3 (at least in theory) 🙂

@SimenB
Copy link
Member Author

SimenB commented Feb 17, 2022

Ah, wonderful @rmolinamir!

@perrin4869
Copy link

perrin4869 commented Feb 17, 2022

@SimenB I was wondering if in v27 or in v28 there is a way to call import, bypassing jest's mocking system?
A while back I was trying to complete a PR for react-router, but I got stuck trying to implement the tests because I couldn't figure out how to do a regular import

Edit: here is where I got stuck: perrin4869/react-router@8d47441#diff-d8a2cb7ecc9e1cf5168cefd084cb7b9ab315ba051f61b4799ad4e33c2baa1394R20

@SimenB
Copy link
Member Author

SimenB commented Feb 17, 2022

@perrin4869 not related to this issue.

However, the answer is "no" - you cannot use "real" import from within Jest. I recommend setting up a separate script using plain node code (you can still use expect if you want to keep the assertions) if you want to bypass Jest's implementation

@perrin4869
Copy link

@SimenB Ah sorry, I was just getting notifications in this issue and suddenly I felt like revisiting!
Thanks for the advice! I was just wondering, how were you envisioning running this separate script? exec()?

@FrozenKiwi
Copy link

FrozenKiwi commented Feb 17, 2022

@perrin4869 Not sure if this helps, but you can use exports to bypass mocking.

In our project, we conditionally export "mocked" versions of each packages for testing (rather creating manual mocks within the packages' clients, cause DRY). We then also export a direct path to classes if I ever wish to bypass those mocks. so any external code calling import { MailClient } from @com/mail gets the mocked version, but if we ever explicitly want to actually interact with the full implementation we call import { MailClient } from @com/mail/client

It's pretty specific, may not be applicable to your situation, but it sounds like you want something similar to the reasons we set this up.

@perrin4869
Copy link

@FrozenKiwi Thanks! That's a convenient setup :)
I'm referring here about being able to test the exports field itself - make sure it doesn't suddenly break with a new release of the library. Unfortunately this doesn't seems possible with jest...

@SimenB
Copy link
Member Author

SimenB commented Feb 20, 2022

There's a lot of people subscribed to this issue, please keep discussion about things not related to the resolver implementation of exports within Jest elsewhere.

marcelgerber added a commit to owid/owid-grapher that referenced this issue Feb 20, 2022
marcelgerber added a commit to owid/owid-grapher that referenced this issue Feb 23, 2022
marcelgerber added a commit to owid/owid-grapher that referenced this issue Mar 15, 2022
tantaman added a commit to tantaman/misc that referenced this issue Mar 15, 2022
see jestjs/jest#9771

using jest v28.0.0-alpha.3

"package exports" are how we export from `mono/model`
marcelgerber added a commit to owid/owid-grapher that referenced this issue Mar 21, 2022
@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 Mar 23, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.