@fastly/esi

中文文档
0.1.7发布于 2026/02/12TypeScriptES Module零依赖构建来源已验证近 30 天下载 3230

JavaScript的ESI执行,使用现代取取取并流出API.

中文使用文档
文档目录14 节
  1. 使用量
  2. API 密码
  3. EsiTransformStream 构造器
  4. 页:1
  5. 支持的标签
  6. 错误
  7. 后端请求
  8. 最大包含深度
  9. XML 名称间隔
  10. 自定义名称空间前缀
  11. HTML 中的 XML 标记
  12. 问题
  13. 安全问题
  14. 许可证

快速计算 JavaScript 的边缘侧面( ESI)

运行 边边包括(ESI) 在您的快速计算 JavaScript 应用程序的边缘.

使用量

npm install @fastly/esi

设计起来非常容易使用:

/// <reference types="@fastly/js-compute" />
import { EsiTransformStream } from "@fastly/esi";

addEventListener("fetch", (event) => event.respondWith(handleRequest(event)));

async function handleRequest(event) {
  const req = event.request;

  // Perform a backend request
  const url = new URL(req.url);
  const headers = new Headers(req.headers);

  const beresp = await fetch(url, {
    headers,
    backend: 'origin_0'
  });

  // Initialize the ESI Transformation
  const esiTransformStream = new EsiTransformStream(url, headers, {
    fetch(input, init) {
      return fetch(input, { ...init, backend: 'origin_0' });
    },
  });
  
  // Simply use pipeThrough
  const transformedResponse = beresp.body.pipeThrough(esiTransformStream); 

  return new Response(transformedResponse, {
    status: beresp.status,
    headers: beresp.headers,
  });
}

注: @fastly/esi 作为快实验室产品提供。 访问 快速实验室 使用条件.

API 密码

EsiTransformStream 构造器

const esiTransformStream = new EsiTransformStream(url, headers, options);

使用以下数值初始化ESI转换流. 这些值用于处理 esi:include 标记以及提供ESI变量的值.

对于可以预测的结果,传递的值与您用来提出后端请求的值相同. 在大多数情况下,你需要通过的唯一值 options 实值 fetch ——提供 backend 用于 fetch() 产生 esi:include 标签.

  • url - 获取资源的绝对 URL,用于解决相对 URL,以及 用于ESI变量.

  • headers - 信头,将连同由下列原因引起的子请求一起发送: esi:include,作为 以及ESI变量使用.

  • options - 具有下列密钥的对象:

    • fetch(input, init) (可选)

      这个 fetch() 函数随时调用 esi:include 遇到标记 。 如未具体说明 全球 fetch() 函数被使用.

      • 将调用已解决的、所请求的资源的绝对URL,以及 页:1 headers 传递给建筑师,但如果资源是 请求从不同的主机,然后 host 页眉设定为资源所在 请求.
      • 在快速计算中提供此函数的一个常用方法是添加 backend 值为 正在获取。 使用动态后端时不需要这个.
          const esiTransformStream = new EsiTransformStream(url, headers, {
            fetch(input, init) {
              return fetch(input, { ...init, backend: 'origin_0' });
            },
          });
        
    • processIncludeResponse(esiIncludeResult) (可选)

      函数调用后 fetch() 从 esi:include 已经成功。 它与一个物体同名 包含下列密钥:

      • url - 已解析的、绝对的 URL esi:include 标签.
      • headers - 获取请求的资源时使用的 HTTP 信头 esi:include 标签.

        说明: 以上价值与当时一样 fetch 函数被调用. 如果你提供了一个覆盖 fetch 函数导致获取资源 从另一个位置,或使用修改后的标题,这些不反映于上述数值.

      • response - 那个 Response 对象返回 fetch() 电话.

      此函数预计返回 a string,或一个 Promise 决 议 string,哪个 被变压器用来替换整个 esi:include 标记在溪流中. 这种价值是可选的,应只用于先进情况,要小心.

      默认功能递归通过另一个响应 EsiTransformationStream 这样模板就可以调入额外的模板.

    • handleIncludeError(xmlElement) (可选)

      由两个方案要求资源时调用的职能 src 财务报告和审定财务报表 alt (如果提供的话) esi:include 标记已被尝试, 并导致错误 。 该函数可以返回 a string 或一个 Promise 决心 string 用于替换整个 esi:include 标记,或 null。 。 。 .

      如果未指定, 或返回 null 或一个 Promise 决心 null,则 默认行为是丢出 EsiIncludeError 错误.

    • esiPrefix (可选,高级)

      字符串值或 null,用于指定默认的 XML 前缀标识符,以解释为ESI标记. 如果您想要完全压制此功能, 请设置此值为 null。 。 。 . 见 自定义名称空间前缀 详情见下文.

      默认值为 'esi'。 。 。 .

页:1

支持的标签

目前,以下标记作为 说明数字 :

  • esi:包含
  • esi:评论
  • esi: 移动
  • esi:try / esi: 尝试 / esi: 除外
  • esi: 选择 / esi: 当 / esi: 否则
  • esi: 瓦尔

ESI变量在ESI标记的属性中支持. ESI 表达式在 test 属性 esi:when。 。 。 .

此外,还支持 " !-si.- " .

以下标记不支持 :

  • esi: 内置

错误

如果错误来自 esi:include 不处理,或者你处理它并返回 null (通过 handleIncludeError 选项,该流将丢出一个 EsiIncludeError。注意如果发生这种情况 在读取的流中 event.respondWith(),然后平台已经发送 状态代码和信头,并且已经流到客户端。 因此,为时已晚 响应此错误或发送其它状态代码或信头.

如果您想要返回一个替代状态代码, 那你必须流出整个响应到内存, 确保没有出错,然后返回缓冲器.

  const value = new Response(beresp.body.pipeThrough(esiTransformStream));

  let buffer;
  try {
    buffer = await value.arrayBuffer();
  } catch(ex) {
    if(!(ex instanceof EsiIncludeError)) {
      throw ex;
    }

    return new Response(
      'esi:include error',
      {
        status: 500,
      },
    );
  }

  return new Response(
    buffer,
    {
      status: beresp.status,
      headers: beresp.headers,
    },
  );

由于这可能导致一个较长的TTFB,因此处理错误是理想的 esi:include。 。 。 .

后端请求

记住 esi:include 标签将引发后端请求, 因此 它们必须遵守 约束 在平台一级.

最大包含深度

获取的模板 esi:include 标记可递归包括额外 esi:include 标签. 这个库规定了10个深等的限度,然后 EsiIncludeError 将会被扔出.

XML 名称间隔

ESI 标签被定义为生活在 http://www.edge-delivery.org/esi/1.0 名称空间. 这意味着正式地,命名空间需要在标记本身或母元素上声明,例如:

<esi:include src="/bar" xmlns:esi="http://www.edge-delivery.org/esi/1.0"/>

或:

<html xmlns:esi="http://www.edge-delivery.org/esi/1.0">
  <esi:include src="/bar" />
</html>

然而,执行《经济、社会、文化权利国际公约》历来没有明确要求作出这一宣布。 此外, 因为我们必须处理的方式 HTML 中的 XML 标记并不总是能够可靠地找到 xML 标签的父目录。 基于这些原因,此库默认意味着此声明并可供使用 到处都是.

<!-- Works, because xmlns:esi="http://www.edge-delivery.org/esi/1.0" is available by default. -->
<esi:include src="/bar" />

自定义名称空间前缀

如果你想在前缀下提供ESI esi: 而不是,提供它作为 esiPrefix 值当 构建 EsiTransformStream中。如果您正在将此图书馆与其他图书馆结合使用,则可能有所帮助 使用 'esi' 用于自身使用的前缀.

例如,你可以设置这样的变流:

const esiTransformStream = new EsiTransformStream(url, headers, {
  esiPrefix: 'my-esi'
});

那么,如果你有这样的文件,它的各种标记将按描述处理:

<!-- EsiTransformStream knows about my-esi, so this is treated as an ESI include -->
<my-esi:include src="/foo" />
<!-- EsiTransform does not know about esi, so this is not handled -->  
<esi:include src="/bar" />
<!-- Attribute on the tag explicitly sets namespace, so this is treated as an ESI include -->
<esi:include src="/bar" xmlns:esi="http://www.edge-delivery.org/esi/1.0" />

如果您希望完全禁用自动前缀声明,也可以设置值到 null数字 :

const esiTransformStream = new EsiTransformStream(url, headers, {
  esiPrefix: null
});

注意:如果你这样做,那么 EsiTransformStream 将不知道任何 ESI 命名空间,所以您需要指定 文档中的命名空间.

HTML 中的 XML 标记

ESI 标签是 定义为基于 XML 的语言这意味着他们必须跟随 xML 的规则,例如属性引用和匹配关闭标记。 然而,该图书馆的设计目的是 在 HTML 上下文中工作,因此它以下列方式运行 HTML 和 XML 标记:

  • HTML 和 XML 标记在默认名称空间中出现( 没有 XML 前缀) , 则被您视为纯文本 转变。 这包括开口标记和任何属性,以及任何收尾标记.

  • 出现有XML前缀的标记被归类为XML并必须符合XML的规则. 然后说:

    • 属于ESI命名空间的标记由这个库处理和处理.
    • 属于其他命名空间的标记不经过处理即可通过.

如果两种标签的文本内容都包含任何嵌入式标签,那么它们也会按照同一类型进行处理 规则,即只有出现有XML前缀的标记才被视为XML.

我们这样做有几个原因:

  • HTML使用更宽松的一套规则. 例如,HTML定义了不需要关闭标记的标记(例如: input)和可能暗示其关闭标记的标记(例如: p) (中文(简体) ). 这使得快速和 准确确定 HTML 文档的结构.
  • 一些ESI模板由部分HTML元素编写. 例如,“标题”模板可能包含 hTML 元素的打开标记,其匹配的关闭标记存在于"脚"模板中. 与这种 假设, 我们不执行 HTML 标签上的 XML 规则 .

这对高级命名空间的使用产生了一些额外的影响:

  • 这个库不会从默认的命名空间中找到ESI标记,即使它被设定为默认的命名空间. 例如,以下内容虽然在形式上有效,但不会在这个图书馆工作:
<div>
  <!-- include tag in default namespace will be ignored. -->
  <include src="/bar" xmlns="http://www.edge-delivery.org/esi/1.0"/>
</div>
  • 如果你们要宣布 xmlns:<prefix> 如果声明被贴在标签上 就会被忽略 从默认的命名空间。 例如,以下内容虽然在形式上有效,但不会在这个图书馆工作:
<!-- xmlns:esi is ignored because it's on div which is in the default namespace. -->
<div xmlns:esi="http://www.edge-delivery.org/esi/1.0">
  <esi:include src="/foo" /> <!-- Won't be recognized! -->
</div>

在上述两种情况下,采取以下行动:

<div>
  <esi:include src="/foo" xmlns:esi="http://www.edge-delivery.org/esi/1.0" />
</div>

问题

如果你遇到任何与安全无关的错误或意外行为,请 提交问题 使用错误报告模板.

安全问题

请看我们的 警卫 指导如何报告与安全有关的问题.

许可证

麻省理工学院。 。 。 .

版本与发布记录

@fastly/esi 共发布 8 个版本,首次发布于 2023/12/19;过去 12 个月发布了 1 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.1.7latest2026/02/129 个月前
0.1.62025/09/051.2 年前
0.1.52025/01/061.9 年前
0.1.42024/01/302 年前
0.1.32024/01/292 年前
0.1.22024/01/162 年前

关于 @fastly/esi 的常见问题

@fastly/esi 是什么?

JavaScript的ESI执行,使用现代取取取并流出API.

如何安装 @fastly/esi?

在项目目录运行 npm install @fastly/esi,或使用 pnpm add / yarn add / bun add。

@fastly/esi 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@fastly/esi 支持 ESM 还是 CommonJS?

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

@fastly/esi 可以商用吗?

@fastly/esi 使用 未声明 许可。package.json 没有声明许可证。没有许可证的代码默认保留全部权利,商用前请联系作者或查看仓库中的 LICENSE 文件。以上为概括,不构成法律意见,请以许可原文为准。

@fastly/esi 的下载量有多少?

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

@fastly/esi 还在维护吗?

最新版本 0.1.7 发布于 2026/02/12(9 个月前);至今共发布 8 个版本,其中过去 12 个月发布了 1 个;首次发布于 2023/12/19。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。