Nuxt 3 笔记:配置
配置文件和类型
Nuxt 配置 nuxt.config.js
export default defineNuxtConfig({
// 配置项写在这里
})
defineNuxtConfig()这个方法无需手动导入。
运行时配置 runtimeConfig
写入与读取:运行时配置写在 Nuxt 配置中的 runtimeConfig 字段内。在代码中可通过 useRuntimeConfig() 读取这部分配置。
可用范围:通常 runtimeConfig 内的字段只在服务端可读,不过 runtimeConfig.public 内的字段在客户端也是可读的。
可以通过环境变量来覆盖这些运行时配置字段。环境变量的取名似乎就是运行时配置的字段名转换为 PASCAL_CASE 之后加上 NUXT_ 前缀。比如 :
- 运行时配置
apiSecret→ 环境变量NUXT_API_SECRET - 运行时配置
public.apiBase→ 环境变量NUXT_PUBLIC_API_BASE
应用配置 app.config.js
这里定义的配置在构建时可读。不会被环境变量覆盖。
export default defineAppConfig({
title: 'Hello Nuxt',
theme: {
dark: true,
colors: {
primary: '#ff0000',
},
},
})
defineAppConfig()这个方法无需手动导入。
在代码中可通过 useAppConfig() 读取这部分配置。
runtimeConfig 与 “应用配置” 的区别
runtimeConfig:
- 适用场景:私密的或公开的 token,需要在构建后通过环境变量指定。
app.config:
- 适用场景:在构建时就需要确定的公开的 token,不敏感的配置信息,比如主题变量、网站标题等。
更多对比: https://nuxt.com/docs/getting-started/configuration#runtimeconfig-vs-appconfig
构建结果
-
所有
runtimeConfig会打进.output/server/chunks/nitro/config.mjs文件中,也就是说,所有的运行时配置先统一导入到服务端。然后其中的.public再传递给客户端,以确保敏感的runtimeConfig信息不会泄漏到客户端。 -
应用配置会打进
.output/public/_nuxt/entry.xxxxxxxx.js和.output/server/chunks/app/server.mjs文件中,分别是客户端和服务端的入口文件。
外部配置文件
Nuxt 内部用到的各个核心组件的配置都收拢到 nuxt.config.js 里的各个字段了,比如:Nitro、PostCSS、Vite、Webpack。
不过另一些配置文件还是单独存在的,比如:TypeScript、ESLint、Prettier、Stylelint、TailwindCSS、Vitest。
Nuxt 配置
nuxt.config.js的详细配置文档在这里:https://nuxt.com/docs/api/configuration/nuxt-config
疑问
在 utils/*.js 中调用 useAppConfig() 会导致 500 错误:
[Vue Router warn]: uncaught error during route navigation: 23:55:58
Error: nuxt instance unavailable 23:55:58
at Module.useNuxtApp (/Users/cssmagic/Projects/XC/www/node_modules/nuxt/dist/app/nuxt.mjs:165:13)
at Module.useAppConfig (/Users/cssmagic/Projects/XC/www/node_modules/nuxt/dist/app/config.mjs:31:41)
at /Users/cssmagic/Projects/XC/www/utils/seo.js:3:41
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async ViteNodeRunner.directRequest (file:///Users/cssmagic/Projects/XC/www/node_modules/vite-node/dist/client.mjs:285:5)
at async ViteNodeRunner.cachedRequest (file:///Users/cssmagic/Projects/XC/www/node_modules/vite-node/dist/client.mjs:146:14)
at async request (file:///Users/cssmagic/Projects/XC/www/node_modules/vite-node/dist/client.mjs:172:16)
at async /Users/cssmagic/Projects/XC/www/pages/memo/index.vue:9:31
at async ViteNodeRunner.directRequest (file:///Users/cssmagic/Projects/XC/www/node_modules/vite-node/dist/client.mjs:285:5)
试了一下,在 composables/*.js 中也有这个问题。
难道 useAppConfig() 只能在 <script setup> 中调用?那这就大大减少 appConfig 的使用场景了,而且非常不利于逻辑抽象。
更新:在 utils 和组合式函数中的函数内调用 useAppConfig() 就没问题。说明在 Nuxt 的 auto import 阶段还不能调用这个 API。
配置环境变量
开发阶段
不需要额外做什么。因为 Nuxt 3 会在执行 dev, build, generate 脚本时,自动读取项目根目录下的 .env 文件并导出为环境变量,在代码中可通过 process.env.XXXXX 读取。
生产阶段(错误方法)
考虑到 Nuxt 应用在运行阶段不会自动读取 .env 文件,打算在部署阶段自行处理。——首先想到的是方法是手动把 .env 的内容给 pm2 再给 Nuxt 应用。
由于 pm2 还不支持直接读取 .env 文件,所以实现步骤有些繁琐:
-
修改部署脚本,实现在部署阶段把
.env文件复制到应用目录(/opt/case/xxxxx)下。 -
在项目中安装
dotenv依赖包,以便 pm2 在启动应用时调用。 -
在
ecosystem.config.js中,读取.env文件的内容,再使用dotenv.parse()解析为对象,再写入apps[0].env配置项。为什么不直接用
dotenv.config()直接把.env导出为环境变量让 Nuxt 应用使用呢?这个方法在本地(macOS)下是可以的,但在 CentOS 服务器上则不行,Nuxt 应用读到不到环境变量。 ~~这可能是因为 pm2 没有把当前进程的环境变量传递给 Nuxt 应用的进程,可能是 pm2 在不同平台上的运行机制有差异,暂时没有深究。~~ (真正的原因详见下面的 “生产阶段(正确方法)”。)
想到这个方法是因为 Nuxt 3 的官方文档很有误导性,让人以为在生产阶段必须要手动处理。
生产阶段(正确方法)
上述方法应该是可行的。但想到了一个更合理的办法——因为生产阶段也是要构建的,所以在构建阶段把 .env 放到仓库里再进行构建,环境变量就可以生效了。
另外,关于上面所说的 “本地有效,而在 CentOS 服务器上无效” 的问题,发现并不是因为平台差异。其实在本地尝试时,.env 是构建阶段就生效的,而不是由 pm2 在启动应用时注入的。——因为本地的代码仓库内有 .env 文件,而服务器上的代码仓库里没有。——因为 .env 文件本身是被 Git 忽略的。
同时也确认了另一件事:nuxt.config.js 在构建阶段就会处理其内部引用的环境变量(process.env.XXXXX),不论是构建生成的给客户端运行的代码,还是构建生成的给服务端运行的代码。——虽然理论上服务端有能力读取环境变量,但 Nuxt 会在构建时就一视同仁在两端的构建产物里都把环境变量打进去,这也避免了两端行为出现差异的可能性。
相关链接:
- https://nuxt.com/docs/guide/directory-structure/env