Vue+Vite中用bcrypt遇依赖解析错误,换bcryptJS可解决求原因
问题场景
在Vue+Vite项目的登录组件中,调用loginService处理用户名密码,尝试用bcrypt哈希密码时出现依赖解析错误;移除bcrypt代码后项目运行正常,将bcrypt替换为bcryptjs则问题解决。
错误信息
X [ERROR] Could not resolve "mock-aws-s3"
node_modules/@mapbox/node-pre-gyp/lib/util/s3_setup.js:43:28: 43 │ const AWSMock = require('mock-aws-s3'); ╵ ~~~~~~~~~~~~~你可以将"mock-aws-s3"标记为外部依赖以排除在打包之外,这会消除错误。也可以用try/catch包裹require调用,在运行时而非打包时处理失败。
X [ERROR] Could not resolve "aws-sdk"
node_modules/@mapbox/node-pre-gyp/lib/util/s3_setup.js:76:22: 76 │ const AWS = require('aws-sdk'); ╵ ~~~~~~~~~你可以将"aws-sdk"标记为外部依赖以排除在打包之外,这会消除错误。也可以用try/catch包裹require调用,在运行时而非打包时处理失败。
X [ERROR] Could not resolve "nock"
node_modules/@mapbox/node-pre-gyp/lib/util/s3_setup.js:112:23: 112 │ const nock = require('nock'); ╵ ~~~~~~你可以将"nock"标记为外部依赖以排除在打包之外,这会消除错误。也可以用try/catch包裹require调用,在运行时而非打包时处理失败。
相关代码
登录组件
<template> <div> <h1>Welcome to the WarBank</h1> <div> <form class="tile" @submit.prevent="login"> <input type="text" v-model="userCredentials.userName" placeholder="username" /> <input type="password" v-model="userCredentials.passWord" placeholder="****" /> <button type="submit">Login</button> </form> </div> </div> </template> <script lang="ts"> import { defineComponent, reactive } from "vue"; import { User } from "../interface/login"; import { fetchLoginService } from "../services/loginService"; export default defineComponent({ name: "Login", components: { OpenAccount, }, setup() { const userCredentials: User = reactive({ userName: "", passWord: "", }); const login = async() => { fetchLoginService(userCredentials.userName,userCredentials.passWord); }; return { userCredentials, login, }; }, }); </script> <style scoped> </style>
Service文件
import axios from 'axios'; import bcrypt from 'bcrypt'; export async function fetchLoginService(userName:string, password:string){ const loginURL = "URL here" const hashpassword = await bcrypt.hash(password,12); axios.post(loginURL,{userName,password:hashpassword}).then((response:any)=>{ console.log(response); }).catch((error)=>{ console.log(error) }) }
vite.config.ts
import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' // https://vitejs.dev/config/ export default defineConfig({ plugins: [vue()], optimizeDeps: { include: ['bcrypt'], }, })
原因分析
bcrypt的环境适配问题:原版
bcrypt是为Node.js后端环境开发的,它依赖@mapbox/node-pre-gyp工具来编译和安装原生二进制模块。而@mapbox/node-pre-gyp又引入了aws-sdk、mock-aws-s3、nock这些后端专属依赖——这些模块用于云存储操作、后端测试,完全不兼容前端浏览器环境,Vite在打包时无法解析这类仅适用于Node.js的依赖,因此抛出错误。bcryptjs的适配优势:
bcryptjs是bcrypt的纯JavaScript实现,没有任何原生二进制依赖,完全兼容浏览器和前端构建工具(如Vite),因此替换后不会出现依赖解析问题。同类问题共性:类似场景中,原生Node.js模块在前端环境使用时,常因依赖后端工具链或专属模块导致打包失败,选择纯JS实现的替代库是更可靠的方案。
内容的提问来源于stack exchange,提问作者Bhanu Prakash War

