NextJS 与 ExpressJS 服务器 ENV 变量在使用前未加载

时间:2021-04-29 12:11:35

标签: node.js express environment-variables next.js

我有一个带有 ExpressJS 服务器的 NextJS 应用程序,用于处理出于身份验证原因的应用程序的某些部分。应用程序运行没有问题,直到我尝试使用 Sequelize ORM 将 env 变量用于我的数据库配置。起初我认为这可能是由于 NextJS 和 ExpressJS 一起运行而产生的细微差别,但是在代码中的不同点进行控制台记录后,看起来我的 Sequelize DB 配置文件正在运行并在 NextJS/ExpressJS 之前设置环境变量从文件中加载它们。

任何人都可以提供有关为什么会这样的背景信息吗?

config/sequelize.js 我的数据库配置文件:

console.log("Loading config file")
console.log(process.env.DB_DATABASE) // Returns undefined

module.exports = {
  "development": {
    "username": "username",
    "password": "password",
    "database": process.env.DB_DATABASE, // undefined
    "dialect": "postgres"
  },
}

server.js 我的 NextJS 和 ExpressJS 服务器:

console.log('server.js - file read')
console.log('process.env.DB_DATABASE: ' + process.env.DB_DATABASE) // Returns undefined

const express = require('express')
const next = require('next')

const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()
    
app.prepare()
.then(() => {
    const server = express()

    console.log('app.prepare() triggered. Express server configuration started below')
    console.log('process.env.DB_DATABASE: ' + process.env.DB_DATABASE) // Returns "db_template". CORRECT!

    //  Setting proxy for session handlng that is required for non-dev servers
    if (!dev){
        server.set('trust poxy', 1)
    }

    //  ExpressJS Routes
    server.use(routes);

    //  Mount the router on the app 
    //  Any routes that aren't handled by ExpressJS are handled by NextJS
    server.get('*', (req, res) => {
        return handle(req, res)
    })

    server.listen(3000, (err) => {
        if (err) throw err
        console.log('> Ready on http://localhost:3000')
        console.log('Expressjs server listening')
        console.log('process.env.DB_DATABASE: ' + process.env.DB_DATABASE) // Returns "db_template". CORRECT!
    })
})
.catch((ex) => {
    console.error(ex.stack)
    process.exit(1)
})

这是按执行顺序排列的终端输出:

npm run dev

> next-js-boilerplate@0.1.0 dev /Users/user/dev/nextjs/auth-boilerplate
> nodemon server.js

[nodemon] 2.0.7
[nodemon] reading config ./nodemon.json
[nodemon] to restart at any time, enter `rs`
[nodemon] or send SIGHUP to 81315 to restart
[nodemon] ignoring: ./node_modules/**/* ./.next/**/*
[nodemon] watching path(s): controllers/**/* models/**/* config/**/* libs/**/* ssr-server.js
[nodemon] watching extensions: js,json
[nodemon] starting `node server.js`
[nodemon] forking
[nodemon] child pid: 81317
[nodemon] watching 9 files

server.js - file read
process.env.DB_DATABASE: undefined

Loading config
undefined

Browserslist: caniuse-lite is outdated. Please run:
npx browserslist@latest --update-db
Loaded env from /Users/connorphillips/dev/nextjs/auth-boilerplate/.env
info  - Using external babel configuration from /Users/connorphillips/dev/nextjs/auth-boilerplate/.babelrc
event - compiled successfully

app.prepare() triggered. Express server configuration started below
process.env.DB_DATABASE: email_local


> Ready on http://localhost:3000
Expressjs server listening
process.env.DB_DATABASE: email_local

执行顺序汇总:

<块引用>
  • server.js 文件被读取
  • config/sequelize.js 文件被读取
  • 从 .env.development 加载的 env
  • server.js app.prepare() 被触发
  • server.js server.listen() 被触发

1 个答案:

答案 0 :(得分:0)

我遇到了同样的问题。

在执行 app.prepare() 之前初始化代码顶部的导入模块。
我认为您的 config/sequelize.js 是从 "routes" 模块导入的。

我的解决方法是将 "routes" 导入 app.prepare().then().

app.prepare()
.then(() => {
    ...

    // ExpressJS Routes
    // use require because javascirpt import is hoisted.
    server.use(require('./your-routes-path')); // if you use module.exports
    server.use(require('./your-routes-path').default); // if you use export default

    ...
})