[Amplify]项目aws-amplfiy服务旧版本升级v6经验分享

前些天公司发下来给一个项目的aws-amplify服务升级到v6的任务,以下是我的升级经历和总结,希望对你有所帮助。

1. 关于打包 (Webpack4) + Babel 转译的问题

如果你的项目使用 Webpack4 打包,而在代码中直接导入 Amplify v6(或者间接导入带有新语法的模块),因为webpack4不能直接识别一些很新的js语法,而且babel默认不会转译node_modules下的依赖包的文件,导致webpack打包不了,在npm run dev时报错:

复制代码
 error  in ./node_modules/@aws-amplify/core/node_modules/uuid/dist/esm-browser/v4.js

Module parse failed: Unexpected token (9:33)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
|     }
|     options = options || {};
>     const rnds = options.random ?? options.rng?.() ?? rng();
|     if (rnds.length < 16) {
|         throw new Error('Random bytes length must be >= 16');
............

如果出现了这种错误,那么你需要使用到babel等工具来进行转译。

我是vue2项目,可以在vue.config.js中给transpileDependencies项进行配置:

TypeScript 复制代码
// 详情可见https://cli.vuejs.org/zh/config/#transpiledependencies 
module.exports = {
    transpileDependencies: [
        /aws-amplify/
    ],
    .......
}

2. Amplify 配置按照官方文档配置后,启动仍报not configured错误

在我的升级过程中,出现了一个比较诡异的问题 ------ 即使按照官方文档已经配置好了**Amplify.configure(...),** 项目启动后仍报「没有配置」 (not configured)的错误**。**

最终解决方案是:

1、在项目根目录下的 amplify/backend/ 中补充配置文件。由 Amplify CLI 生成,具体内容视项目而定。如果你没有公司在Amplify上的账号,这一步操作通知相关负责人去完成。

2、在前端代码中,使用如下方式初始化 Amplify:

(1)把初始化的代码写到一个单独的 JS (或 TS) 文件里,然后在你的入口文件最顶部导入它:

aws-amplify-init.js:

TypeScript 复制代码
import { Amplify } from 'aws-amplify';
import amplifyconfig from './amplifyconfiguration.json';

Amplify.configure(amplifyconfig);

入口文件.js:

TypeScript 复制代码
import './amplify-init'  // ← 必须放最前面,确保在任何组件/模块之前执行

(2)若你在项目代码中导入 Auth, API, Storage等 Amplify 模块,使用 @aws-amplify/xxx 的路径形式,而不是 aws-amplify/xxxaws-amplify

TypeScript 复制代码
import { signOut, signIn, fetchAuthSession } from '@aws-amplify/auth';

我这里在使用'aws-amplify/xxx'引入时,也会报没有配置(像什么userPool not configured)的问题

TypeScript 复制代码
import { signOut, signIn, fetchAuthSession } from 'aws-amplify/auth';

这个问题目前也不清楚具体原因,可能是由于aws-amplify双包机制(aws-amplify和@aws-amplify) + webpack按package.json解析依赖path导致的。总之不太会是aws-amplify本身的问题。

3. Storage.put → uploadData 的迁移,以及路径差异的问题

在 v6 中,Storage (S3 上传/下载等) 的 API 做了重构。根据官方迁移指南:旧版本使用的是:

TypeScript 复制代码
import { Storage } from 'aws-amplify';

await Storage.put('test.txt', blob);

而在 v6 中,推荐使用新的模块化导入 + 功能 API:

TypeScript 复制代码
import { uploadData, getUrl } from 'aws-amplify/storage';

await uploadData({
  key: 'test.txt',
  data: blob,
});

但是新版本中使用uploadData之后,发现实际请求中,文件上传的路径不知道为何实际传输的文件的路径不一样:

原本: xxxxx/public/fileName

新版本v6使用uploadData: xxxxx/fileName

最后是在传输文件这里对比,补上了缺失的目录后,传输文件的地址才变得正确。 个人猜测可能升级后uploadData的验证和put不一样了,或者和公司在Amplify上的设置有关系还是怎么。但是本人在本次升级中只拿到了前端项目的代码,这些更细节的东西后续就交给公司的测试兄弟和项目经理们去解决了。(o.0)

4. GraphQL / API 的迁移:client 的生成 + subscribe / websocket / header 的改动

v6 对 API / GraphQL 部分也做了重构/优化:模块化导入 + 新的客户端 SDK + 更灵活的授权方式 (authMode) + 更好的 tree-shaking/bundle size 优化

参考链接:
Amplify クライアントを使用したクライアントアプリケーションの構築 - AWS AppSync GraphQL

在graphql()里,订阅实时事件的请求类型使用的是websocket。

在旧版本aws-amplify中,graphql的验证消息会直接补充到url的参数中:

graphql?header=xxxx&payload=e30=

如果你想在v6中也在url上包含这些信息,那么你需要在创建client时添加上header参数:

const client = generateClient({ headers: {......}, })

比如我的项目旧版本中具备两个参数:header、payload

那么我的代码就是:

const client = generateClient({ headers: { header: 'xxxxxx', payload: 'e30=' }, })

补充一点:旧版本的url中存放的是base64转码后的对象 Buffer.from(JSON.stringify(header)).toString('base64')

并且需要补充验证消息。v6创建client时,还要写认证模式 如果你的authMode是'apiKey',那你需要提供apiKey; 如果是'userPool',那你需要提供authToken。并且这个authToken,需要传入的是本次登录的验证消息里面idToken(不用base64转码)

5、signIn()升级和fetchAuthSession()

登录之后(signIn),本次登录的验证内容不再包含在signIn的返回内容中,你需要调用fetchAuthSession来获取本次登录的相关验证信息:

旧版本:

TypeScript 复制代码
await Auth.signIn(userName, passWord).then(res => { 
    console.log('login成功,响应体内容:', res) 
}) 

setJwtToken(res.signInUserSession.accessToken.jwtToken)

新版本:

TypeScript 复制代码
await signIn({ 
    username, password 
}) 

const tokenData = (await fetchAuthSession()).tokens 

if (tokenData) { 
    setJwtToken(tokenData.accessToken.toString()) 
} else { 
    console.error('fetchAuthSession error: User not signed in') 
}

创建client使用到的authToken就是base64转码后的idToken。

idToken的获取:

TypeScript 复制代码
const idToken = (await fetchAuthSession()).tokens.idToken.toString()

创建client:

TypeScript 复制代码
generateClient({ authMode: 'userPool', authToken: idToken })

希望对你有所帮助。

相关推荐
互联网老欣1 天前
2025年保姆级教程:阿里云服务器部署Dify+Ollama,打造专属AI应用平台
服务器·阿里云·ai·云计算·dify·ollama·deepseek
Altair12311 天前
nginx的https的搭建
运维·网络·nginx·云计算
AKAMAI2 天前
从客户端自适应码率流媒体迁移到服务端自适应码率流媒体
人工智能·云计算
G31135422732 天前
从零开始 通义千问大模型本地化到阿里云通义千问API调用
阿里云·云计算
Akamai中国2 天前
提升 EdgeWorker 可观测性:使用 DataStream 设置日志功能
人工智能·云计算·云服务
XINVRY-FPGA2 天前
XCVP1802-2MSILSVC4072 AMD Xilinx Versal Premium Adaptive SoC FPGA
人工智能·嵌入式硬件·fpga开发·数据挖掘·云计算·硬件工程·fpga
孤廖2 天前
终极薅羊毛指南:CLI工具免费调用MiniMax-M2/GLM-4.6/Kimi-K2-Thinking全流程
人工智能·经验分享·chatgpt·ai作画·云计算·无人机·文心一言
伞啊伞2 天前
DR模式部署
云计算
wanhengidc3 天前
云手机性能如何?
运维·服务器·科技·智能手机·云计算