Vue3/Vite: 將模組外部化
P粉107991030
P粉107991030 2023-08-26 13:45:43
0
1
543

我正在嘗試在Vue 3應用程式中使用crypto對字串進行雜湊。

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 } 

據我了解,現在瀏覽器中可以使用crypto,所以不需要使用browserify替代。

然而,我在瀏覽器控制台中遇到了以下錯誤:

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

我理解這個錯誤為「Vite在建置過程中配置了將crypto模組外部化」。但是我在我的vite.config.js中沒有找到這樣的設定:

// Plugins: import vue from '@vitejs/plugin-vue' import vuetify from 'vite-plugin-vuetify' // Utilies: import { defineConfig } from 'vite' import { fileURLToPath, URL } 從 '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 } }) 

是否有任何「內建」的Vite預設設定會導致這個問題?這個問題是否在其他地方進行了配置?我該如何解決這個問題並在我的應用程式中使用crypto模組?

P粉107991030
P粉107991030

全部回覆 (1)
P粉019353247

問題在於NodeJS和瀏覽器有一個名為crypto的模組(實現了webcrypto標準),它們是相容的,但需要以不同的方式訪問,因為在瀏覽器中它是由不存在於NodeJS中的window上下文提供的。

如果您直接在瀏覽器中工作,您不會看到區別,因為window是預設上下文。

但是Vite是在NodeJS上下文中工作的,它(正確地)認為在瀏覽器中這個模組不可用作crypto,因此會拋出錯誤。它不知道/不關心這個模組在瀏覽器中也存在,但是作為window.crypto

也許可以在vite.config.js中進行配置,但我對此不太熟悉。

我想到了以下解決方案,它在兩個環境中都有效:

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; }

現在這個函數在兩個環境中都可以工作。

    最新下載
    更多>
    網站特效
    網站源碼
    網站素材
    前端模板
    關於我們 免責聲明 Sitemap
    PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!