Vue3/Vite: Externalizing modules
P粉107991030
P粉107991030 2023-08-26 13:45:43
0
1
565

I'm trying to hash a string using crypto in a Vue 3 application.

async function hash (token) { const data = new TextEncoder().encode(token) const byteHash = await crypto.subtle.digest("SHA-256", data) // ^ the below error is thrown here const arrayHash = Array.from(new Uint8Array(byteHash)) const hexHash = arrayHash.map(b => b.toString(16).padStart(2, '0')).join('').toLocaleUpperCase() return hexHash } 

As far as I know, crypto is now available in browsers, so there is no need to use browserify instead.

However, I encountered the following error in the browser console:

Error: Module "crypto" has been externalized for browser compatibility. Cannot access "crypto.subtle" in client code. 

I understand this error as "Vite is configured to externalize the crypto module during the build process." But I don't find such a setting in my vite.config.js:

// Plugins: import vue from '@vitejs/plugin-vue' import vuetify from 'vite-plugin-vuetify' // Utilities: import { defineConfig } from 'vite' import { fileURLToPath, URL } from 'node:url' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ vue(), // https://github.com/vuetifyjs/vuetify-loader/tree/next/packages/vite-plugin vuetify({ autoImport: true }) ], define: { 'process.env': {} }, resolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)) }, extensions: ['.js', '.json', '.jsx', '.mjs', '.ts', '.tsx', '.vue'] }, server: { port: 3000 }, test: { setupFiles: ['../vuetify.config.js'], deps: { inline: ['vuetify'] }, globals: true } }) 

Are there any "built-in" Vite default settings that could cause this issue? Is this issue configured elsewhere? How can I solve this problem and use the crypto module in my application?

P粉107991030
P粉107991030

reply all (1)
P粉019353247

The problem is that both NodeJS and the browserhave a module calledcrypto(which implements thewebcryptostandard), they are compatible, but need to be Accessed differently because in the browser it is provided by awindowcontext that does not exist in NodeJS.

If you work directly in the browser, you won't see the difference becausewindowis the default context.

But Vite is working in the context of NodeJS, it (correctly) believes that this module is not available ascryptoin the browser, and therefore throws an error. It doesn't know/care that this module also exists in the browser, but aswindow.crypto.

Maybe it can be configured invite.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.

    Latest Downloads
    More>
    Web Effects
    Website Source Code
    Website Materials
    Front End Template
    About us Disclaimer Sitemap
    php.cn:Public welfare online PHP training,Help PHP learners grow quickly!