我正在 Nuxt 3 中构建一个网站,用于使用 SSR 的前端,以及后端的 Laravel。在 Nuxt 3 项目中,我在 utils 目录中有一个 ApiBridge.js 文件,用于组织 API 调用、设置基本 URL 等。自启动该项目以来,我一直在关闭服务器端渲染的情况下运行它为了方便起见,但是当我尝试在启用 SSR 的情况下运行它(在 nuxt.config.js 中启用)时,我收到“Nuxt 实例不可用”错误。我在旅途中学习 Nuxt 3 的同时正在做这个项目,所以我可能会遗漏一些明显的东西。
import axios from "axios";
const runtimeConfig = useRuntimeConfig()
const api = axios.create({
baseURL: runtimeConfig?.API_BASE_URL,
withCredentials: true,
});
const apiBridge = {
login: (info) => api.post('/login', {
...info,
}),
register: (info) => api.post('/register', {
...info,
})
/* .... */
}
export default apiBridge;
为什么会这样?这是一个不好的方法吗?如何解决?为什么它在关闭 SSR 的情况下工作?是因为进口汽车吗?提前致谢!
环顾网络,但没有发现任何有用的东西。
编辑: 评论要求的 nuxt.config.js
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
modules: [
'@nuxtjs/tailwindcss',
[
'@pinia/nuxt',
{
autoImports: [
// automatically imports `defineStore`
'defineStore', // import { defineStore } from 'pinia'
// automatically imports `defineStore` as `definePiniaStore`
['defineStore', 'definePiniaStore'], // import { defineStore as definePiniaStore } from 'pinia'
],
},
],
],
tailwindcss: {
configPath: './tailwind.config.js'
},
build: {
},
// ssr: false, // remove later
runtimeConfig: {
public: {
BASE_URL: process.env.BASE_URL,
API_BASE_URL: process.env.API_BASE_URL,
}
},
})
“Nuxt instance unavailable”的错误消息通常发生在尝试访问 Nuxt 的实例之前或创建之前或销毁之后。当尝试从 Nuxt 的生命周期挂钩之外访问 Nuxt 的上下文或插件时,可能会发生此错误。
在您的情况下,我假设由 Nuxt 插件或模块提供的
useRuntimeConfig()
函数似乎是在 Nuxt 的生命周期挂钩之外调用的。使用 SSR 运行时,此功能可能不可用,因为服务器端渲染进程与客户端渲染进程是分开的,并且无权访问 Nuxt 实例。
解决此问题的一种方法是将
useRuntimeConfig()
调用移动到 Nuxt 生命周期钩子中,例如 asyncData()
或 fetch()
。这将确保在调用该函数时 Nuxt 实例可用。然后,您可以将 API_BASE_URL
作为参数或通过 ApiBridge
操作传递给 nuxtServerInit()
模块。
解决此问题的另一种方法是使用环境变量而不是运行时配置。您可以在
.env
文件或您的托管环境中设置环境变量,并使用 process.env
访问它们。这样,可以在构建过程中设置 API 基本 URL,并将在服务器端和客户端都可用。
关于你为什么在关闭 SSR 的情况下工作的问题,可能是因为在客户端渲染过程中调用了
useRuntimeConfig()
函数,其中 Nuxt 实例可用。然而,这不是一个可靠的解决方案,并且在使用 SSR 运行时可能会导致问题。
一般来说,避免在其生命周期挂钩之外访问 Nuxt 实例并使用适当的依赖注入技术将变量和依赖项传递给您的模块和组件是一个很好的做法。
来回反复之后,我最终将 apiBridge 移动到可组合目录并将其更改为 Nuxt 3 可组合。我认为这是在 Nuxt 3 中应该完成的方式。它看起来确实很整洁,并且完成了工作。
import axios from "axios"
export const useApiBridge = () => {
const runtimeConfig = useRuntimeConfig()
const api = axios.create({
baseURL: runtimeConfig.API_BASE_URL,
withCredentials: true,
});
return {
login: (info) => api.post('/login', {
...info,
}),
register: (info) => api.post('/register', {
...info,
})
}
}
然后在组件和其他文件中我像这样使用它
const apiBridge = useApiBridge()