Nuxt-Notes icon indicating copy to clipboard operation
Nuxt-Notes copied to clipboard

Nuxt 3 笔记:配置

Open cssmagic opened this issue 1 year ago • 0 comments

配置文件和类型

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 文件,所以实现步骤有些繁琐:

  1. 修改部署脚本,实现在部署阶段把 .env 文件复制到应用目录(/opt/case/xxxxx)下。

  2. 在项目中安装 dotenv 依赖包,以便 pm2 在启动应用时调用。

  3. 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

cssmagic avatar Mar 17 '24 12:03 cssmagic