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
"TypeError: create is not a function" when using with jest configured for ESM #559
Comments
Yeah, it seems picking the cjs bundle. Another challenge for us, @barelyhuman . |
Right when I thought it's done 😂 , I'll check it out |
@duarten could you instead try with so
and use that for the execution?
|
That way it seems jest doesn't understand the modules it loads:
|
Cool, that’s enough info for me to know what’s going on |
@duarten {
"name": "repro",
"version": "1.0.0",
"type": "module",
"main": "index.js",
"scripts": {
"test": "jest"
},
"jest": {
"transform": {
"\\.m?jsx?$": "jest-esm-transformer"
}
},
"dependencies": {
"jest": "27.1.1",
"react": "17.0.2",
"zustand": "3.5.10"
},
"devDependencies": {
"jest-esm-transformer": "^1.0.0"
}
} the problem is with jest and not zustand.
the above solution is the simplest one without breaking a lot into your original setup, other options include using Hope that helps |
Thanks, @barelyhuman! Closing as it's not a zustand issue. |
Sorry guys to open this issue again. I do think it is a zustand issue. It does not have anything to do with jest. In fact, it returns back to the way zustand is transpiled. I used rollup to compile my esm module to cjs. I had used import create from 'zustand/vanilla'
const store = create( ... ) // store details ignored My compiled module seemed ok. const create = require('zustand/vanilla');
const store = create( ... ) After tried to run a simple nodejs code to test my store in javascript, I encountered the Putting a
What the module really exports is an object with a When I looked down ....
exports["default"] = createStore; As far as I know, the correct way to export a default value in a cjs module is as below: module.exports = createStore; I think the problem is with the way Currently, to resolve my issue I did a type checking on import create from 'zustand/vanilla';
if (typeof create == 'function') {
store = create( .... );
} else {
store = create.default( ... );
} Sorry for my long post. I hope my feedback helps to correct zustand compilation issue. |
Running into the same issue with Next.js. I need to access create.default instead of create when cjs is used. Somehow it stopped working correctly after updating ts-up in my lib. This seems odd: export { createStore as default }; |
Let me check if the export target was changed in the previous releases, can one of you @Pagebakers @mansoor-omrani let me know the zustand version you are working with? The transpilation should take care of adding an additional node module resolver compatible export with the esm default export standard as well. example: module.exports = create
exports["default"] = create both should be a part of the output code, which I'm sure was working before a little information about the version would help |
While this isn't ideal, I think it's intended. Object.defineProperty(exports, '__esModule', { value: true }); So, in Node CJS, it's correct to read it as If we were to support
|
That's actually nice, if we can configure rollup to do it. |
A few of my older packages has this with rollup, let me look it up |
https://nodejs.org/api/packages.html#writing-dual-packages-while-avoiding-or-minimizing-hazards The recommendation is to use named exports only for dual bundle packages.
|
The recommendation came long after we already had the exposed API solidified 😅 |
Precisely. |
Yeah fair enough 😆 Just stating it, since I suspect it will cause issues with projects other than jest/nextjs as well. |
So this is why my build broke after upgrading ts-up. Previously my cjs bundle was transpiled like this. var import_react = __toESM(require("react"));
var import_zustand = __toESM(require("zustand"));
var import_vanilla = __toESM(require("zustand/vanilla"));
var import_context = __toESM(require("zustand/context")); Now just plain cjs var react = require("react");
var zustand = require("zustand");
var vanilla = require("zustand/vanilla");
var context = require("zustand/context"); |
I appreciate the tooling trying to handle the cases for us but there's way too many openings that it's bound to fail at some or the other corner. We'll obviously try to patch it up but just a fact when working with ESM and CJS. At this point the simplest way to write libraries would be to just write in esm and let the user's bundler handle how the code is compiled. This solution has it own set of issues but is the one with the least friction in terms of overall usability. As for now, module.exports = Object.assign({}, module.exports, exports.default) the change in rollup for // `config` being the rollup config object
config.output.outro =
'module.exports = Object.assign({}, module.exports, exports.default)' The problem is that, this would add it to every file we have and that might not be ideal, I could raise a dummy PR to test it out |
Yes, please try it. |
Hi @barelyhuman, I'm using zustand 4.1.1 |
@mansoor-omrani Thanks, |
That's working. Thank you. |
I still get this error |
@mkhib Before you do that, can you try If neither works, a reproducible example would help :) |
Unfortunately, it didn't work. |
Oh okay, I see the issue, it's picking the CJS even with TS, if it's blocking your work you can replace the import with In the mock though, where you are using I'll see if can get jest to resolve the cjs package properly from TS, but that's a workaround for now |
@mkhib ignore the above, I failed to see that there was a Your mocks version of zustand is to export That should solve your issue |
@barelyhuman Thanks a lot! It worked like a charm. Thanks for your time and attention. |
Default exports and imports are deprecated. The default import of `zustand` generates a deprecation warning on the console. The default export that was suggested previously would actually fail to compile. See the comments at the very bottom of pmndrs#559 for further discussion. This commit fixes the example in the documentation by introducing named exports & imports instead of default exports & imports.
Default exports and imports are deprecated. The default import of `zustand` generates a deprecation warning on the console. The default export that was suggested previously would actually fail to compile. See the comments at the very bottom of pmndrs#559 for further discussion. This commit fixes the example in the documentation by introducing named exports & imports instead of default exports & imports.
Default exports and imports are deprecated. The default import of `zustand` generates a deprecation warning on the console. The default export that was suggested previously would actually fail to compile. See the comments at the very bottom of pmndrs#559 for further discussion. This commit fixes the example in the documentation by introducing named exports & imports instead of default exports & imports.
Default exports and imports are deprecated. The default import of `zustand` generates a deprecation warning on the console. The default export that was suggested previously would actually fail to compile. See the comments at the very bottom of pmndrs#559 for further discussion. This commit fixes the example in the documentation by introducing named exports & imports instead of default exports & imports.
* docs: Fix Jest example's usage of default imports Default exports and imports are deprecated. The default import of `zustand` generates a deprecation warning on the console. The default export that was suggested previously would actually fail to compile. See the comments at the very bottom of #559 for further discussion. This commit fixes the example in the documentation by introducing named exports & imports instead of default exports & imports. * docs: Suggest using plain import for Jest `jest.requireActual` is not necessary when we're not mocking any other part of `zustand`. * docs: Fix TypeScript example The `create` function was curried where it should not have been. The example is now written in plain TypeScript, as the code that it contains does not require JSX. * Prettier suggestions * Use `jest.requireActual` to avoid circular dependencies
I'm still running into this problem, following the instructions provided at https://github.com/pmndrs/zustand/blob/main/docs/guides/testing.mdx#typescript-usage. Is it possible that it's because I'm using the slices pattern with TypeScript? I'd also note that the docs at https://docs.pmnd.rs/zustand/guides/testing#typescript-usage don't reflect the changes described here. |
The above solution was very specific to the repro mentioned by the above developer. If there's a specific error that you are getting a reproduction would help us help you. |
I am not using ESM but I had a similar error while running tests with jest: |
Consider the following setup:
package.json
:index.js
:repro.test.js
:Then, when running
node --experimental-vm-modules node_modules/.bin/jest
I get:It seems that the import is not picking the esm bundle?
The text was updated successfully, but these errors were encountered: