Nuxt 3 部署 AWS Amplify 子目录:解决 404 路径问题
2024-12-18 19:53:34
Nuxt 3 应用部署在 AWS Amplify 子文件夹下的路径问题解决
基于 Nuxt 3 开发的应用,需要将其部署至 AWS Amplify 的指定子文件夹,这个过程会出现一些特定的路径问题。这个问题与路由,以及 Nuxt 3 的构建输出配置息息相关。了解如何去分析产生的原因,解决它并不困难。
一、问题解析:根源在何处?
将 Nuxt 3 应用部署到 AWS Amplify 子目录下,例如 /v2
,当访问形如 /v2/validate/xxxx
动态路由时,会出现 404 错误。出错的根源在于 AWS Amplify 的路由处理机制与 Nuxt 3 动态路由的构建输出方式之间的不匹配。当构建的目标目录设置为.dist/v2
且基础路径 baseURL
设置为/v2
时,虽然静态资源可以正确访问,但由 Nitro 处理的服务器端路由,尤其是动态路由[...id].vue
,会出现路径识别问题。
Nuxt 3 构建时会将文件生成到指定目录,即设置的输出目录 .dist/v2
。访问 /v2
可以正常访问,此时请求的是 /v2/index.html
文件。访问 /v2/validate/xxx
时,理论上应该查找 /v2/validate/[...id].html
,然而实际没有这个文件,导致返回 404。这是因为动态路由需要服务器端的支持才能正常渲染。简单讲,就是构建过程不会生成这个文件,服务器又处理不了。
二、解决方案:打通路径障碍
处理这个部署路径问题,思路是调整服务器端的路由处理,使 AWS Amplify 能识别/v2
下的动态路由。结合 nuxt.config.ts
配置与 Amplify 的重定向规则来实现。具体有三种:
方案1: 调整 Nitro 预设和重定向
利用 Nitro 的 aws-amplify
预设可以更精准地匹配 Amplify 的环境。这种方法调整的配置会减少部署步骤中的一些麻烦。
-
调整
nuxt.config.ts
:// https://nuxt.com/docs/api/configuration/nuxt-config export default defineNuxtConfig({ compatibilityDate: '2024-04-03', devtools: { enabled: true }, app: { baseURL: '/v2/', }, nitro: { preset: 'aws-amplify', serveStatic: false, output: { publicDir: './dist/v2', dir: './.amplify-build', }, }, });
将
baseURL
设置为了/v2/
。将构建产物存放在.amplify-build
目录,给 Amplify 使用。/v2
下的静态资源会生成到dist/v2
下,让它可以访问。 -
设置 Amplify 重定向规则 :
AWS Amplify 控制台中找到应用,转到 "Rewrites and redirects" 。修改规则,使其能够正确地进行重写:
- Source address:
</v2/<*>
- Target address:
/v2/index.html
- Type:
200 (Rewrite)
添加这条规则保证所有的请求都可以正常。这条规则作用,将所有
/v2
下的请求都重定向到/v2/index.html
,交由 Nuxt 3 应用进行路由处理。 - Source address:
方案2: 修改构建输出目录并使用自定义构建命令
此种方法对项目结构影响相对较大,需要在根目录下操作,不够方便,可以作为方案一失败后的备选。
-
调整
nuxt.config.ts
:// https://nuxt.com/docs/api/configuration/nuxt-config export default defineNuxtConfig({ compatibilityDate: '2024-04-03', devtools: { enabled: true }, app: { baseURL: '/v2/', }, nitro: { // preset: 'aws-amplify', static: false, output: { publicDir: './dist', dir: './.output', }, }, });
这个方案的关键在于保持输出文件夹与原本类似,然后把 publicDir 设置为
./dist
,同时为了区分把dir
修改为了./.output
. -
修改
amplify/project-config.json
:{ "projectName": "test", "version": "3.1", "frontend": "javascript", "javascript": { "framework": "vue", "config": { "SourceDir": "src", "DistributionDir": "dist/v2", "BuildCommand": "npm run generate && mv dist v2 && mv .output dist", "StartCommand": "npm run dev" } }, "providers": [ "awscloudformation" ] }
注意:这里
"StartCommand": "npm run dev"
,测试环境下可以使用dev
,但是生产环境中不能使用。这个配置的作用是将静态资源打包进 dist/v2 中,Amplify 构建产物也打包进 dist,并且在部署时候识别.
npm run generate && mv dist v2 && mv .output dist
。使用该指令,先运行原本的npm run generate
命令。 然后使用mv
指令修改.output
为dist
,再修改./dist
为dist/v2
. -
配置 Amplify 重定向规则 :
使用与方案 1 中同样的重定向规则配置 Amplify 控制台:
- Source address:
</v2/<*>
- Target address:
/v2/index.html
- Type:
200 (Rewrite)
这条规则跟方案一的目的相同。
- Source address:
方案3: 使用 NITRO_PRESET
环境变量
此方案直接通过设置NITRO_PRESET
,不需要修改配置代码,在Amplify的环境下相对容易维护,但是设置较麻烦,需要频繁更改环境。可以放在方案一跟方案二都失败了再去使用。
-
保留
nuxt.config.ts
原有配置,调整app.baseURL
:
保留nuxt.config.ts
中原有配置,可以仅修改app.baseURL
:// https://nuxt.com/docs/api/configuration/nuxt-config export default defineNuxtConfig({ compatibilityDate: '2024-04-03', devtools: { enabled: true }, app: { baseURL: '/v2/', }, nitro: { // preset: 'aws-amplify', static: false, output: { publicDir: './dist/v2', dir: './dist/v2', }, }, });
-
设置
NITRO_PRESET
环境变量 :在 AWS Amplify 控制台,转到应用的 "Environment variables" 设置。添加一个环境变量:
- Key :
NITRO_PRESET
- Value :
aws_amplify
NITRO_PRESET
为aws_amplify
将会改变 Nitro 构建的行为,适配 Amplify 环境。 - Key :
-
配置 Amplify 重定向规则 :
与上述两种方法相同:- Source address:
</v2/<*>
- Target address:
/v2/index.html
- Type:
200 (Rewrite)
将
/v2
下路由交给/v2/index.html
处理。 - Source address:
三种解决方案在调整后都需要重新部署 。这些配置能正确地将对/v2
下资源的请求路由给 Nuxt 3 应用处理。选择哪个方案,需要根据具体的项目结构和个人习惯做出选择,三个方案最终结果是类似的。三个方案建议按照先后顺序使用,一个方法解决,没有必要继续设置剩下的方案。
注意:不同的 AWS Amplify 的账号环境下,具体配置可能有一些差异,所以一定要结合自己控制台进行部署。另外注意安全方面:不要直接暴露内部文件结构,避免使用过于明显的路径,定期查看服务器日志。