@adobe/helix-shared-storage

中文文档
4.0.1发布于 2026/10/27Apache-2.0ES Module构建来源已验证近 30 天下载 1.1万

Helix 项目共享模块 - 存储

中文使用文档
文档目录20 节
  1. 安装
  2. 基本用途
  3. 与预定义的小桶合作
  4. Bucket 操作
  5. 存储对象
  6. 获取对象
  7. 复制对象
  8. 列出对象
  9. 复制目录树
  10. 删除对象
  11. 更新元数据
  12. 配置选项
  13. Bucket 名称映射
  14. 后端选项( 如禁用 R2 镜像)
  15. 重要行为
  16. 自动压缩
  17. 路径化
  18. 元数据信头
  19. 并行操作
  20. 批次删除

螺旋共享 - 存储

存储模块提供了一个统一的后端-不可知界面,用于管理云存储中的对象. Storage 财务报告和审定财务报表 Bucket 配置为可插件 StorageBackend ——这个包船本身没有云SDK;它定义了界面和通用的桶操作(压缩,元数据拷贝/重名代数,深拷贝/去除)上.

默认的 AWS S3( + Cloudflare R2 镜像) 后端活在一个单独的包中, @adobe/helix-shared-storage-s3,大多数消费者会想安装 与这个.

安装

npm install @adobe/helix-shared-storage @adobe/helix-shared-storage-s3

基本用途

现有S3/R2消费者使用 StorageS3,则 Storage 带有默认 S3(+R2)后端的子类预线,导出自 @adobe/helix-shared-storage-s3数字 :

import { StorageS3 as Storage } from '@adobe/helix-shared-storage-s3';

export async function main(req, context) {
  const storage = Storage.fromContext(context);
  const bucket = storage.contentBus();

  const data = await bucket.get('/my/content.json');

  return new Response(data);
}

消费者想要不同的后端(或根本不需要云SDK依赖)构建核心的通用 Storage 直接带有明确 backendFactory 函数 (bucketId, opts) => StorageBackend数字 :

import { Storage } from '@adobe/helix-shared-storage';
import { createDefaultBackendFactory } from '@adobe/helix-shared-storage-s3';

const storage = new Storage({
  backendFactory: createDefaultBackendFactory(process.env),
  log: console,
});

const bucket = storage.bucket('my-bucket-name');
await bucket.put('/path/to/file.txt', 'Hello World', 'text/plain');
const data = await bucket.get('/path/to/file.txt');
storage.close();

与预定义的小桶合作

存储模块为访问常见的螺旋桶提供了方便的方法:

const storage = Storage.fromContext(context);

const contentBucket = storage.contentBus();
const codeBucket = storage.codeBus();
const mediaBucket = storage.mediaBus();
const configBucket = storage.configBus();
const sourceBucket = storage.sourceBus(); // mirroring to a secondary backend disabled by default

Bucket 操作

存储对象

从响应对象存储数据 :

import { Response } from '@adobe/fetch';

const response = new Response('Hello World', {
  headers: {
    'content-type': 'text/plain',
    'cache-control': 'max-age=3600',
  },
});

await bucket.store('/path/to/file.txt', response);

过 { compress: false } 作为第三个参数 store() 以跳过 gzip 压缩 :

await bucket.store('/path/to/file.txt', response, { compress: false });

已经作出的反应 content-encoding: gzip 即使压缩被禁用,也不改变存储方式.

用可选压缩直接存储数据 :

// With compression (default)
await bucket.put('/path/to/file.txt', 'Hello World', 'text/plain', {
  'custom-meta': 'value',
});

// Without compression
await bucket.put('/path/to/file.txt', 'Hello World', 'text/plain', {}, false);

获取对象

获取对象内容 :

const data = await bucket.get('/path/to/file.txt');
if (data) {
  console.log(data.toString());
}

获取元数据对象内容 :

const meta = {};
const data = await bucket.get('/path/to/file.txt', meta);
if (data) {
  console.log('Content:', data.toString());
  console.log('Metadata:', meta);
}

只获取元数据 :

const metadata = await bucket.metadata('/path/to/file.txt');
console.log(metadata);

获取对象头 :

const headers = await bucket.head('/path/to/file.txt');
if (headers) {
  console.log('Content-Type:', headers.contentType);
  console.log('Last-Modified:', headers.lastModified);
}

复制对象

在同一桶内复制 :

await bucket.copy('/source/file.txt', '/destination/file.txt');

元数据操作复制 :

await bucket.copy('/source/file.txt', '/destination/file.txt', {
  renameMetadata: {
    'old-meta-key': 'new-meta-key',
  },
  addMetadata: {
    'additional-meta': 'value',
  },
});

列出对象

列出前缀下的所有对象 :

const { objects } = await bucket.list('path/to/folder/');
objects.forEach((obj) => {
  console.log('Key:', obj.key);
  console.log('Size:', obj.contentLength);
  console.log('Type:', obj.contentType);
  console.log('Modified:', obj.lastModified);
});

以浅析方式列出对象( 只有直接的孩子) :

const { objects } = await bucket.list('path/to/folder/', {
  shallow: true,
  maxItems: 100, // limit result count
});

列表文件夹 :

const folders = await bucket.listFolders('path/to/');
folders.forEach((folder) => {
  console.log('Folder:', folder);
});

复制目录树

通过可选过滤复制整个目录树 :

// Copy all files
await bucket.copyDeep('/source/folder/', '/destination/folder/');

// Copy with filter
await bucket.copyDeep(
  '/source/folder/',
  '/destination/folder/',
  (obj) => obj.contentType === 'text/plain',
);

// Copy with metadata options
await bucket.copyDeep(
  '/source/folder/',
  '/destination/folder/',
  () => true,
  {
    addMetadata: {
      'copied-at': new Date().toISOString(),
    },
  },
);

删除对象

删除单个对象 :

await bucket.remove('/path/to/file.txt');

删除多个对象 :

await bucket.remove([
  '/path/to/file1.txt',
  '/path/to/file2.txt',
  '/path/to/file3.txt',
]);

删除整个目录 :

await bucket.rmdir('/path/to/folder/');

更新元数据

更新现有对象的元数据. meta 可能将自定义、用户定义的密钥和普通密钥混合 系统属性字段名( 如 . contentType)——每个后端识别并应用自己的 适当的子集( 默认的 S3 后端映射) contentType 到对象的 Content-Type 系统属性而不是自定义元数据 :

await bucket.putMeta('/path/to/file.txt', {
  contentType: 'text/html',
  'new-meta-key': 'new-value',
  'updated-at': new Date().toISOString(),
});

putMeta() 完全替换元数据集——任何系统属性字段或自定义密钥不 包含的内容没有保留。 要更新元数据而不意外丢失已有字段, 请使用 getMeta() (单位:千美元) putMeta()- 兼容的对应物 metadata()安全往返:

const meta = await bucket.getMeta('/path/to/file.txt');
meta['updated-at'] = new Date().toISOString();
await bucket.putMeta('/path/to/file.txt', meta);

配置选项

Bucket 名称映射

您可以使用 HELIX_BUCKET_NAMES 环境变量或 bucketNames 选项 :

const storage = new Storage({
  backendFactory,
  bucketNames: JSON.stringify({
    config: 'my-custom-config-bucket',
    code: 'my-custom-code-bucket',
    content: 'my-custom-content-bucket',
    media: 'my-custom-media-bucket',
  }),
});

或使用助手函数 :

import { parseBucketNames } from '@adobe/helix-shared-storage';

const bucketMap = parseBucketNames(process.env.HELIX_BUCKET_NAMES);
console.log(bucketMap.content); // 'helix-content-bus' (default) or custom name

后端选项( 如禁用 R2 镜像)

bucket() 而命名的大巴访问器则使用一个不透明的选项包逐字转发到配置的 backendFactory ——核心不解读. 默认的 S3/ R2 后端 (@adobe/helix-shared-storage-s3)确认 { disableR2: true }数字 :

// Disable R2 for a specific bucket
const bucket = storage.contentBus({ disableR2: true });

R2 镜像是否配置 完全没有,以及任何HTTP/出时/重试调试,都是后端包件问题——见 @adobe/helix-shared-storage-s3是因为 createDefaultBackendFactory 用于它读取的 S3/R2 特定环境变量(CLOUDFLARE_ACCOUNT_ID, (中文(简体) ), HELIX_STORAGE_DISABLE_R2, (中文(简体) ), HELIX_HTTP_CONNECTION_TIMEOUT(见a/c.5/49/70,附件).

重要行为

自动压缩

所有通过 put() 财务报告和审定财务报表 store() 除非明确禁用,否则会用gzip自动压缩。 取回对象时自动解压 get()。 。 。 .

路径化

对象密钥中的铅鞭被自动去除. 两者 /path/to/file.txt 财务报告和审定财务报表 path/to/file.txt 指向同一个对象.

元数据信头

某些 HTTP 头被存储为后端系统属性而非自定义元数据 : cache-control, (中文(简体) ), content-type,以及 expires编辑 last-modified 以密钥作为自定义元数据存储头 x-source-last-modified。 。 。 .

并行操作

向每个后端 a 发送写入操作( put, store, copy, remove, put Meta) MirroringBackend 以平行(如S3 + R2与默认后端)来组成;读取操作只查询主机.

批次删除

每个后端在去除多个对象(如默认的S3/R2后端块为1000组以遵守AWS S3的限制)时,都会拥有自己的分批限制.

版本与发布记录

@adobe/helix-shared-storage 共发布 47 个版本,首次发布于 2024/04/29;过去 12 个月发布了 23 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
4.0.1latest2026/10/2711 天前
4.0.02026/09/171 个月前
3.3.02026/09/072 个月前
3.2.02026/09/072 个月前
3.1.02026/09/072 个月前
3.0.02026/09/012 个月前

关于 @adobe/helix-shared-storage 的常见问题

@adobe/helix-shared-storage 是什么?

Helix 项目共享模块 - 存储

如何安装 @adobe/helix-shared-storage?

在项目目录运行 npm install @adobe/helix-shared-storage,或使用 pnpm add / yarn add / bun add。

@adobe/helix-shared-storage 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/adobe__helix-shared-storage 是否存在。

@adobe/helix-shared-storage 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@adobe/helix-shared-storage 可以商用吗?

@adobe/helix-shared-storage 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@adobe/helix-shared-storage 的下载量有多少?

根据 npm 官方下载统计,@adobe/helix-shared-storage 在 2026/10/05 – 2026/11/03 这 30 天内被下载 10,509 次,日均约 350 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@adobe/helix-shared-storage 还在维护吗?

最新版本 4.0.1 发布于 2026/10/27(11 天前);至今共发布 47 个版本,其中过去 12 个月发布了 23 个;首次发布于 2024/04/29。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。