You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

fastify-mongoose报uri参数必填,fastify-env加载环境变量失效怎么解决?

问题原因
  • 核心是Fastify插件注册为异步流程,你传递给插件的配置参数是在调用register()的同步执行阶段就完成取值的,不会等待前置插件加载完成后再计算。
  • 代码中声明的uri变量初始值为undefined,fastify-env加载完成后给uri赋值的逻辑在异步的ready()回调中执行,而注册fastify-mongoose的代码是同步执行的,执行时uri还未被赋值,传入的是undefined,因此触发uri参数必填的报错。
  • 即使start函数中调用了await fastify.ready(),也不影响之前register(fastify_mongoose)时已经传入了undefined的配置,因为配置取值在register调用那一刻就已经完成。
修复方案

不需要额外声明全局的PORT、uri变量,直接从fastify.config取值即可,以下是两种常用的修复方式:

方案1:使用after钩子等待前置插件加载完成

const ejs = require('ejs')
const path = require('path');
const fastify = require('fastify')();
const fastify_static = require('fastify-static');
const fastify_autoload = require('fastify-autoload');
const fastify_mongoose = require('fastify-mongoose');
const fastify_env = require('fastify-env');

// 先注册fastify-env
fastify.register(fastify_env, {
    dotenv: true,
    schema: {
        type: 'object',
        required: ['MONGO_URI', 'PORT'],
        properties: {
            MONGO_URI: {
                type: 'string',
                default: ''
            },
            PORT: {
                type: 'string',
                default: ''
            }
        }
    }
})

// 等fastify-env加载完成后再注册依赖环境变量的插件
fastify.after(() => {
    fastify.register(fastify_mongoose, {
        uri: fastify.config.MONGO_URI
    })

    fastify.register(fastify_static, {
        root: path.join(__dirname, 'public'),
    })

    fastify.register(require('point-of-view'), {
        engine: {
            ejs: ejs,
        },
        root: path.join(__dirname, 'view')
    })

    fastify.register(fastify_autoload, {
        dir: path.join(__dirname, 'Logic/Routes'),
    })

    fastify.register(require('./Logic/Plugins/cache'))
})

const start = async () => {
    try {
        await fastify.ready();
        await fastify.listen(fastify.config.PORT);
        console.log('Listening on port: ', fastify.config.PORT);
    } catch (error) {
        throw new Error(error);
    }
}

start();

方案2:用异步函数包裹全流程,等待fastify-env注册完成

利用register返回Promise的特性,用await等待前置插件加载完成后再注册后续插件:

const ejs = require('ejs')
const path = require('path');
const fastify = require('fastify')();
const fastify_static = require('fastify-static');
const fastify_autoload = require('fastify-autoload');
const fastify_mongoose = require('fastify-mongoose');
const fastify_env = require('fastify-env');

const init = async () => {
    // 等待fastify-env加载完成
    await fastify.register(fastify_env, {
        dotenv: true,
        schema: {
            type: 'object',
            required: ['MONGO_URI', 'PORT'],
            properties: {
                MONGO_URI: {type: 'string', default: ''},
                PORT: {type: 'string', default: ''}
            }
        }
    })

    // 注册其他插件
    fastify.register(fastify_mongoose, {uri: fastify.config.MONGO_URI})
    fastify.register(fastify_static, {root: path.join(__dirname, 'public')})
    fastify.register(require('point-of-view'), {engine: {ejs}, root: path.join(__dirname, 'view')})
    fastify.register(fastify_autoload, {dir: path.join(__dirname, 'Logic/Routes')})
    fastify.register(require('./Logic/Plugins/cache'))

    // 启动服务
    await fastify.ready()
    await fastify.listen(fastify.config.PORT)
    console.log('Listening on port: ', fastify.config.PORT)
}

init().catch(err => {
    throw new Error(err)
})

内容的提问来源于stack exchange,提问作者hyden97

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 14:45:02