React+Vite应用环境变量失效致AWS Cognito认证异常求助
问题:Vite构建React+AWS Cognito应用时环境变量无法正确加载
我用Vite构建集成AWS Cognito认证的React应用,遇到环境变量无法正确加载或访问的问题,AWS Cognito配置因构建时环境变量传递错误而失效。移除vite.config.ts中硬编码的fallback值后,应用无法运行,控制台报错:
Uncaught Error: Both UserPoolId and ClientId are required. at new CognitoUserPool2 (amazon-cognito-identity-js.js?v=6908fcf6:5140:13) at auth.ts:14:18
相关代码参考
auth.ts文件
import { CognitoUserPool, CognitoUser, AuthenticationDetails, CognitoUserSession, CognitoUserAttribute } from 'amazon-cognito-identity-js'; const poolData = { UserPoolId: import.meta.env.VITE_AWS_USER_POOL_ID, ClientId: import.meta.env.VITE_AWS_USER_POOL_WEB_CLIENT_ID }; const userPool = new CognitoUserPool(poolData); // 报错指向的第14行 export const getCurrentUser = () => { return userPool.getCurrentUser(); }; export const isAuthenticated = async (): Promise<boolean> => { const user = getCurrentUser(); if (!user) return false; return new Promise((resolve) => { user.getSession((err: Error | null, session: CognitoUserSession | null) => { if (err || !session || !session.isValid()) { resolve(false); return; } resolve(true); }); }); }; export const signIn = (email: string, password: string): Promise<any> => { return new Promise((resolve, reject) => { const authenticationDetails = new AuthenticationDetails({ Username: email, Password: password }); const cognitoUser = new CognitoUser({ Username: email, Pool: userPool }); cognitoUser.authenticateUser(authenticationDetails, { onSuccess: (result) => { resolve(result); }, onFailure: (err) => { reject(err); } }); }); }; // 其余认证函数:signOut、signUp、confirmRegistration等代码省略
vite.config.ts文件
import { defineConfig, loadEnv } from "vite"; import react from "@vitejs/plugin-react"; import tailwindcss from "@tailwindcss/vite"; import path from "path"; export default defineConfig(({ mode }) => { const env = loadEnv(mode, process.cwd(), ''); const poolConfig = { userPoolId: env.VITE_AWS_USER_POOL_ID || "my-user-pool-id", // 移除fallback后失效 clientId: env.VITE_AWS_USER_POOL_WEB_CLIENT_ID || "my-web-client-id" // 移除fallback后失效 }; return { plugins: [react(), tailwindcss()], base: "/", resolve: { alias: { "@": path.resolve(__dirname, "./src"), './runtimeConfig': './runtimeConfig.browser', }, }, define: { 'process.env': {}, 'import.meta.env.VITE_AWS_USER_POOL_ID': JSON.stringify(poolConfig.userPoolId), 'import.meta.env.VITE_AWS_USER_POOL_WEB_CLIENT_ID': JSON.stringify(poolConfig.clientId), 'import.meta.env.VITE_API_URL': JSON.stringify(env.VITE_API_URL), 'import.meta.env.VITE_AWS_REGION': JSON.stringify(env.VITE_AWS_REGION), 'import.meta.env.MODE': JSON.stringify(mode) } }; });
.env文件
VITE_AWS_USER_POOL_ID=us-east-1_myuserpoolid VITE_AWS_USER_POOL_WEB_CLIENT_ID=myclientid VITE_API_URL=https://api.example.com VITE_AWS_REGION=us-east-1
GitHub Actions工作流配置
- name: Build run: npm run build env: VITE_API_URL: ${{ secrets.VITE_API_URL }} VITE_AWS_REGION: ${{ secrets.VITE_AWS_REGION }} VITE_AWS_USER_POOL_ID: ${{ secrets.VITE_AWS_USER_POOL_ID }} VITE_AWS_USER_POOL_WEB_CLIENT_ID: ${{ secrets.VITE_AWS_USER_POOL_WEB_CLIENT_ID }}
咨询问题
- 如何正确配置Vite,无需在vite.config.ts中硬编码敏感环境变量值?
- 使用
import.meta.env在Vite中是否存在已知问题,尤其是结合AWS Cognito时?
解决方案
1. 移除vite.config.ts中冗余的define配置
Vite默认会自动处理以VITE_开头的环境变量,无需手动在define中声明import.meta.env变量——手动声明会覆盖Vite的默认注入逻辑,导致.env文件或CI/CD传入的变量无法生效。
修改后的vite.config.ts:
import { defineConfig, loadEnv } from "vite"; import react from "@vitejs/plugin-react"; import tailwindcss from "@tailwindcss/vite"; import path from "path"; export default defineConfig(({ mode }) => { loadEnv(mode, process.cwd(), ''); // 仅加载环境变量,无需手动赋值 return { plugins: [react(), tailwindcss()], base: "/", resolve: { alias: { "@": path.resolve(__dirname, "./src"), './runtimeConfig': './runtimeConfig.browser', }, }, define: { 'process.env': {} // 仅保留这一行(兼容依赖中使用process.env的情况) } }; });
2. 确保环境变量文件的正确性
- 环境变量文件必须放在项目根目录,不能嵌套在子文件夹中
- 开发环境使用
.env.development,生产环境使用.env.production,默认.env会被所有环境加载(优先级低于环境特定文件) - 变量名必须严格以
VITE_开头,否则Vite不会自动注入
3. 代码中添加环境变量缺失的守卫逻辑
在初始化Cognito UserPool前,先检查环境变量是否存在,提前抛出明确错误,避免后续初始化失败:
import { CognitoUserPool, CognitoUser, AuthenticationDetails, CognitoUserSession, CognitoUserAttribute } from 'amazon-cognito-identity-js'; // 先验证环境变量是否存在 const userPoolId = import.meta.env.VITE_AWS_USER_POOL_ID; const clientId = import.meta.env.VITE_AWS_USER_POOL_WEB_CLIENT_ID; if (!userPoolId || !clientId) { throw new Error("AWS Cognito配置缺失:请确保VITE_AWS_USER_POOL_ID和VITE_AWS_USER_POOL_WEB_CLIENT_ID已正确设置"); } const poolData = { UserPoolId: userPoolId, ClientId: clientId }; const userPool = new CognitoUserPool(poolData); // 后续认证函数保持不变
4. CI/CD环境验证
GitHub Actions中的配置已经正确传递了环境变量,构建时Vite会自动将这些变量注入到代码中,无需额外处理。
关于import.meta.env与AWS Cognito的问题
- Vite的
import.meta.env本身与AWS Cognito没有兼容性问题,核心是确保环境变量在构建阶段被正确注入(Vite会静态替换这些变量,运行时无法动态修改)。 - 注意:AWS Cognito的
UserPoolId和ClientId属于客户端可公开的配置(不是敏感密钥),可以安全地注入到前端代码中,无需担心泄露风险。
内容的提问来源于stack exchange,提问作者Mauricio Pastora
相关产品推荐
相关产品推荐

