storybook: Vite + Storybook 6.3 + Jest: "global is not defined"
Describe the bug
I am trying to get Vite + Storybook 6.3 working with some existing stories. These stories use jest.fn() as mocks. I previously added this in preview.js to get jest.fn() working within storybook:
import jest from "jest-mock";
window.jest = jest;
But when using the Vite integration I am now getting an error when running storybook:
Uncaught ReferenceError: global is not defined
at ../node_modules/jest-mock/build/index.js (index.js:948)
at __require2 (chunk-IHTDASF6.js?v=3b66b68d:17)
at dep:jest-mock:1
To Reproduce
I am trying vite with storybook 6.3 and npm 7.19 workspaces. My repro repo is here: https://github.com/adiun/vite-monorepo:
- Ensure you have
npm 7.19installed for the workspaces functionality - In the root, run
npm i - In the
appfolder, runnpm run storybook. - In the browser console for storybook you will see:
Uncaught ReferenceError: global is not defined
at ../node_modules/jest-mock/build/index.js (index.js:948)
at __require2 (chunk-IHTDASF6.js?v=3b66b68d:17)
at dep:jest-mock:1
System
Environment Info:
System:
OS: macOS 11.3
CPU: (16) x64 Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz
Binaries:
Node: 14.16.0 - /usr/local/bin/node
npm: 7.19.0 - /usr/local/bin/npm
Browsers:
Chrome: 91.0.4472.114
Edge: 91.0.864.48
Firefox: 88.0.1
Safari: 14.1
npmPackages:
@storybook/addon-docs: 6.3.0 => 6.3.0
About this issue
- Original URL
- State: open
- Created 3 years ago
- Reactions: 2
- Comments: 17 (11 by maintainers)
Commits related to this issue
- fix(vite): monkey-patch global to an empty object See https://github.com/storybookjs/storybook/issues/15391 — committed to guardian/discussion-rendering by mxdvl 2 years ago
- fix(vite): assign global to window See the following issues: - https://github.com/storybookjs/storybook/issues/18399 - https://github.com/storybookjs/storybook/issues/15391 — committed to guardian/discussion-rendering by mxdvl 2 years ago
- fix(vite): assign global to window See the following issues: - https://github.com/storybookjs/storybook/issues/18399 - https://github.com/storybookjs/storybook/issues/15391 — committed to guardian/discussion-rendering by mxdvl 2 years ago
- fix(vite): assign global to window See the following issues: - https://github.com/storybookjs/storybook/issues/18399 - https://github.com/storybookjs/storybook/issues/15391 — committed to guardian/discussion-rendering by mxdvl 2 years ago
- fix(vite): assign global to window See the following issues: - https://github.com/storybookjs/storybook/issues/18399 - https://github.com/storybookjs/storybook/issues/15391 — committed to guardian/discussion-rendering by mxdvl 2 years ago
- fix(vite): assign global to window See the following issues: - https://github.com/storybookjs/storybook/issues/18399 - https://github.com/storybookjs/storybook/issues/15391 — committed to guardian/discussion-rendering by mxdvl 2 years ago
- docs: re-enable `addon-jest` with Vite workaround https://github.com/storybookjs/storybook/issues/15391 — committed to nl-design-system/utrecht by Robbert 9 months ago
- docs: re-enable `addon-jest` with Vite workaround https://github.com/storybookjs/storybook/issues/15391 — committed to nl-design-system/utrecht by Robbert 9 months ago
Following up on this… it’s actually a bad idea to redefine global like this in
main.js:The Vite docs even mention this.
The problem is that when running a
build-storybook, any references toglobalin libraries like@storybook/client-loggerwill be rewritten towindowand it will break since it’s running innode.So I removed this code in
main.jsto getbuild-storybookworking and added this hack to.storybook/preview-head.htmlto getstart-storybookworking:main.js:
preview.js:
preview-head.html:
Alright, I finally fixed this…
jest-mockdoesn’t explicitly provide a default export so in storybook’spreview.jsthis is what I have:This combined with assigning
globaltowindowinmain.jsfixed this issue.preview.js
main.js
Updated my repo too
Maybe we should document this in the README - a section about troubleshooting and potential workarounds? We could inject
window.global = windowinto the iframe, generated by the builder itself, but I suspect that we may encounter edge cases where that’s not desirable? I guess the problem here is that Jest is written to be run in Node.js, whereglobalis a variable. I suppose the “correct” solution would be to fix Jest, so it uses globalThis?Or with overrides in npm, confirmed working.
Yes, I’ve been working on upgrading jest in the storybook packages, but it’s a bit complex because of the way that jest types are global and the interactions with jest-dom. I’m waiting for some feedback on https://github.com/testing-library/jest-dom/pull/483.
I’m confused, if this is the fix, couldn’t we open a PR here in storybook to upgrade the dependency
Or what else are we missing?
For anyone using yarn, overriding the
jest-mockversion usingresolutionsin your package.json might work for you to get the latest version ofjest-mockwhich doesn’t have theglobalissue.Nuxt tries to cover a few distribution and render channels (e.g. service workers) and for this reason adds its own polyfills, but
globalin a cjs file is not yet supported https://github.com/nuxt/nuxt.js/issues/12830. One can workaround this issue by an adding custom alias that essentially redirects it toglobalThis, see the instructions at https://github.com/nuxt-community/storybook/pull/385. But it would be nice if this workaround wouldn’t be needed at all and storybook would rely directly on the more modernglobalThis.Yes, my use case is completely independent of jest.