# @aws/durable-execution-sdk-js-eslint-plugin 中文文档

规范地址：https://npmcn.com/package/%40aws/durable-execution-sdk-js-eslint-plugin/

版本：1\.2\.0
npm 元数据更新时间：2026-10-26T03:46:47.729Z
中文译文更新时间：2026-11-07T15:11:59.658Z
软件包许可：Apache-2\.0

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40aws/durable-execution-sdk-js-eslint-plugin
原文对照：https://npmcn.com/package/%40aws/durable-execution-sdk-js-eslint-plugin/?lang=original
项目主页：https://github.com/aws/aws-durable-execution-sdk-js/tree/main/packages/aws-durable-execution-sdk-js-eslint-plugin
源码仓库：https://github.com/aws/aws-durable-execution-sdk-js

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：99.7 kB，22 个文件
- 模块格式：CommonJS
- TypeScript 类型：包内自带
- Node.js 要求：\>=22
- 运行依赖：0 个
- peer 依赖：eslint ^8\.57\.0 \|\| ^9\.0\.0 \|\| ^10\.0\.0
- 首次发布：2025-11-27T16:42:19.022Z
- 最新版本发布：2026-10-26T03:46:47.316Z
- 近 30 天下载量：11128（2026-10-08 至 2026-11-06，npm 官方下载统计）
- 已发布版本数：6（近 12 个月 6 个）

## 中文简介

AWS Lambda 持久函数最佳做法的 ESLint 插件

## 安装

```sh
npm install @aws/durable-execution-sdk-js-eslint-plugin
```

也可以使用：`pnpm add @aws/durable-execution-sdk-js-eslint-plugin`、`yarn add @aws/durable-execution-sdk-js-eslint-plugin`、`bun add @aws/durable-execution-sdk-js-eslint-plugin`

## README

# AWS 持久执行 ESLint 插件

AWS Lambda持久功能的ESLint规则. 他们报告破解回放的密码.

## 如何进行重放

一个能耐的函数通过回放工作. 等待后继续执行死刑时a 调用,重试,或失败,兰布达再次运行 你的处理器从一开始就. SDK然后走过代码,直到上次运行停止:

-   在已经完成的一步中,SDK返回了该步骤所保存的结果. 没错 不再运行步骤的函数 .
-   在第一次未完成的操作中,SDK运行并保存了结果.

因此,一步中的代码运行 当该步骤执行, 和代码外 步骤在每次重播时再次运行.

**一步外的代码必须是决定性的.** SDK识别每个耐用 第一次行动需要上下文,第二次,和 诸如此类。 在重放时, 它匹配每个调用到同一位置的已保存操作 . 鉴于同样的保存结果,您的代码必须按相同的顺序发出相同的呼叫. 任何能给出不同答案的第二次都属于一步之内. 这包括当前时间、随机数字、UUID和API调用结果 变化.

此插件中有两个规则保护此要求 : `no-non-deterministic-outside-step` 财务报告和审定财务报表 `no-closure-in-durable-operations`第三项规则, `no-nested-durable-operations`, (中文(简体) ), 检查操作的耐用性。 第四个规则, `require-durable-operation-in-child-context`,报告一个没有 持久工作。 默认关闭.

## 所需资源

-   ESLint 8.57 或后期,9或10,使用平面配置格式(`eslint.config.js`) (中文(简体) ). CI测试ESLint 8.57,最新9和10. `@typescript-eslint/parser` 8个需要 同样的ESLint版本.
-   节点.js 22或后.
-   TypeScript 文件的解析器, 例如 `@typescript-eslint/parser`。 。 。 .

插件不支持遗留的 eslintrc 格式 。 见 [遗存 eslintrac 配置](https://npmcn.com/package/%40aws/durable-execution-sdk-js-eslint-plugin/#readme-legacy-eslintrc-configuration)。 。 。 .

## 安装

```bash
npm install --save-dev @aws/durable-execution-sdk-js-eslint-plugin @typescript-eslint/parser
```

`@typescript-eslint/parser` 让ESLint读取 TypeScript 。 一个 JavaScript 唯一的工程 不需要这个。 删除 `languageOptions.parser` 线条来自以下示例.

## 使用量

将建议配置添加到您的 `eslint.config.js`它可以实现三项规则 报告代码破解,作为错误重放.

```js
// eslint.config.js
import typescriptParser from "@typescript-eslint/parser";
import durableExecution from "@aws/durable-execution-sdk-js-eslint-plugin";

export default [
  {
    files: ["**/*.ts"],
    languageOptions: { parser: typescriptParser },
  },
  durableExecution.configs["flat/recommended"],
];
```

在共同JS项目中,使用 `require` 相反:

```js
// eslint.config.js
const typescriptParser = require("@typescript-eslint/parser");
const durableExecution = require("@aws/durable-execution-sdk-js-eslint-plugin");

module.exports = [
  {
    files: ["**/*.ts"],
    languageOptions: { parser: typescriptParser },
  },
  durableExecution.configs["flat/recommended"],
];
```

建议配置没有 `files` 设置, 因此它适用于每个文件 ESLint 检查。 为了将它限制在您的持久功能上,将它扩散到您自己的对象中:

```js
{
  ...durableExecution.configs["flat/recommended"],
  files: ["src/handlers/**/*.ts"],
}
```

ESLint 8.57在发现平面配置时使用平面配置 `eslint.config.js` 或者说 `eslint.config.mjs` 文档。 ESLint 9和10总是使用.

### 你自己选规则

以您选中的名称注册插件, 然后打开您想要的规则 。 这个 示例使用名称 `durable`数字 :

```js
// eslint.config.js
import durableExecution from "@aws/durable-execution-sdk-js-eslint-plugin";

export default [
  {
    files: ["**/*.ts"],
    plugins: { durable: durableExecution },
    rules: {
      "durable/no-nested-durable-operations": "error",
      "durable/no-closure-in-durable-operations": "error",
      "durable/no-non-deterministic-outside-step": "warn",
      "durable/require-durable-operation-in-child-context": "warn",
    },
    // languageOptions: { parser: ... } for TypeScript, as above
  },
];
```

### 建议配置中的规则名称

推荐的配置将插件注册为 `@aws/durable-functions`. ESLint (英语) 在输出时显示该名称,并在 `eslint-disable` 注释 :

```ts
// eslint-disable-next-line @aws/durable-functions/no-nested-durable-operations
```

### 遗存 eslintrac 配置

插件无法从 eslintrac 文件装入, 如 `.eslintrc.json`. ESLint (英语) 添加前缀 `eslint-plugin-` 转到 eslintrac 文件的插件名称 然后找那个包裹。 对于这个包裹,它寻找 `@aws/eslint-plugin-durable-execution-sdk-js-eslint-plugin`,不存在. ESLint 10移除了斯林特克.

早期版本的 README 显示 `extends: ["plugin:@aws/durable-execution-sdk-js-eslint-plugin/recommended"]`。这种设置 从来没有工作过。 如果你有项目仍然使用 Eslintrac , 请移动到平地 配置,或遵循 ESLint 的 [移徙指南](https://eslint.org/docs/latest/use/configure/migration-guide)。 。 。 .

导出 `configs.recommended` 是这个配置的后遗症。 没错 已贬值,而且只保留在读其 `rules` 继续工作.

## 规则

头三道规则在 `flat/recommended` 作为错误. `require-durable-operation-in-child-context` 并不是,因为它的代码报告 仍然重播正确。 要使用它,打开它,如显示 [你自己选规则](https://npmcn.com/package/%40aws/durable-execution-sdk-js-eslint-plugin/#readme-choose-the-rules-yourself)。 。 。 .

| 规则 | 报告的内容 |
| --- | --- |
| [`no-nested-durable-operations`](https://npmcn.com/package/%40aws/durable-execution-sdk-js-eslint-plugin/#readme-no-nested-durable-operations) | 在其运行的背景上开始了持久行动 |
| [`no-closure-in-durable-operations`](https://npmcn.com/package/%40aws/durable-execution-sdk-js-eslint-plugin/#readme-no-closure-in-durable-operations) | 在步骤外声明该步骤改变的变量 |
| [`no-non-deterministic-outside-step`](https://npmcn.com/package/%40aws/durable-execution-sdk-js-eslint-plugin/#readme-no-non-deterministic-outside-step) | 一步外的非定型代码, 如时间和随机值 |
| [`require-durable-operation-in-child-context`](https://npmcn.com/package/%40aws/durable-execution-sdk-js-eslint-plugin/#readme-require-durable-operation-in-child-context) (未建议) | 儿童背景,其功能不能使其环境持久运作 |

### `no-nested-durable-operations`

防止在自己的持久操作中使用相同的上下文对象.

一个步骤是一个工作单位,它不能包含其他可持久操作. 到组 操作,在儿童背景下运行 `runInChildContext`,并召唤他们 儿童的背景.

已检查操作 : `step`, (中文(简体) ), `wait`, (中文(简体) ), `waitForCallback`, (中文(简体) ), `waitForCondition`, (中文(简体) ), `parallel`, (中文(简体) ), `map` 财务报告和审定财务报表 `runInChildContext`。 。 。 .

#### QQ 错误

```typescript
const handler = withDurableExecution(
  async (event: any, context: DurableContext) => {
    return await context.step("step1", async () => {
      // Error: Cannot use the same context object inside its own operation
      await context.wait({ seconds: 1 });

      const result = await context.step("step2", async () => {
        return "nested step";
      });

      return result;
    });
  },
);
```

#### 对

```typescript
// Use runInChildContext for nested operations
const handler = withDurableExecution(
  async (event: any, context: DurableContext) => {
    return await context.runInChildContext("block1", async (childCtx) => {
      await childCtx.wait({ seconds: 1 });

      const result = await childCtx.step("step2", async () => {
        return "nested step";
      });

      return result;
    });
  },
);
```

#### 已知的限制

该规则通过查找箭头函数的参数查找上下文 函数表达式,或用于文件中声明的变量。 没有 承认作为函数声明参数的上下文,例如 `async function handler(event, context) { ... }`,所以它没有报告那里. 将处理器写作箭头函数,例如上面的例子,以获取 检查.

### `no-closure-in-durable-operations`

防止在持久操作中修改关闭变量。 阅读结束 允许变量.

步骤的功能不会在回放时再次运行,所以它会改变为 步骤以外的变量不会在重放时发生。 步骤之后的代码 发现一个不同的值 在第一次运行时看到, 这使得代码 非决定性。 为了传递出一步中的值,从一步中返回.

已检查操作 : `step`, (中文(简体) ), `runInChildContext`, (中文(简体) ), `waitForCondition` 财务报告和审定财务报表 `waitForCallback`。 。 。 .

#### QQ 错误

```typescript
const handler = withDurableExecution(
  async (event: any, context: DurableContext) => {
    let a = 2;
    const result = await context.runInChildContext(
      async (childContext: DurableContext) => {
        const stepResult = await childContext.step(async () => {
          // Error: this step does not run again on replay, so this change to 'a' is lost
          a = a + 1;
          return "child step completed";
        });
        return stepResult;
      },
    );
    return result;
  },
);
```

#### 对

```typescript
const handler = withDurableExecution(
  async (event: any, context: DurableContext) => {
    let a = 2;
    const result = await context.runInChildContext(
      async (childContext: DurableContext) => {
        const stepResult = await childContext.step(async () => {
          // Reading 'a' is OK
          const value = a + 1;
          return value;
        });
        return stepResult;
      },
    );
    return result;
  },
);

// Or use local variables
const handler = withDurableExecution(
  async (event: any, context: DurableContext) => {
    const result = await context.runInChildContext(
      async (childContext: DurableContext) => {
        const stepResult = await childContext.step(async () => {
          let a = 2;
          a = a + 1;
          return "child step completed";
        });
        return stepResult;
      },
    );
    return result;
  },
);
```

### `no-non-deterministic-outside-step`

要求非决定性代码在一步内运行. 一步外的代码运行 每次重播时 都要给出同样的答案 一个步骤的结果 被保存,因此重放会读取所保存的值,而不是再次运行调用.

规则规定这些调用在步骤回调之外时:

-   `Math.random()`
-   `Date.now()` 财务报告和审定财务报表 `new Date()` 没有参数
-   `performance.now()`
-   `crypto.randomBytes()` 财务报告和审定财务报表 `crypto.getRandomValues()`
-   名字包含 `uuid`,例如 `crypto.randomUUID()` 或者说 `uuidv4()`

规则检查电话写在哪里 包括帮手的尸体 在步骤外定义的函数。 它还向一个助手报告一个电话 当调用到 帮手在外面一步.

#### QQ 错误

```typescript
const handler = withDurableExecution(
  async (event: any, context: DurableContext) => {
    // Error: this code runs again on every replay, and both values change
    const orderId = crypto.randomUUID();
    const startedAt = Date.now();

    await context.step("charge", async () => chargeCard(orderId));
    return { orderId, startedAt };
  },
);
```

#### 对

```typescript
const handler = withDurableExecution(
  async (event: any, context: DurableContext) => {
    // The step saves these values, so a replay returns the same ones
    const { orderId, startedAt } = await context.step(
      "create-order",
      async () => ({ orderId: crypto.randomUUID(), startedAt: Date.now() }),
    );

    await context.step("charge", async () => chargeCard(orderId));
    return { orderId, startedAt };
  },
);
```

### `require-durable-operation-in-child-context`

要求儿童环境至少对其环境进行一次持久操作.

儿童的背景是: `runInChildContext` 传到它的功能. `map` 将一个传递给每个项目的函数,并且 `parallel` 各递一个 树枝。 当函数时,子上下文会保存其函数的结果 结束。 重放返回以保存结果而不再调用函数 . 因此,这个功能在上下文上不要求持久操作,例如: `step`, (中文(简体) ), `invoke` 或者说 `wait`,仍然重播正确。 它在两个方面与一步不同:

-   当它抛出时,一步来重复它的工作. 默认重试策略最多 6 个 尝试。 子上下文在第一个错误时失败 .
-   大于检查站尺寸限制的结果不适合孩子 上下文中的检查点。 然后SDK在每次重放时再次运行此功能 重建结果.

因此,规则要求你把作品放在一步.

该细则报告这些职能:

-   函数传递到 `runInChildContext`
-   函数传递到 `map`
-   每个分支传递给 `parallel`,作为函数或 `{ name, func }`

#### QQ 错误

```typescript
const handler = withDurableExecution(
  async (event: any, context: DurableContext) => {
    // Error: no durable operation runs on ctx
    await context.runInChildContext("transform", async (ctx) =>
      cheapTransform(event),
    );

    // Error: the same for each item
    await context.map("transform", event.items, async (ctx, item) =>
      cheapTransform(item),
    );
  },
);
```

#### 对

```typescript
const handler = withDurableExecution(
  async (event: any, context: DurableContext) => {
    // A step saves the result, and it retries the work if it throws
    await context.step("transform", async () => cheapTransform(event));

    // A child context that contains a durable operation
    await context.map("transform", event.items, async (ctx, item) =>
      ctx.step("compute", async () => cheapTransform(item)),
    );
  },
);
```

#### 规则如何遵循上下文

该规则跟随上下文进入在同一文件中声明的函数. 没错 当代码通过上下文作为参数时, 例如 `charge(ctx)`,以及 函数被声明为 `function charge() {}` 或者说 `const charge = () => {}`。 。 。 . 该规则不遵循文件再次指定的函数声明 .

当上下文到达它无法读取的代码时, 规则不报告任何信息 。 例如: 一个导入函数,一个方法调用,例如 `service.run(ctx)`,返回值,一个 对象属性、休息参数、上下文前的扩展参数,以及 `arguments`.该代码可以进行持久操作.

#### 已知的限制

`map` 财务报告和审定财务报表 `parallel` 是常用方法名称。 洛达什有 `_.map`比如说。 这么说吧 规则检查 a `map` 或者说 `parallel` 当它知道接收器是一个 持久环境。 接收器必须是下列参数之一:

-   附加说明类型 `DurableContext`,包括诸如 `import type { DurableContext as Ctx }`
-   函数的第二个参数 `withDurableExecution`,内置或 按名称
-   a 的上下文参数 `runInChildContext`, (中文(简体) ), `map` 或者说 `parallel` 函数

规则检查 `runInChildContext` 在任何接收器上,因为名称是特定的 给SDK.

## 为什么是这些规则?

在第一次运行时,在步外重放一次代码,并在每次运行时重放一次 重弹. SDK 只有在每次运行都相同的情况下才能正确恢复执行 同一顺序的持久通话. 以下前两项规则保护这一要求. 第三作保护了被巢操作的结构.

### 在一步之外没有非决定性代码

读取时钟或生成随机值的代码给出了不同的答案 每个运行。 如果运行在一步之外,重放可以计算出一个不同的值 第一次运行是。 一会儿 `if` 语句然后可以取取另一个分支,和代码 和SDK保存的电话不同 将呼叫包成 步骤保存其结果,所以每回放读取相同的值.

### 持久业务没有关闭

一个步骤的功能不会在回放时再次运行. 如果在外部更改变量 步骤,第一个运行看到变化,一个回放不。 后面的代码 步骤,然后在两个运行时使用不同的值。 从 步骤代替,因为 SDK 保存什么步骤返回.

读取关闭变量是安全的,因为它不会改变状态. 只有变异 (派任,递增,递减)有问题.

### 没有嵌入式持久操作

使用与其运行的操作相同的上下文的持久操作会导致 运行时间错误和出乎意料的行为。 SDK 期望分组工作在 儿童环境。 这一规则有助于在开发时抓住这些问题.

### 需要在儿童背景下开展持久行动

儿童环境组织持久行动。 无持久性的儿童背景 操作仍然保存它的结果,所以它可以正确重放。 这就是为什么规则 不在推荐配置中 。 一步步做同样的工作 重复,所以规则 指向一个步骤.

## 许可证

阿帕奇 - 2.0

## 常见问题

### @aws/durable-execution-sdk-js-eslint-plugin 是什么？

AWS Lambda 持久函数最佳做法的 ESLint 插件

### 如何安装 @aws/durable-execution-sdk-js-eslint-plugin？

在项目目录运行 npm install @aws/durable-execution-sdk-js-eslint-plugin，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：eslint（^8\.57\.0 \|\| ^9\.0\.0 \|\| ^10\.0\.0）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @aws/durable-execution-sdk-js-eslint-plugin 支持 TypeScript 吗？

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

### @aws/durable-execution-sdk-js-eslint-plugin 支持 ESM 还是 CommonJS？

以 CommonJS 形式发布，可以直接 require\(\)；在 ES Module 项目中也可以用 import 引入（Node\.js 会把 module\.exports 作为默认导出）。

### @aws/durable-execution-sdk-js-eslint-plugin 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=22。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @aws/durable-execution-sdk-js-eslint-plugin 可以商用吗？

@aws/durable-execution-sdk-js-eslint-plugin 使用 Apache-2\.0 许可。宽松许可：允许商业使用、修改和再分发，并附带明确的专利授权；分发时需保留许可与 NOTICE 文件，修改过的文件要注明改动。以上为概括，不构成法律意见，请以许可原文为准。

### @aws/durable-execution-sdk-js-eslint-plugin 的下载量有多少？

根据 npm 官方下载统计，@aws/durable-execution-sdk-js-eslint-plugin 在 2026/10/08 – 2026/11/06 这 30 天内被下载 11,128 次，日均约 371 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @aws/durable-execution-sdk-js-eslint-plugin 还在维护吗？

最新版本 1\.2\.0 发布于 2026/10/26（12 天前）；至今共发布 6 个版本，其中过去 12 个月发布了 6 个；首次发布于 2025/11/28。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

