histoire
histoire copied to clipboard
ReferenceError when using `crypto` in Svelte 3 components
Describe the bug
We are using crypto.randomUUID()
to generate unique IDs for input label associations on the fly in our Svelte 3 <Input/>
component:
let inputId = crypto.randomUUID();
Today, when porting our Storybook to Histoire, I noticed that the story isn't appearing in Histoire, and a Reference Error gets thrown in the terminal, when a Svelte 3 component uses crypto
.
I've attached a minimal repro, which has both npm run story:dev
and npm run dev
, to showcase that this error only occurs in Histoire, not the Svelte 3 app itself.
~/projects/histoire-svelte3-starter-vpjzy9
❯ npm run story:dev
$ histoire dev
➜ Local: http://localhost:6006/
➜ Network: use --host to expose
Collect stories start all
[HMR][Svelte] Unrecoverable HMR error in <BaseButton>: next update will trigger a full reload
Error while collecting story /home/projects/histoire-svelte3-starter-vpjzy9/src/BaseButton.story.svelte:
ReferenceError: crypto is not defined
at instance (/home/projects/histoire-svelte3-starter-vpjzy9/src/BaseButton.svelte:105:13)
at Module.init (/home/projects/histoire-svelte3-starter-vpjzy9/node_modules/svelte/internal/index.mjs:1891:11)
at new BaseButton (/home/projects/histoire-svelte3-starter-vpjzy9/src/BaseButton.svelte:140:25)
at Module.createProxiedComponent (/home/projects/histoire-svelte3-starter-vpjzy9/node_modules/svelte-hmr/runtime/svelte-hooks.js:338:9)
at new ProxyComponent (/home/projects/histoire-svelte3-starter-vpjzy9/node_modules/svelte-hmr/runtime/proxy.js:243:29)
at new Proxy<BaseButton> (/home/projects/histoire-svelte3-starter-vpjzy9/node_modules/svelte-hmr/runtime/proxy.js:351:11)
at Array.create_default_slot (/home/projects/histoire-svelte3-starter-vpjzy9/src/BaseButton.story.svelte:51:15)
at Module.create_slot (/home/projects/histoire-svelte3-starter-vpjzy9/node_modules/svelte/internal/index.mjs:69:29)
at j (/home/projects/histoire-svelte3-starter-vpjzy9/node_modules/@histoire/plugin-svelte/dist/collect/Story.js:4:66)
at Module.init (/home/projects/histoire-svelte3-starter-vpjzy9/node_modules/svelte/internal/index.mjs:1906:37)
Collect stories end 469 ms
A workaround for now is to check if crypto is defined and conditionally use a fallback:
let inputId = 'crypto' in window ? crypto.randomUUID() : Math.random();
I tried the same in Vue 3, and it seems to work fine there.
Reproduction
https://stackblitz.com/edit/histoire-svelte3-starter-vpjzy9?file=src/BaseButton.svelte
System Info
System:
OS: macOS 12.5.1
CPU: (8) arm64 Apple M1 Pro
Memory: 107.89 MB / 16.00 GB
Shell: 5.8.1 - /bin/zsh
Binaries:
Node: 16.17.0 - ~/.nvm/versions/node/v16.17.0/bin/node
npm: 8.15.0 - ~/.nvm/versions/node/v16.17.0/bin/npm
Browsers:
Chrome: 104.0.5112.101
Firefox: 102.0.1
Safari: 15.6.1
npmPackages:
@histoire/plugin-svelte: ^0.10.7 => 0.10.7
histoire: ^0.10.7 => 0.10.7
vite: ^2.9.14 => 2.9.14
Used Package Manager
pnpm
Validations
- [X] Follow our Code of Conduct
- [X] Read the Contributing Guidelines.
- [X] Read the docs.
- [X] Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
- [X] Check that this is a concrete bug. For Q&A open a GitHub Discussion.
- [X] The provided reproduction is a minimal reproducible example of the bug.
crypto
is probably not available in Node globals
Is this linked to #384 ?
When trying to import Sveltekit specific modules in components (i.e. $path
) it will break the Histoire story and component will never show.
Not related I think.
yeah, looks like it's part of svelte3
I see you originally ran this on Node 16. Does it work if you try Node 20? https://nodejs.org/api/globals.html#crypto_1
SvelteKit is supposed to polyfill crypto
if you're running on an older version of Node where it's not available. Histoire needs to selectively include only some SvelteKit plugins. It's possible that this means SvelteKit would need to make sure the polyfill happens in a plugin that Histoire is running or something like that.
Please reopen in case you still have the issue with Node 20