# @fohte/eslint-config 中文文档

规范地址：https://npmcn.com/package/%40fohte/eslint-config/

版本：0\.5\.3
npm 元数据更新时间：2026-10-17T17:29:06.170Z
中文译文更新时间：2026-11-15T03:59:18.740Z
软件包许可：MIT

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

原始 npm 页面：https://www.npmjs.com/package/%40fohte/eslint-config
原文对照：https://npmcn.com/package/%40fohte/eslint-config/?lang=original
源码仓库：https://github.com/fohte/eslint-config

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

- 包体积（解压后）：75.9 kB，44 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- Node.js 要求：\>=20\.19\.0 \|\| \>=22\.13\.0
- 运行依赖：2 个
- peer 依赖：eslint ^9\.0\.0 \|\| ^10\.0\.0，typescript \>=5\.0\.0，@shadcn/lint \>=0\.1\.2，@vitest/eslint-plugin ^1\.0\.0，eslint-config-prettier ^10\.0\.0，eslint-plugin-import-x ^4\.0\.0，@typescript-eslint/parser ^8\.60\.0，eslint-plugin-tailwindcss ^4\.0\.0，@typescript-eslint/eslint-plugin ^8\.60\.0，eslint-plugin-simple-import-sort ^13\.0\.0，@ninoseki/eslint-plugin-neverthrow \>=0\.2\.0，@eslint-community/eslint-plugin-eslint-comments ^4\.0\.0
- 首次发布：2023-12-24T13:17:31.137Z
- 最新版本发布：2026-10-17T17:29:05.717Z
- 近 30 天下载量：2718（2026-10-15 至 2026-11-13，npm 官方下载统计）
- 已发布版本数：27（近 12 个月 21 个）

## 中文简介

Fohte 的 ESLint 配置

## 安装

```sh
npm install @fohte/eslint-config
```

也可以使用：`pnpm add @fohte/eslint-config`、`yarn add @fohte/eslint-config`、`bun add @fohte/eslint-config`

## README

# @fohte/slint-配置

有TypeScript支持的个人ESLint配置包.

## 安装

```bash
npm install --save-dev @fohte/eslint-config

# Install peer dependencies
npm install --save-dev @eslint-community/eslint-plugin-eslint-comments @typescript-eslint/eslint-plugin @typescript-eslint/parser @vitest/eslint-plugin eslint eslint-config-prettier eslint-plugin-import-x eslint-plugin-simple-import-sort

# Optional: If using TypeScript
npm install --save-dev typescript

# Optional: If using the errorHandling option
npm install --save-dev @ninoseki/eslint-plugin-neverthrow
npm install neverthrow

# Optional: If using the tailwind option
npm install --save-dev eslint-plugin-tailwindcss
npm install tailwindcss

# Optional: If using the shadcn option
npm install --save-dev @shadcn/lint
```

## 使用量

`eslint.config.js`数字 :

```javascript
import { config } from '@fohte/eslint-config'

// Basic (JS + TypeScript strict rules)
export default config()

// Alternatively, enable type-checked rules
// (strict-type-checked + strict-boolean-expressions):
// export default config({ typescript: { typeChecked: true } })

// Optionally, ban throw/try-catch and enforce neverthrow Result handling
// (requires typescript.typeChecked: true):
// export default config({
//   typescript: { typeChecked: true },
//   errorHandling: {},
// })

// Optionally, ban raw tracer.startSpan()/startActiveSpan() calls that skip context.with():
// export default config({ opentelemetry: { enabled: true } })

// Optionally, ban Tailwind CSS arbitrary values (e.g. `w-[600px]`),
// steering towards design tokens defined in `@theme` instead:
// export default config({
//   tailwind: { cssConfigPath: 'src/index.css' },
// })

// Optionally, enforce shared component styling rules in selected files:
// export default config({
//   shadcn: { files: ['src/**/*.{jsx,tsx}'] },
// })

// Optionally, ban raw form and button elements in selected files:
// export default config({
//   noRawFormElements: {
//     files: ['app/src/**/*.tsx'],
//     ignores: ['app/src/components/ui/**'],
//   },
// })
```

### 进口政策

`config()` 禁止相对进口`./foo`, (中文(简体) ), `../foo`)和 `@/*` 别名通过 `no-restricted-imports`,并引导两者走向 [节点子路径导入](https://nodejs.org/api/packages.html#subpath-imports) (单位:千美元)`#foo`,在 `imports` 输入 `package.json`) (中文(简体) ). 这个 `@/*` 化名只解析 TypeScript/ bundler 级别,所以一个平地节点/`tsx` 不分享分辨率步骤的运行时间在运行时间失败; `#` 进口由Node自己的模块解析器自行解决,因此这种失败模式不可能发生.

选择退出(例如,不使用 `src/` ,在后缀中覆盖规则 `userConfigs` 引用到 `config()`数字 :

```javascript
export default config(
  {},
  {
    rules: {
      'no-restricted-imports': 'off',
    },
  },
)
```

### `errorHandling` 选项

要求数 `typescript.typeChecked: true`,因为 `neverthrow/must-use-result` 需要类型信息以检测未使用 `Result` 数值.

启用时, 它对所有人适用两个规则 `.ts{,x}` 除测试文件外的文件 :

-   `no-restricted-syntax`: 禁令 `throw` 财务报告和审定财务报表 `try`编号 :`catch`返回 a `Result` 通过 `err()`编号 :`errAsync()` 相反,或使用 `ResultAsync.fromPromise()` 与丢弃的 API 互通,而无需本地 `throw`如果外部SDK的以抛出为基础的合同真的不能这样包起来,则添加一个 `eslint-disable-next-line` 解释为什么:
    
    ```ts
    // eslint-disable-next-line no-restricted-syntax -- interops with an external SDK's throw-based contract
    try {
      return externalSdkCall()
    } catch (error) {
      return err(error)
    }
    ```
    
-   [`neverthrow/must-use-result`](https://www.npmjs.com/package/@ninoseki/eslint-plugin-neverthrow): 禁止抛弃a [`neverthrow`](https://github.com/supermacro/neverthrow) `Result`编号 :`ResultAsync` 不处理它.
    

### `opentelemetry` 选项

当启用时, `no-restricted-syntax` 禁止直接呼叫 `tracer.startSpan()`编号 :`tracer.startActiveSpan()` 总计 `.ts{,x}` 文件,因为两者都能够默默地产生一个无法在孩子执行过程中创建的父跨:

-   `startSpan()` 绝不单独进入主动语境——孩子的间距(例如在这个间距内发射的HTTP呼叫)将不会被嵌入其中,除非呼叫者明确将周围的代码包裹在其中 `context.with(trace.setSpan(context.active(), span), ...)`。 。 。 .
-   `startActiveSpan()`'回调在活动上下文中自动运行,但只用于回调的自身持续时间——将跨度存储到 `end()` 它后来(例如开始和结束在单独的回调中分拆)从活性上下文中从后期代码运行之前放弃.

这只显示为微量后端中错误的出错跨度,而不是运行时出错. 如果两者都不匹配,则添加一个 `eslint-disable-next-line` 解释原因.

与 `errorHandling`,两个选项都配置 `no-restricted-syntax` ——ESLint的平面配置完全取代了规则的设置(而不是将其合并),当两个配置对象为同一个文件设置了相同的规则时,所以 `startSpan`编号 :`startActiveSpan` 选择器合并为 `errorHandling`是因为 `no-restricted-syntax` 输入而不是他们自己的配置。 这意味着 `opentelemetry` 禁用然后共享 `errorHandling`对测试文件的豁免.

### `tailwind` 选项

`cssConfigPath` (Tailwind的 CSS 文件路径) `@theme` (a) 需要指示牌); `files` 默认为全部 `.ts{,x}` 文件,但可以缩小(例如单列波中的单个软件包):

```javascript
export default config({
  tailwind: {
    files: ['web/**/*.ts', 'web/**/*.tsx'], // optional, defaults to all .ts{,x} files
    cssConfigPath: 'web/src/index.css',
  },
})
```

启用时, 它对给定的规则 `files` (测试文件除外):

-   [`tailwindcss/no-arbitrary-value`](https://github.com/francoismassart/eslint-plugin-tailwindcss):禁止任意值(例如:. `w-[600px]`(单位:千美元) `className`编号 :`class` 属性和类名称函数( c)`clsx`, (中文(简体) ), `cn`(见E/CN.4/Sub.2/2002/L.48等)。 向 `@theme` 在您的 CSS 配置中 :
    
    ```css
    @theme {
      --width-panel: 600px;
    }
    ```
    
    ```diff
    - <div className="w-[600px]" />
    + <div className="w-panel" />
    ```
    
-   `no-restricted-syntax`数字 : `no-arbitrary-value` 只检查类属性/功能,所以隐藏在空字符串常数中的括号值(然后插入) `className`)否则会滑出未被发现. 这个规则也抓住了那个案子.
    

喜欢 `opentelemetry`,这个共享其 `no-restricted-syntax` 条目 `errorHandling` (和 `opentelemetry`)而不是悄悄地压倒它,因此所有这三项禁令都在内部共同适用 `tailwind.files`。自 `tailwind.files` 范围可以小于 `errorHandling`编号 :`opentelemetry`默认( 全部) `.ts{,x}` 文件,合并发生于 `tailwind.files`范围: 它外的文件只保留 `errorHandling`编号 :`opentelemetry` 禁止 里面的档案可以完全结合.

### `noRawFormElements` 选项

设定 `files` 以禁止原始 JSX 格式和按钮元素的文档。 测试文件被自动排除; 使用 `ignores` 用于额外排除,例如共享的UI组件:

```javascript
export default config({
  noRawFormElements: {
    files: ['app/src/**/*.tsx'],
    ignores: ['app/src/components/ui/**'],
  },
})
```

这样可以 `fohte/no-raw-form-elements`,哪个标记小写 `<button>`, (中文(简体) ), `<input>`, (中文(简体) ), `<select>`,以及 `<textarea>` 元素,并要求您使用共享的 UI 组件. `<a>` 组件和资本化组件不受影响.

### `shadcn` 选项

安装 `@shadcn/lint` 0.1.2或以后选择加入。 选择所支持的源文件 `files`; 测试文件自动排除,以及 `ignores` 还可增加更多的除外情形:

```javascript
export default config({
  shadcn: { files: ['src/**/*.{jsx,tsx}'] },
})
```

这样可以 `shadcn/no-restyle`, (中文(简体) ), `shadcn/no-inline-styles`, (中文(简体) ), `shadcn/require-static-classes`, (中文(简体) ), `shadcn/no-unknown-classes`,以及 `shadcn/no-raw-colors` 作为错误. `no-restyle` 确认从 `@fohte/ui` 及其子路径,同时允许布局类。 添加线索 `userConfigs` 条目以覆盖或禁用单个规则。 例如, 禁用 `no-restyle` 在保存其他规则的同时,允许:

```javascript
export default config(
  { shadcn: { files: ['src/**/*.{jsx,tsx}'] } },
  {
    files: ['src/components/ui/**'],
    rules: { 'shadcn/no-restyle': 'off' },
  },
)
```

### 内部规则

除了上游预设外,这个配置船还装有本地插件(`fohte`) 用于测试文件和故事书故事文件,并选择用于选择由 `noRawFormElements`。由内建预设启用的规则设定为 `error`;需要明确选项或用户配置的规则如下文所记载.

`fohte/require-story-name` 被注册为 Storybook 故事文件,但默认关闭。 启用后缀 `userConfigs` 条目 :

```javascript
export default config(
  {},
  {
    files: ['**/*.stories.tsx'],
    rules: { 'fohte/require-story-name': 'error' },
  },
)
```

-   `fohte/no-inline-object-in-expect` (测试文件):旗帜 `expect(<object/array literal>).toEqual(...)` (和 `toStrictEqual` 编号 : `toMatchObject`,包括: `await … .resolves` 编号 : `.rejects` 编号 : `.not` 链条,以及 `as const` 编号 : `satisfies` 编号 : `!` 被包裹的文字)。 并标出同一字面别名,通过一个在 `expect()` 电话 直接传递测试中的值, 或将断言分为多个 `expect()` 打电话.
    
    ```ts
    // bad
    expect({ result, calls: spy.mock.calls.length }).toEqual({
      result: 'ok',
      calls: 0,
    })
    
    // bad: aliasing the literal through a variable doesn't escape the rule
    const actual = { result, calls: spy.mock.calls.length }
    expect(actual).toEqual({ result: 'ok', calls: 0 })
    
    // good
    expect(result).toBe('ok')
    expect(spy).not.toHaveBeenCalled()
    ```
    
-   `fohte/no-raw-form-elements` (当 `noRawFormElements` 已配置 : 标记小写 JSX `<button>`, (中文(简体) ), `<input>`, (中文(简体) ), `<select>`,以及 `<textarea>` 要素。 使用共享的 UI 组件代替 .
    
-   `fohte/no-play-in-stories` (故事文件):旗帜 a `play` 函数和 `parameters: { screenshot: { skip: true } }` 用于描述一个故事或其元a(默认导出)。 故事应该通过 `args`编号 :`render` ; 移动行为断言(单击、输入、, `expect` 电话) `.test.tsx` ,使状态成为 `play` 函数用于通过道具设置(例如打开菜单)取而代之(例如. `defaultOpen`) (中文(简体) ). 这也针对一个"故事书"VRT设置,在同一个文件中标出两个故事,其截图为字节-同义(通常是一个未被检测到的视觉错误,例如两个状态进行相同的渲染):一个被跳过的故事没有显示截图,这样检查就永远看不到. 由于故事不能定义 `play`每一个故事的唯一说法就是它的外表 所以 `screenshot.skip` 总是隐藏着这个发现——解决潜在的视觉重复而不是跳过.
    
    ```ts
    // bad: play belongs in a .test.tsx file, not the story
    export const Disabled: Story = {
      args: { disabled: true },
      play: async ({ canvasElement }) => {
        await expect(within(canvasElement).getByRole('checkbox')).toBeDisabled()
      },
    }
    
    // good: the state play used to set up is driven by a prop instead
    export const Disabled: Story = {
      args: { disabled: true },
    }
    ```
    
-   `fohte/require-story-name` (故事文件,默认关闭):需要每个导出的对象故事定义自己的 `name` 属性。 它尊重文字字符串和正则表达式过滤器 `includeStories` 财务报告和审定财务报表 `excludeStories`。如果任一过滤器是动态的,则规则会跳过该文件,因为它无法确定导出什么故事本.
    

## 发展

### 设置

```bash
# Install dependencies
npm install

# Build TypeScript
npm run build

# Watch mode
npm run watch
```

### 脚本

-   `npm run build` - 编译类型脚本文件
-   `npm run watch` - 发展观察模式
-   `npm run lint` - 在源文件中运行 ESLint
-   `npm run test` - 运行建设和涂抹

### 项目结构

```
src/
├── index.ts           # Main export
├── main.ts            # Base ESLint configuration
├── typescript.ts      # TypeScript-specific configuration
├── error-handling.ts  # errorHandling option (throw/try-catch ban, neverthrow enforcement)
├── opentelemetry.ts   # opentelemetry option (startSpan/startActiveSpan ban)
├── no-raw-form-elements.ts # noRawFormElements option (raw JSX element ban)
├── tailwind.ts        # tailwind option (Tailwind arbitrary-value ban)
├── shadcn.ts          # shadcn option (shared component style rules)
└── types/             # Type definitions for untyped packages
```

### 释放进程

这个项目使用 [请放行](https://github.com/googleapis/release-please) 自动发布.

#### 1\. 创建特征分支并作出修改

-   从 `master`
-   更改( 承诺信件不需要遵循任何特定格式)

#### 2\. 创建 PR并合并为主

-   推动您的分支并创建 PR
-   **公关标题必须遵循 [常规武器委员会](https://www.conventionalcommits.org/)**数字 :
    -   `fix:` 用于错误修正( patch 释放)
    -   `feat:` 新特性(小于发布)
    -   `feat!:` 或者说 `fix!:` 用于分解更改(主要发布)
-   审查后, 合并 PR( 只有平面合并)

#### 3\. 自动释放程序

当更改合并为 `master`,请自动释放:

-   创建/更新释放 PR
-   更新软件包中的版本。 json
-   更新变换
-   当发布 PR 合并时 :
    -   创建 GitHub 发布和 git 标签
    -   发布到 npm

### 承诺前虎克

这个项目使用承诺前钩来保证代码质量. 当您执行更改时, 钩会自动运行 .

## 常见问题

### @fohte/eslint-config 是什么？

Fohte 的 ESLint 配置

### 如何安装 @fohte/eslint-config？

在项目目录运行 npm install @fohte/eslint-config，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：eslint（^9\.0\.0 \|\| ^10\.0\.0）、@vitest/eslint-plugin（^1\.0\.0）、eslint-config-prettier（^10\.0\.0）、eslint-plugin-import-x（^4\.0\.0）、@typescript-eslint/parser（^8\.60\.0）、@typescript-eslint/eslint-plugin（^8\.60\.0）、eslint-plugin-simple-import-sort（^13\.0\.0）、@eslint-community/eslint-plugin-eslint-comments（^4\.0\.0）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @fohte/eslint-config 支持 TypeScript 吗？

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

### @fohte/eslint-config 支持 ESM 还是 CommonJS？

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

### @fohte/eslint-config 需要什么版本的 Node\.js？

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

### @fohte/eslint-config 可以商用吗？

@fohte/eslint-config 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @fohte/eslint-config 的下载量有多少？

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

### @fohte/eslint-config 还在维护吗？

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

