-
Notifications
You must be signed in to change notification settings - Fork 904
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
Jest does not work with Firebase out of the box #6747
Comments
I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight. |
If I understand correctly, these rules (the extension must be mjs or there must be I think that Jest/JSDOM runs in Node but for some reason, the build config prefers to pull in the browser bundle. I'm sure there's a reason for this but if the build system is set to follow Node rules there's probably going to be problems if it's pointed at a browser bundle. If there's any way to change the resolver setting in your build config so it prefers the |
As far as I understand, jest has its own module resolution and loader. It needs to be able to mock modules, so it needs to somehow overwrite |
Looking around, it seems the The rules cited above (mjs or "type:module") are rules for Node ES modules specifically, not rules for all ES modules. Unfortunately there are is a lot of different build tooling out there for browser bundles and some of it breaks if you don't follow those rules, and some of it breaks if you do. I'm not sure there is a really good solution to "I want it to resolve following Node rules, but I want the resolved module to behave like browser code" that doesn't break somebody. I'll try to do some research, if this is very standardized now and there are only a few outliers that would be broken maybe we could make it a breaking change in 10.x similar to us moving to ES2017 as the default bundle in 9.x. |
Looking more closely, it looks like the So we might be able to do the same in the |
I'm working on adding "type:module" to the files, as you can see in the linked PR but in the meantime I stumbled across this old issue and wondered if this solution will work for you as a workaround for now: #6417 (comment) You didn't say what specific error you were running into so this might be something completely different, but thought I would link it just in case it helped you get unblocked until this can be addressed in the packaging. |
levino/react-firebase-hooks#3 The "import" errors have gone, but now firestore gets confused and things go south. And just as a remark: As you can see from the list of "bad dependencies", it looks like firebase is one of the very few that are incorrectly configured to work with jest. |
Would you mind sharing the sources for this? Would it be possible to add ci tests for these compatibility issues so one can find a solution to all problems without breaking anything? Also often these issues rather arise from consumers misconfiguration of their build tools than from the publisher using a wrong file extension. So maybe these issues where fixed in the wrong place... |
And just as a bit of context: I want to write tests for firebase hooks which interact with a firebase emulator back end. To test the hooks I tried using |
I created a Next.js project with Jest and Firebase and ran a basic test out of the box to get the error I assume you are getting (you didn't mention what specific error you were getting but you mentioned "import" errors in a comment):
I tested it out with my new PR and it did not fix that error. Changing the extension to mjs and changing the package.json exports field to point to the newly named mjs file also did not fix it, however (in my Next/Jest setup). Did changing it to mjs work for you? Can you tell me more about your setup? You said you're using Jest, and you mentioned I guess what I'd like to do is create a reproduction the error locally so I can see it, so I can test a number of possible options to see if they make the error go away. So I'd like to first make sure I'm reproducing the same error you are getting. Edit: I followed the instructions here: https://jestjs.io/docs/ecmascript-modules and I'm getting this error:
Which again, is with already using the mjs extension. |
Thank you very much for spending so much time on this @hsubox76 and sorry for my late response. I reproduce the original error here or here. This example is using the version How can I use your code? Has it been released as a |
Also a suggestion: Before working any more on fixes, I would suggest to somehow write some kind of integration test (build I will give this idea a spin, once I have some time. |
I'm going to keep looking into this regardless but is your goal to run tests in Jest using ES module imports or is it to just run tests in Jest successfully at all? Because it seems like ES module support in Jest is currently experimental and requires a flag and a number of settings. https://jestjs.io/docs/ecmascript-modules Additionally, searching around the web, it looks like people are having a lot of trouble setting it up and it tends to be very finicky. The workaround I referred to above in another PR (direct link here) is what a lot of Jest/Firebase users are using to just make it work in Jest (not caring about using ES modules specifically). Looking closely, what it actually does is delete the entire This should solve your initial problem of the tests not starting up at all in Jest. The subsequent problem you're having with Firestore erroring is a separate issue which probably won't be solved with any kind of module resolution fixes. It might be related to this bug here? #6658 The workaround does seem really messy to me and there has to be a cleaner way of forcing Jest to use CJS bundles at the very least, so I don't think asking every Jest user to use that workaround is something to be satisfied with. I'm going to keep looking into some kind of less cumbersome solution for the default case for Jest users. Oh, and if you want to verify for yourself if the mjs solution works or doesn't, the quickest way is to go into your project into |
FYI I changed |
I have no issues with the emulator. All tests pass without In order to emulate a firebase version with your changes locally like you suggest I have to change the files in dozens of subpackages of @firebase. The resolver jumps around between these packages like crazy, since it is monorepo with a lot of packages. The easiest way would be if you could publish all these packages with a Also this issue is not super urgent for me any more so maybe we could just wait for the next release of |
My goal is to load I guess why not more people have this issue is that usually, people find it too difficult to set up jest and the emulators so that they can run integration tests against it. It is somewhat clunky and quirky but doable and quite necessary for proper development with firebase imo. |
The changes I made in the release won't work for your use case. They adjust some entry points to follow Node ESM rules which isn't the problem with Jest. The correct fix for Jest, in standard mode, without using the experimental ES modules (which you aren't, you'd have to set the flag) is to change the Jest resolver as described in that link. You can actually make the jest.resolver.js file even shorter:
That's because the problem is that Jest's resolver by default is set up to prioritize However, while Firebase packages do indeed all have a I have to think about who should fix this, but I feel like Jest is incorrect here. Nesting In order for us (the Firebase SDK) to "fix it" without changing Jest, we'd have to create a duplicate "require" field outside the "node" object for every package, which seems kind of hacky. Anyway I guess I may look around the Jest repo to see if this has been discussed and maybe bring it up if it hasn't been. For a workaround, I think most users can add that jest.resolver.js file I pasted above, and then just add one line to jest.config.ts, and that's not out-of-the-box but it should work. If you don't mind, I'm going to change the issue title to "Jest does not work with Firebase out of the box", for better discoverability and such, by other people having Jest problems. Let me know if that is not an accurate summary of the main problem we're trying to fix here. |
The jest issue is a symptom of the incorrect way to build this package, this is why I did not mention jest in the original issue descrioption. You can only have a esmodule js file if you say What I can say is: |
I created https://github.com/levino/firebase-js-sdk/tree/feature/use-yarn-berry which is based on your changes but uses
Then you go to What remains is adding a regression test. Also please note that I had to configure the firestore a bit with:
because if I did not to this, the tests would simply time out. I guess the firebase js code for browser tries to use some fancy feature that is not supported correctly in |
#6826 has been released with 9.15.0 and I tried it in your project and it doesn't seem to fix the issue, but if it's working for you I guess I'll close this and you can reply if it's still not working. |
Currently there are ".js" files generated which are "es modules". Since there is no
"type": "module"
in the package.json, this is simply illegal as far as I can tell. It creates issues when trying to load firebase withjest
andjsdom
.Either we have to make this a module or always use
.mjs
for all modules.The text was updated successfully, but these errors were encountered: