我对 Express.js 应用程序进行了非常基本的设置,并尝试向其中添加 Auth.js。当我这样做时,API 会启动,但是当加载 /api/auth 之外的任何路径时,它会导致以下堆栈跟踪,并且控制台中没有日志。唯一表明问题的其他迹象是它重定向到 /api/auth/error?error=Configuration
[auth][error] TypeError: (0 , import_preact_render_to_string.renderToString) is not a function
api:dev:at send (/Users/josh/projects/saas-starter-kit/node_modules/@auth/core/lib/pages/index.js:13:350)
api:dev:at Object.error (/Users/josh/projects/saas-starter-kit/node_modules/@auth/core/lib/pages/index.js:119:20)
api:dev:at AuthInternal (/Users/josh/projects/saas-starter-kit/node_modules/@auth/core/lib/index.js:31:31)
api:dev:at Auth (/Users/josh/projects/saas-starter-kit/node_modules/@auth/core/index.js:109:34)
api:dev:at <anonymous> (/Users/josh/projects/saas-starter-kit/node_modules/@auth/express/index.js:141:45)
如何重现
tsconfig.json
{
"compilerOptions": {
"target": "es2016",
"module": "commonjs",
"outDir": "./dist",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true
}
}
索引.ts
import { logger } from '@repo/logger'
import 'dotenv/config'
import { createServer } from './server'
const port = process.env.PORT || 3001
const server = createServer()
server.listen(port, async() => {
logger.info(`api server is starting: Date: ${new Date()}`)
})
服务器.ts
import express, { type Express } from 'express'
import morgan from 'morgan'
import { ExpressAuth } from "@auth/express"
import GitHub from "@auth/express/providers/github"
export const createServer = (): Express => {
const app = express()
app
.use(express.urlencoded({ extended: true }))
.use(express.json())
.set("trust proxy", true)
.use("/api/auth/*", ExpressAuth({
debug: true,
trustHost: true,
providers: [
GitHub
],
}))
.get('/status', (_, res) => {
return res.json({ ok: true })
})
return app
}
.env.local
AUTH_SECRET=""
AUTH_GITHUB_ID=""
AUTH_GITHUB_SECRET=""
AUTH_URL="http://localhost:3001/api/auth"
启动命令
dotenvx run --env-file ./.env.local -- nodemon --exec \"node -r esbuild-register ./src/index.ts\" -e .ts
预期行为 我希望登录页面会加载一些内容,而不是服务器控制台错误消息。
就我而言,同样的问题是由于我在项目中使用的“CommonJS”模块造成的。老实说,我不知道它是如何相关的......但我的解决方案是使用动态导入,因为 cofigure 打字稿对我来说变得太困难了。 我编写
AuthJsDepencencies
加载器将这些细节从我的项目中封装出来,并使用它,例如:
async function main() {
const app = express()
const authHandler = await AuthJsDependencies.load()
app.use('/auth/*', authHandler)
}
如果有趣 - 不是异步单例加载依赖项的最佳示例:
export class AuthJsDependencies {
private static target?: Awaited<ReturnType<typeof AuthJsDependencies._load>>;
public static async load() {
if (!AuthJsDependencies.target) {
AuthJsDependencies.target = await AuthJsDependencies._load();
}
return this.target!;
}
public static async _load() {
const [
{ ExpressAuth },
{ default: SequelizeAdapter },
{ default: Google },
] = await Promise
.all([
import("@auth/express"),
import("@auth/sequelize-adapter"),
import("@auth/express/providers/google"),
]);
return {
ExpressAuth,
SequelizeAdapter,
Google,
};
}
}