Node.js/TypeScript API无法正确加载Azure Cosmos MongoDB连接字符串环境变量
我用TypeScript开发了运行在Node.js上的API,对接Microsoft Azure数据库。前一晚测试一切正常,但今早启动时持续出现以下错误:
TypeError: Cannot read properties of undefined (reading 'startsWith') at connectionStringHasValidScheme (C:\Users\Jordan\Downloads\Website\auth-api\node_modules\mongodb-connection-string-url\lib\index.js:9:30) at new ConnectionString (C:\Users\Jordan\Downloads\Website\auth-api\node_modules\mongodb-connection-string-url\lib\index.js:85:34) at parseOptions (C:\Users\Jordan\Downloads\Website\auth-api\node_modules\mongodb\lib\connection_string.js:191:17) at new MongoClient (C:\Users\Jordan\Downloads\Website\auth-api\node_modules\mongodb\lib\mongo_client.js:51:63) at Object.<anonymous> (C:\Users\Jordan\Downloads\Website\auth-api\dist\server.js:25:16) at Module._compile (node:internal/modules/cjs/loader:1358:14) at Module._extensions..js (node:internal/modules/cjs/loader:1416:10) at Module.load (node:internal/modules/cjs/loader:1208:32) at Module._load (node:internal/modules/cjs/loader:1024:12) at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:174:12)
这是我的第一个Web开发项目,可能漏了些基础操作。我已经试过重命名.env文件、给连接字符串加引号、重装所有node_modules,但问题依旧。确认.env文件在API根目录,语法也没问题。
我的TS代码
import express, { Request, Response } from 'express'; import cors from 'cors'; import { MongoClient } from 'mongodb'; import dotenv from 'dotenv'; dotenv.config(); const app = express(); const port = process.env.PORT || 3000; console.log('COSMOS_DB_URI:', process.env.COSMOS_DB_URI); app.use(cors()); app.use(express.json()); const client = new MongoClient(process.env.COSMOS_DB_URI!); client.connect().then(() => { const db = client.db('jrfbActivityLogger'); const usersCollection = db.collection('Usernames'); app.post('/login', async (req: Request, res: Response) => { try { const { username } = req.body; const user = await usersCollection.findOne({ username }); if (user) { res.status(200).json({ success: true }); } else { res.status(401).json({ success: false, message: 'Authentication failed' }); } } catch (error) { console.error('Error:', error); res.status(500).json({ success: false, message: 'An error occurred' }); } }); app.listen(port, () => { console.log(`Server is running on port ${port}`); }); }).catch((err) => { console.error('Failed to connect to database:', err); });
.env文件内容(已脱敏)
COSMOS_DB_URI=mongodb://myDBUsername:mydbpassword@mydb.mongo.cosmos.azure.com:myport/?ssl=true&replicaSet=globaldb&retrywrites=false&maxIdleTimeMS=120000&appName=@mydb@
tsconfig.json配置
{ "compilerOptions": { "target": "ES6", "module": "commonjs", "rootDir": "./src", "outDir": "./dist", "strict": true, "esModuleInterop": true }, "include": ["src/**/*.ts"], "exclude": ["node_modules"] }
解决思路及步骤
这个错误的核心是process.env.COSMOS_DB_URI的值为undefined,导致MongoDB客户端在解析连接字符串时调用startsWith方法失败。以下是针对性的排查和解决步骤:
指定dotenv加载路径
当前调用dotenv.config()未指定路径,如果TS文件在src目录下,dotenv可能无法找到根目录的.env文件。可以显式指定路径解决:import path from 'path'; dotenv.config({ path: path.resolve(__dirname, '../.env') });添加环境变量校验
代码里的非空断言!无法保证运行时变量非空,建议前置校验避免报错:const cosmosUri = process.env.COSMOS_DB_URI; if (!cosmosUri) { throw new Error('COSMOS_DB_URI环境变量未设置'); } const client = new MongoClient(cosmosUri);同时观察启动时的
console.log输出,如果显示undefined,说明.env文件确实未被加载,检查文件名(需是.env而非env)、文件路径是否正确。验证构建后的路径逻辑
因为编译后的代码在dist目录运行,确认dist/server.js中dotenv.config()的路径是否正确。可以临时将.env复制到dist目录测试,若能正常运行,说明是路径问题,按第一步方法修复即可。处理连接字符串特殊字符
如果密码包含#、=这类特殊字符,需要用双引号包裹整个连接字符串:COSMOS_DB_URI="mongodb://myDBUsername:mydbpassword@mydb.mongo.cosmos.azure.com:myport/?ssl=true&replicaSet=globaldb&retrywrites=false&maxIdleTimeMS=120000&appName=@mydb@"重新确认dotenv安装
虽然重装过依赖,可再单独安装dotenv确保版本正确:npm install dotenv --save
按上述步骤排查,应该能定位并解决问题。
内容的提问来源于stack exchange,提问作者jordanc-j

