Vue3+Vite使用crypto模块报错:Module已被外部化的解决咨询
问题描述
我在Vue3项目中尝试使用crypto模块对字符串进行哈希处理,编写了如下代码:
async function hash (token) { const data = new TextEncoder().encode(token) const byteHash = await crypto.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 }
据我了解,现代浏览器原生支持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 } 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 } })
请问是否是Vite的默认设置导致该问题?配置是否存在于其他位置?如何修复该问题以正常使用crypto模块?
问题分析与解决
问题原因:Vite默认会将Node.js核心模块(比如
crypto)外部化,因为浏览器环境中没有这些模块的原生实现,但你这里调用的是浏览器原生的window.crypto,却被Vite误当成了Node.js的crypto模块处理。修复方案:
- 直接引用浏览器全局
crypto:
把代码中的crypto改成window.crypto,明确指向浏览器环境的全局API,避免Vite将其解析为Node.js模块:async function hash (token) { const data = new TextEncoder().encode(token) const byteHash = await window.crypto.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 } - Vite配置优化(备选):
如果上述方法无效,可以在vite.config.js中添加optimizeDeps配置,告诉Vite不要外部化crypto:export default defineConfig({ // ...其他原有配置 optimizeDeps: { exclude: ['crypto'] } }) - TypeScript类型补充(可选):
若项目使用TypeScript,可能需要安装@types/web依赖来获得window.crypto的完整类型支持:npm install @types/web --save-dev
- 直接引用浏览器全局
内容的提问来源于stack exchange,提问作者Fred
相关产品推荐
相关产品推荐

