news 2026/10/16 1:50:05

解读 @firebase/storage-types:从类型变更日志看 Firebase JS SDK 存储模块的演进

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
解读 @firebase/storage-types:从类型变更日志看 Firebase JS SDK 存储模块的演进
  • 开发工具
  • 后端

【免费下载链接】firebase-js-sdk

Firebase Javascript SDK

项目地址:https://gitcode.com/gh_mirrors/fi/firebase-js-sdk
点击查看免费下载

导读

@firebase/storage-types是 Firebase JS SDK 中专门承载 Cloud Storage 公共 TypeScript 类型声明的纯类型包,其 CHANGELOG.md 记录了从 0.3.13 到 0.8.5 的完整版本演进。本文以这份变更日志为线索,结合同仓库的 index.d.ts、public-types.ts 与测试用例,逐条还原每个版本背后的真实代码变更——包括useEmulator/connectStorageEmulator模拟器支持、mockUserToken安全规则测试令牌、StorageError实例判断修复、TypeScript 升级等,帮助读者既看清"改了什么",也明白"为什么改、底层怎么实现"。

注意:根据 README.md,本包不面向直接使用,仅应通过官方firebase包间接使用;当前仓库中它作为@firebase/storage-compat的 peer 依赖存在(见 storage-compat/package.json)。


一、这个包是什么:纯类型包与版本演进全貌

@firebase/storage-types的发布物只有一个文件index.d.ts(见 package.json),它只导出类型、不包含任何运行时逻辑,作用是为 Firebase Storage 的公共 API 提供稳定的 TypeScript 契约。其 peer 依赖为@firebase/app-types@0.x与@firebase/util@1.x(package.json),说明类型定义依赖 app 与 util 两个基础包的类型。

从 CHANGELOG 可以梳理出这条清晰的时间线:

版本类型核心变更
0.3.13Patch允许 Observer 类 API 省略回调(修复 #3224)
0.4.0Minor新增storage().useEmulator()模拟器方法(PR #4346)
0.4.1Patch更新 peerDependencies(修复 #4789)
0.5.0Minor实现 Storage 的mockUserToken并修复 JWT 格式问题(PR #5282)
0.6.0Minor发布模块化 SDK(PR #5345,修复 #5015)
0.6.1 / 0.7.0Patch/MinorTypeScript 升级至 4.7.4(PR #6682 / #6799)
0.8.0Minor修复用户无法用instanceof StorageError判断错误的问题(PR #6974)
0.8.1Patch统一各包repository.url为 NPM 偏好格式(PR #8079)
0.8.2Patch全包 bump 以配合 staging 流程(PR #8237)
0.8.3PatchTypeScript 升级至 5.5.4(PR #8604)
0.8.4 / 0.8.5Patch更新依赖与顶层 devDependencies(PR #9883 / #10293)

可以看到,这个类型包的版本演进与整个 SDK 的架构转型(模块化)、工程基建(TypeScript 版本、依赖管理)以及模拟器生态(emulator、mock token)高度同步。


二、0.3.13:Observer 回调全部可省略

0.3.13 的变更(PR #3224)是"为所有使用 Observer 的 API 更新 TypeScript 类型,允许省略回调"。这对应 index.d.ts 中的StorageObserver<T>:

export interface StorageObserver<T> { next?: NextFn<T> | null; error?: (error: FirebaseStorageError) => void | null; complete?: CompleteFn | null; }

三个回调全部是可选的(?),配合UploadTask.on()的签名(index.d.ts),开发者可以只监听完成、只监听进度,甚至先拿到订阅函数再延迟注册回调。这正是 Firebase Storage 上传任务"观察者模式"的典型用法:next观察进度、error处理失败、complete收尾,三者互不依赖。


三、0.4.0:useEmulator()方法加入类型契约

0.4.0(PR #4346)为 Storage 增加了模拟器支持,对应 index.d.ts 中FirebaseStorage类上的useEmulator方法:

useEmulator( host: string, port: number, options?: { mockUserToken?: EmulatorMockTokenOptions | string; } ): void;

在模块化 SDK 中,这个能力由 api.ts 导出的connectStorageEmulator(storage, host, port, options)提供(useEmulator是 compat 层对它的封装)。其底层实现位于 service.ts 的connectStorageEmulator函数:

export function connectStorageEmulator( storage: FirebaseStorageImpl, host: string, port: number, options: { mockUserToken?: EmulatorMockTokenOptions | string } = {} ): void { storage.host = `${host}:${port}`; const useSsl = isCloudWorkstation(host); if (useSsl) { void pingServer(`https://${storage.host}/b`).catch(() => {}); } storage._isUsingEmulator = true; storage._protocol = useSsl ? 'https' : 'http'; const { mockUserToken } = options; if (mockUserToken) { storage._overrideAuthToken = typeof mockUserToken === 'string' ? mockUserToken : createMockUserToken(mockUserToken, storage.app.options.projectId); } }

几个值得注意的实现细节:

  • 主机拼接:把默认主机firebasestorage.googleapis.com(constants.ts)替换为host:port,所有后续请求都指向模拟器;
  • 协议自适应:普通 localhost 走http;若是 Cloud Workstations 环境(isCloudWorkstation)则强制https并附带一个 cookie 预热请求,这是针对 Firebase Studio 等环境的特殊处理;
  • 令牌注入:传入mockUserToken时写入_overrideAuthToken,后续请求头Authorization: Firebase <token>将使用该令牌;
  • 自动连接:getStorage()内部还会调用getDefaultEmulatorHostnameAndPort('storage'),一旦检测到环境变量配置的模拟器地址就自动连接(api.ts)。

单元测试 service.test.ts 验证了这些行为:设置localhost:1234后host变为localhost:1234、协议为http、请求 URL 匹配http://localhost:1234/...;而传入test.cloudworkstations.dev时协议变为https。


四、0.5.0:mockUserToken与 JWT 格式修复

0.5.0(PR #5282)实现了 Storage 的mockUserToken并修复了 JWT 格式问题。mockUserToken的用途是在单元测试中模拟一个已认证用户,从而测试 Security Rules。它接受两种形式:

  1. 字符串形式:直接作为令牌使用(typeof mockUserToken === 'string'分支);
  2. 对象形式:交给createMockUserToken(mockUserToken, projectId)生成一个无签名的 JWT(alg: "none")。

对象形式的具体构造逻辑在 emulator.ts:使用sub或user_id字段作为用户 ID,默认填充iss、aud、exp(iat + 3600)、firebase.sign_in_provider: 'custom'等字段,再以 base64url 编码的 header/payload 拼接空签名。同时该实现会拒绝已废弃的uid字段并抛出明确提示——这也是 CHANGELOG 中所说"修复 JWT 格式问题"的一部分。类型定义EmulatorMockTokenOptions为({ user_id: string } | { sub: string }) & Partial<FirebaseIdToken>(emulator.ts),并明确uid?: never以在编译期拦截误用。

测试用例验证了两种形式的效果:字符串令牌直接出现在Authorization: Firebase <token>请求头中;对象形式(如{ sub: 'alice' })生成的令牌以eyJhbGciOiJub25lIiwidHlwZSI6IkpXVCJ9.开头,正是{ "alg": "none", "type": "JWT" }的 base64url 编码(service.test.ts)。


五、0.6.0:模块化 SDK 与类型包的分工

0.6.0(PR #5345,修复 #5015)标志着 SDK 全面模块化。在此之前@firebase/storage-types承载的是兼容层(compat)API 的类型;模块化之后,新一代的公开类型定义迁移到了主包 public-types.ts(包含StorageReference、ListOptions、UploadTask、StorageObserver、FullMetadata等),而@firebase/storage-types继续为 compat 层提供兼容类型契约,并在 index.d.ts 中通过declare module '@firebase/component'将storage-compat服务注册进组件依赖注入映射。

这一阶段还体现出一个细节:虽然主包已模块化,useEmulator等旧 API 名称仍保留在类型包中,保证从旧版迁移到新版(例如把firebase.storage().useEmulator(...)换成connectStorageEmulator(storage, ...))时有类型可循、迁移成本可控。


六、0.8.0:StorageError的 instanceof 判断修复

0.8.0(PR #6974,修复 #6944)修复了"用户无法用instanceof StorageError判断错误实例"的问题。这是 JavaScript 继承机制的一个经典陷阱:StorageError继承自FirebaseError,当 TypeScript 编译目标把类编译成 ES5 风格的构造函数时,instanceof可能失效。

修复方法直接体现在 error.ts 的构造函数中:

constructor( code: StorageErrorCode, message: string, private status_ = 0 ) { super( prependCode(code), `Firebase Storage: ${message} (${prependCode(code)})` ); this._baseMessage = this.message; // Without this, `instanceof StorageError`, in tests for example, // returns false. Object.setPrototypeOf(this, StorageError.prototype); }

Object.setPrototypeOf(this, StorageError.prototype)显式修正原型链,使err instanceof StorageError恢复正确结果。同时,StorageError对外暴露了:

  • code:带storage/前缀的错误码(prependCode(code)生成,见 error.ts);
  • customData.serverResponse:服务端返回的原始响应文本;
  • status:对应的 HTTP 状态码;
  • _codeEquals(code):忽略前缀地比较错误码。

类型包侧则对应 index.d.ts 的StorageErrorCode枚举与FirebaseStorageError接口。StorageErrorCode枚举共 24 个错误码,覆盖了共享错误(unknown、object-not-found、bucket-not-found、quota-exceeded、unauthorized等)与 JS 特有错误(invalid-url、invalid-format、no-default-bucket、cannot-slice-blob、server-file-wrong-size、unsupported-environment等),这些枚举值也在 error.ts 中一一对应实现。


七、工程基建类变更:TypeScript 版本与依赖管理

CHANGELOG 后半段的多次 Patch 变更集中在工程基建上:

  • 0.6.1 / 0.7.0(PR #6682 / #6799):TypeScript 升级至 4.7.4;
  • 0.8.1(PR #8079):统一所有包package.json的repository.url为 NPM 偏好的格式;
  • 0.8.2(PR #8237):全包 bump 以配合 staging 发布流程;
  • 0.8.3(PR #8604):TypeScript 升级至 5.5.4,当前 package.json 中devDependencies.typescript即为5.5.4;
  • 0.8.4 / 0.8.5(PR #9883 / #10293):更新依赖与顶层 devDependencies。

由于类型包自身的"测试"就是tsc类型检查(package.json 中test: tsc),TypeScript 版本升级直接影响类型声明的正确性与兼容性——这也解释了为什么类型包会如此频繁地跟随 TS 主版本升级。对于开发者而言,这些变更的意义在于:使用新版 TypeScript 编译自己的项目时,@firebase/storage-types的类型定义能够保持兼容,不会因编译目标差异产生类型错误。


八、类型契约速览:这份.d.ts到底定义了哪些 API

把 index.d.ts 当作一份"接口地图",Storage 类型包的核心类型可以归纳如下:

类型关键字段 / 方法用途
FirebaseStorageref()、refFromURL()、setMaxOperationRetryTime()、setMaxUploadRetryTime()、useEmulator()Storage 服务实例
Referencechild()、put()、putString()、getDownloadURL()、getMetadata()、updateMetadata()、delete()、list()、listAll()对象/路径引用
UploadTaskon()、pause()、resume()、cancel()、then()、catch()、snapshot可观察的上传任务
UploadTaskSnapshotbytesTransferred、totalBytes、state、ref、metadata上传进度快照
SettableMetadatacacheControl、contentType、contentLanguage、customMetadata等可写元数据
UploadMetadata继承SettableMetadata,追加md5Hash上传元数据
FullMetadata继承UploadMetadata,追加bucket、generation、size、downloadTokens等完整元数据
ListOptions/ListResultmaxResults、pageToken/prefixes、items、nextPageToken目录列举
StorageErrorCode24 个storage/*错误码错误分类

值得注意的默认值与上限:ListOptions.maxResults的默认和最大值都是 1000(见 public-types.ts 的文档注释);setMaxOperationRetryTime与setMaxUploadRetryTime的默认值分别是 2 分钟与 10 分钟(constants.ts)。理解这些类型契约,无论做二次封装、编写类型安全的业务代码,还是排查类型报错,都有直接的帮助。


结语

@firebase/storage-types的 CHANGELOG 看起来只是几十行版本记录,但每一条都对应着真实的功能演进:Observer 类型从严格到宽松的 API 设计、模拟器接入从无到有、mockUserToken从实现到 JWT 格式修正、StorageError原型链修复,以及 TypeScript 与依赖基建的持续跟进。透过类型包的视角,可以清晰地看到 Firebase JS SDK 如何在保持 API 兼容的同时持续打磨类型安全与开发体验。若想深入探索,推荐继续阅读 public-types.ts(模块化公开类型)、service.ts(服务与模拟器实现)和 error.ts(错误模型),并结合 service.test.ts 中的单元测试理解各项行为的验证方式。

  • 开发工具
  • 后端

【免费下载链接】firebase-js-sdk

Firebase Javascript SDK

项目地址:https://gitcode.com/gh_mirrors/fi/firebase-js-sdk
点击查看免费下载
上一篇:Qwen1.5-1.8B-Chat-GPTQ-Int8与其他模型对比分析:终极性能评测指南
下一篇:EveryDay 中的 CSS 布局秘籍:Flex、Grid 与响应式设计全攻略

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/16 1:45:11

FaceFusion 换脸实战指南:参数推荐值与排障速查

FaceFusion 换脸实战指南&#xff1a;参数推荐值与排障速查 【免费下载链接】facefusion Industry leading face manipulation platform 项目地址: https://gitcode.com/GitHub_Trending/fa/facefusion FaceFusion 是一个开源的人脸操控平台&#xff0c;核心功能是把一张…

作者头像 李华