[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 })

希望对你有所帮助。

相关推荐
翼龙云_cloud1 天前
阿里云渠道商:如何使用弹性伸缩来实现计算资源的弹性配置?
服务器·阿里云·云计算
落笔画忧愁e1 天前
实测:利用腾讯云锐驰型 200M 带宽,搭建无门槛高清视频分发系统
云计算·腾讯云
冬天的风滚草1 天前
揭秘云原生混布资源调度器Koordinator (十五)GPU 信息采集与上报机制
云计算
冬天的风滚草1 天前
揭秘云原生混布资源调度器Koordinator (十三)GPU 资源管理总览
云计算
冬天的风滚草1 天前
揭秘云原生混布资源调度器Koordinator (十四)DeviceShare 调度插件详解
云计算
CodeCaptain1 天前
阿里云ECS上配置Nginx的反向代理
nginx·阿里云·云计算
有谁看见我的剑了?2 天前
VMware OVF Tool 工具安装学习
云计算
故乡de云2 天前
Google Cloud与AWS大数据AI服务对比:2026年企业选型指南
大数据·人工智能·aws
盛夏5202 天前
Docker容器化部署SpringBoot+Vue项目:从零到一在阿里云宝塔面板的实践指南
阿里云·docker·云计算
狐572 天前
2026-01-10-云计算问答题部分整理-期末复习
云计算·期末复习