P粉0193532472023-08-27 11:31:26
The problem is that both NodeJS and the browser have a module called crypto
(which implements the webcrypto standard), they are compatible, but need to be Accessed differently because in the browser it is provided by a window
context that does not exist in NodeJS.
If you work directly in the browser, you won't see the difference because window
is the default context.
But Vite is working in the context of NodeJS, it (correctly) believes that this module is not available as crypto
in the browser, and therefore throws an error. It doesn't know/care that this module also exists in the browser, but as window.crypto
.
Maybe it can be configured in vite.config.js
, but I'm not very familiar with it.
I came up with the following solution, which works in both environments:
function getCrypto() { try { return window.crypto; } catch { return crypto; } }
async function hash(token) { const compatibleCrypto = getCrypto(); const data = new TextEncoder().encode(token); const byteHash = await compatibleCrypto.subtle.digest('SHA-256', data); const arrayHash = Array.from(new Uint8Array(byteHash)); const hexHash = arrayHash .map(b => b.toString(16).padStart(2, '0')) .join('') .toLocaleUpperCase(); return hexHash; }
Now this function works in both environments.