# @conarti/eslint-plugin-feature-sliced 中文文档

规范地址：https://npmcn.com/package/%40conarti/eslint-plugin-feature-sliced/

版本：2\.0\.1
npm 元数据更新时间：2026-09-18T09:05:32.040Z
中文译文更新时间：2026-11-10T14:46:48.639Z
软件包许可：ISC

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

原始 npm 页面：https://www.npmjs.com/package/%40conarti/eslint-plugin-feature-sliced
原文对照：https://npmcn.com/package/%40conarti/eslint-plugin-feature-sliced/?lang=original
项目主页：https://github.com/conarti/eslint-plugin-feature-sliced#readme
源码仓库：https://github.com/conarti/eslint-plugin-feature-sliced

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

- 包体积（解压后）：180 kB，7 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- Node.js 要求：^18\.18\.0 \|\| ^20\.9\.0 \|\| \>=21\.1\.0
- 运行依赖：3 个
- peer 依赖：eslint \>=9
- 首次发布：2023-06-27T17:45:38.981Z
- 最新版本发布：2026-09-18T09:05:31.745Z
- 近 30 天下载量：56330（2026-10-11 至 2026-11-09，npm 官方下载统计）
- 已发布版本数：24（近 12 个月 15 个）

## 中文简介

特性设计方法插件

## 安装

```sh
npm install @conarti/eslint-plugin-feature-sliced
```

也可以使用：`pnpm add @conarti/eslint-plugin-feature-sliced`、`yarn add @conarti/eslint-plugin-feature-sliced`、`bun add @conarti/eslint-plugin-feature-sliced`

## README

# @conarti/eslint-plugin-feature-scliped (英语)

ESLint规则将密码库保存在地物-切换设计(Feature-Sliced Design)的边界内.

[![npm version](https://img.shields.io/npm/v/@conarti/eslint-plugin-feature-sliced.svg)](https://www.npmjs.com/package/@conarti/eslint-plugin-feature-sliced) [![npm downloads](https://img.shields.io/npm/dm/@conarti/eslint-plugin-feature-sliced.svg)](https://www.npmjs.com/package/@conarti/eslint-plugin-feature-sliced) [![CI](https://github.com/conarti/eslint-plugin-feature-sliced/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/conarti/eslint-plugin-feature-sliced/actions/workflows/ci.yml) [![license](https://img.shields.io/npm/l/@conarti/eslint-plugin-feature-sliced.svg)](https://www.npmjs.com/package/@conarti/eslint-plugin-feature-sliced)

[特色设计](https://fsd.how/) 将前端分割成层、切片和 部分,而且大部分方法都归结为关于哪些文件可以导入哪些其他文件的规则 文档。 此插件执行这些规则 .

FSD 四条规则只读出导入和导出路径. 他们从不解决模块 也不需要 类型信息,因此它们与任何框架、任何捆绑器和任何别名计划合作: `~/shared/ui`, (中文(简体) ), `@/shared/ui`, (中文(简体) ), `@shared/ui`, (中文(简体) ), `$shared/ui` 财务报告和审定财务报表 `src/shared/ui` 都从盒子里明白了. 捆绑的导入排序预设是一个不同的问题: `order` 规则 `eslint-plugin-import-x`,用于解析模块并跟踪您 `import-x/resolver` 设置.

2版本是一个平面配置插件. 默认导出为返回一个已准备好配置的工厂 对象,所以一个完整的FSD设置是一个单调.

## 所需资源

| 所需经费 | 数值 |
| --- | --- |
| ESLint 语录 | 9或更新,仅平面配置(`eslint.config.js`(中文(简体) ) |
| 节点.js | `^18.18.0 || ^20.9.0 || >=21.1.0` |

仍然在ESLint 8或一个遗产上 `.eslintrc` 档案? 留在1.x线上,这条线不变 仍在出版:

```sh
npm i -D @conarti/eslint-plugin-feature-sliced@1
```

## 安装

```sh
npm i -D eslint @conarti/eslint-plugin-feature-sliced
```

JavaScript 工程不需要其他设备 。 导入排序预设基于 `order` 规则 [`eslint-plugin-import-x`](https://github.com/un-ts/eslint-plugin-import-x),作为 a 此软件包的依赖性。 TypeScript 项目需要上方的 TypeScript- aware 剖析器, 因为它 见下一节.

## 快开始

`eslint.config.js` (ESM, 默认值当 `package.json` 已经 `"type": "module"`:

```js
import featureSliced from '@conarti/eslint-plugin-feature-sliced';

export default [
  featureSliced(),
];
```

`eslint.config.cjs` (中文(简体) ). `require` 返回工厂本身:

```js
const featureSliced = require('@conarti/eslint-plugin-feature-sliced');

module.exports = [
  featureSliced(),
];
```

TypeScript 项目. 插件不需要类型信息, 但是 TypeScript 文件仍然需要一个 TypeScript-aware 剖析器, 和任何其他规则一样。 那个解析器是你们的一部分 普通设置, 不是此插件的要求, 因此您已经使用过帮助器, 包括 页:1 `tseslint.config` 来自 `typescript-eslint` 软件包。 下面的例子使用 自行解析器,所以首先安装:

```sh
npm i -D @typescript-eslint/parser
```

```js
import tsParser from '@typescript-eslint/parser';
import featureSliced from '@conarti/eslint-plugin-feature-sliced';

export default [
  {
    files: ['**/*.{ts,tsx}'],
    languageOptions: {
      parser: tsParser,
      sourceType: 'module',
      ecmaVersion: 'latest',
    },
  },
  featureSliced(),
];
```

`featureSliced()` 返回平面配置对象 `name`, (中文(简体) ), `plugins`, (中文(简体) ), `settings` 财务报告和审定财务报表 `rules`,没有 `files` 键,所以它适用于所有ESLint lints. 散开加法 `files` 或者说 任何其它键并范围到源树:

```js
import featureSliced from '@conarti/eslint-plugin-feature-sliced';

export default [
  {
    ...featureSliced(),
    files: ['src/**/*.{ts,tsx}'],
  },
];
```

## 插件检查什么

下面的每一个例子都来自 `tests/fixtures/basic-project`,FSD树 测试套件 结束到每次运行。 其布局 :

```text
src/
  shared/
    lib/format-date.ts
  entities/
    product/
      model/
    session/
      model/
      index.ts
    user/
      api/
      model/
      ui/
      index.ts
    index.ts
  features/
    auth/
      model/
      index.ts
    profile/
      model/
  widgets/
    header/
      ui/
      index.ts
  pages/
    home/
      ui/
      index.ts
  app/
    providers/router.ts
src2/
  entities/
    basket/model/
    cart/
      services/
      ui/
  features/
    checkout/ui/
```

`src/` 以平面默认值嵌入. `src2/` 是第二棵树,倒着 `publicApi: { level: 'segments' }` 财务报告和审定财务报表 `segments: ['services']`,它涵盖了部分层面 检查和自定义段名. `src/entities/index.ts` 这是有目的的: 引用于下 [公共 API](https://npmcn.com/package/%40conarti/eslint-plugin-feature-sliced/#readme-public-api)。 。 。 .

### 层和切片

文件只能从下层导入 。 一层两块之间的导入 除非它们使用 `@x` 说明进一步减少。 单项内导入 切片,在一层没有切片的地层内进口,则被单独放出.

不对, `src/entities/user/model/imports-features-upward.ts`数字 :

```ts
import { loginUser } from 'src/features/auth';
```

> 您不能将图层“ 特性” 导入“ 实体”( 共享 - > 实体 - > 特性 - > 部件 - > 页面 - > 进程 - > app)

没错, `src/features/auth/model/uses-entities-public-api.ts`数字 :

```ts
import { createUser } from 'src/entities/user';
```

只类型进口在默认情况下免除,所以向上 `import type` 继续有效, `src/entities/user/model/type-only-upward-import.ts`数字 :

```ts
import type { AuthState } from 'src/features/auth';
```

动态 `import()` 表达式也会被检查 .

### 绝对和相对路径

在一个切片内部,或者在一个没有切片的地层内,进口必须是相对的. 横跨多层 必须绝对.

不对, `src/entities/user/ui/absolute-inside-slice.ts`数字 :

```ts
import { createUser } from 'src/entities/user/model/create-user';
```

> 一定有相对的路径

不对, `src/widgets/header/ui/relative-cross-layer-import.ts`数字 :

```ts
import { createUser } from '../../../entities/user';
```

> 一定有绝对的路径

没错, `src/entities/user/ui/user-card.ts` 财务报告和审定财务报表 `src/pages/home/ui/home-page.ts`数字 :

```ts
import { createUser } from '../model/create-user';
```

```ts
import { Header } from 'src/widgets/header';
```

### 公共 API

另一片只能通过它自己的 `index` 文档。 检查的深度取决于 `level`默认时 `'slices'` 规则报告一个导入到已知的 再来一分 文件直接坐落在切片根外的任何片段(导入 `src/entities/user/helper`,例如,固定不包含),不报告在该 级别 `level: 'segments'` 它是一个 `unknown-segment`。 。 。 .

不对, `src/pages/home/ui/deep-import-into-slice.ts`数字 :

```ts
import { UserCard } from 'src/entities/user/ui/user-card';
```

> 绝对进口只允许从公共api(“弧/实体/用户”)进口

规则附带一个建议, `Remove the "ui/user-card"`,该重写路径 `src/entities/user`。 。 。 .

层本身不能有公共API,所以 `index` 文件直接坐落在一层是 无论它包含什么。 不对, `src/entities/index.ts`数字 :

```ts
export { createUser } from './user';
```

> 层公共 API 不允许 。 它在建筑和实际上都有害(代码分割)

### 交叉区再出口

切片的一部分不得再从兄弟部分出口. 只有再出口声明 (单位:千美元)`export { x } from '...'`, (中文(简体) ), `export type { x } from '...'`, (中文(简体) ), `export * from '...'`)被审视.

不对, `src/entities/user/model/index.ts`数字 :

```ts
export { fetchUser } from '../api';
```

> 段"模型"不应从兄弟段"api"再出口. 将再出口移动到切片公共API.

建议重写 `'../api'` 改为 `'..'`切片公开API.

没错, `src/entities/session/index.ts` 财务报告和审定财务报表 `src/entities/session/model/index.ts`数字 :

```ts
export { sessionToken } from './model';
```

```ts
export { sessionToken } from './session-token';
```

### 进口订单

外部包在层导入前出现, 层从层的顶端排序 降为 `shared`。 。 。 .

不对, `src/widgets/header/ui/wrong-import-order.ts`数字 :

```ts
import { createUser } from 'src/entities/user';
import axios from 'axios';
```

> `axios` 进口应在导入 `src/entities/user`

对:

```ts
import axios from 'axios';
import { createUser } from 'src/entities/user';
```

## 配置

### 工厂选项

```js
featureSliced(options);
```

| 选项 | 类型 | 默认 | 它会做什么 |
| --- | --- | --- | --- |
| `severity` | `'error'` 或者说 `'warn'` | `'error'` | 为FSD四条规则的发情. 每个规则都可以推翻它。 导入排序预设不受影响: 它总是带有 `error`。 。 。 . |
| `layers` | 数组 `string` 或者说 `{ name, hasSlices }` | `shared` (没有切片), `entities`, (中文(简体) ), `features`, (中文(简体) ), `widgets`, (中文(简体) ), `pages`, (中文(简体) ), `processes`, (中文(简体) ), `app` (没有切片). `processes` 为相容性而保留,尽管FSD的光谱使其贬值. | 分层分层,最下层第一. |
| `segments` | `string[]` 或者说 `{ replace: string[] }` | `ui`, (中文(简体) ), `model`, (中文(简体) ), `lib`, (中文(简体) ), `api`, (中文(简体) ), `config`, (中文(简体) ), `assets` | 分节名. 数组扩展默认值, `{ replace }` 替换它们. |
| `layersSlices` | `false` 或选项对象 | `{}` (规则) | 备选方案 `layers-slices`。 。 。 . |
| `absoluteRelative` | `false` 或选项对象 | `{}` (规则) | 备选方案 `absolute-relative`。 。 。 . |
| `publicApi` | `false` 或选项对象 | `{}` (规则) | 备选方案 `public-api`。 。 。 . |
| `noCrossSegmentReexport` | `false` 或选项对象 | `{}` (规则) | 备选方案 `no-cross-segment-reexport`。 。 。 . |
| `sortImports` | `false`, (中文(简体) ), `'recommended'`, (中文(简体) ), `'with-newlines'`, (中文(简体) ), `'with-type-group'`, (中文(简体) ), `'with-newlines-and-type-group'` | `'recommended'` | 哪个导入排序预设以启用,或 `false` 完全不录. |

将图层和片段名称以不敏感方式进行比较.

### 规则选项

每个规则都接受下面标记的键. 规则未知的密钥是类型错误 TypeScript, 在 JavaScript 中被默默忽略, 因为规则计划不关闭 关闭 `additionalProperties: false`。 。 。 .

| 选项 | 规则 | 类型 | 默认 | 它会做什么 |
| --- | --- | --- | --- | --- |
| `severity` | 全部四个 | `'error'` 或者说 `'warn'` | 工厂 `severity` | 只有这个规则才重要. |
| `ignoreImports` | 全部四个 | `string[]` | `[]` | 跳过导出与其中之一相匹配的规格 . |
| `ignoreFiles` | 全部四个 | `string[]` | `[]` | 跳过路径符合其中之一的文件 . |
| `allowTypeImports` | `layers-slices` | `boolean` | `true` | 从图层检查中豁免只输入类型 . |
| `level` | `public-api` | `'slices'` 或者说 `'segments'` | `'slices'` | 公众API检查有多深. |

实例:

```js
import featureSliced from '@conarti/eslint-plugin-feature-sliced';

export default [
  featureSliced({
    severity: 'warn',
    publicApi: {
      severity: 'error',
      level: 'segments',
    },
    layersSlices: {
      allowTypeImports: false,
    },
  }),
];
```

### 严重性

`severity` 设置级别 `layers-slices`, (中文(简体) ), `absolute-relative`, (中文(简体) ), `public-api` 财务报告和审定财务报表 `no-cross-segment-reexport` 一次; 规则本身 `severity` 胜过它。 移民的时候 现有代码库, `'warn'` 保持建筑绿色 并且仍然表面 每一个违反.

导入排序预设总是带 `error`,因为预设是一个完整的规则条目 而不是一套选择。 要更改其级别, 请添加一个仅覆盖的后置配置对象 严重性。 ESLint 平面配置保留了此情况下较早条目的选项, 所以预设 保持原状:

```js
import featureSliced from '@conarti/eslint-plugin-feature-sliced';

export default [
  featureSliced(),
  {
    rules: {
      '@conarti/feature-sliced/import-order': 'warn',
    },
  },
];
```

### 禁用规则

通过 `false` 对于规则设置它 `off`。通过 `sortImports: false` 删除导入顺序 全部从配置中输入,这是当另一个排序者拥有导入命令时您想要的.

```js
import featureSliced from '@conarti/eslint-plugin-feature-sliced';

export default [
  featureSliced({
    absoluteRelative: false,
    noCrossSegmentReexport: false,
    sortImports: false,
  }),
];
```

捆绑排序与其他导入排序器相冲突 。 如果你的配置已经运行 `import-x/order`, (中文(简体) ), `import/order`, (中文(简体) ), `simple-import-sort` 或者说 `perfectionist/sort-imports`双方之一关闭, 否则他们俩会争吵的.

### 忽略导入和文件

两种选择都采用 [缩写](https://github.com/micromatch/picomatch) 肿块,但都是相配的 反对不同的字符串 :

-   `ignoreImports` 与输入的规格完全匹配,所以 模式看起来像导入.
-   `ignoreFiles` 匹配到文件被嵌入的绝对路径,它始于 文件系统的根而非您的项目 。 这就是为什么这些模式必须从 `**/`。 。 。 .

```js
import featureSliced from '@conarti/eslint-plugin-feature-sliced';

export default [
  featureSliced({
    layersSlices: {
      ignoreImports: ['@/entities/legacy', '**/vendor/**'],
      ignoreFiles: ['**/src/legacy/**/*'],
    },
    publicApi: {
      ignoreFiles: ['**/*.stories.tsx'],
    },
  }),
];
```

### 自定义层

`layers` 是从最低层到最高层。 纯字符串表示 一个有切片的图层;一个对象允许您说其他的。 数组取代默认值, 所以列表 您的工程所用的每层, 包括您所保留的 FSD .

```js
import featureSliced from '@conarti/eslint-plugin-feature-sliced';

export default [
  featureSliced({
    layers: [
      { name: 'shared', hasSlices: false },
      'entities',
      'domain',
      'features',
      'widgets',
      'pages',
      { name: 'app', hasSlices: false },
    ],
  }),
];
```

每项规则对列表所做的:

-   `layers-slices` 从顺序中得出等级,并在其信息中指定整个顺序. 层与 `hasSlices: false` 永远不会触发切片切片检查.
-   `absolute-relative` 用途 `hasSlices` 决定路径是否停留在一个单元内:在一层 不切整层计算为一个单位,所以内部的进口必须是相对的.
-   `public-api` 用名称在路径中查找图层和切片,并发现 `index` 文件直接放在一层.
-   `no-cross-segment-reexport` 只看有切片的地层.
-   导入排序预设按反向顺序每层构建一个路径组, 所以最上层 首先排序.
-   这个 `@x` 字面名称上的交叉输入标记 `entities` 忽略此列表 完全没有。 重命名这个层 里面的每一个交叉输入 都变成了普通的违反.

列表中不包含的名称根本不是一个图层 。 一条没有已知地层的路径是左侧的 单独使用全部四个 FSD 规则, 即 npm 包的导入保持沉默; 导入排序 预设仍然看到它们,并将其归档到 `external`。 。 。 .

### 自定义段

数组添加默认名称( N)`ui`, (中文(简体) ), `model`, (中文(简体) ), `lib`, (中文(简体) ), `api`, (中文(简体) ), `config`, (中文(简体) ), `assets`),同时 `{ replace: [...] }` 丢弃默认值,只使用您列出的内容.

```js
import featureSliced from '@conarti/eslint-plugin-feature-sliced';

export default [
  featureSliced({
    segments: ['services', 'hooks', 'i18n'],
    publicApi: { level: 'segments' },
  }),
];
```

```js
import featureSliced from '@conarti/eslint-plugin-feature-sliced';

export default [
  featureSliced({
    segments: { replace: ['ui', 'model', 'services'] },
  }),
];
```

片段列表用于 `public-api`时 `level: 'segments'` 位于扇形的文件夹 未列入清单的职位报告为: `unknown-segment`,通过路径分析 `layers-slices` 依靠从片段分出一分 向插件教授自定义 区段因此从中去除假阳性 `public-api` 从 `layers-slices`。 。 。 .

已知所限. 两个规则从来不读 `segments` 选项,并将片段名称匹配到 而非内建列表, 因此在一个自定义分区的工程中, 指定了它们对于某一分区的位置的想法 开始与其他规则不同 :

-   `absolute-relative` 用内置列表解决路径的切片, 所以绝对导入 当切片使用自定义片段名称时,不报告该片段。 见 [问题37](https://github.com/conarti/eslint-plugin-feature-sliced/issues/37)。 。 。 .
-   `no-cross-segment-reexport` 匹配同一内置列表中的兄弟区段名称。 见 [问题35](https://github.com/conarti/eslint-plugin-feature-sliced/issues/35)。 。 。 .

### 导入排序预设

所有四个预设都具有相同的字母顺序(升起、大小写不敏感)和相同的层 路径组。 它们只在空白行以及类型进口是否获得自己的一组方面有所不同:

| 预设 | 组之间的空行 | 类别进口的单独类别 |
| --- | --- | --- |
| `'recommended'` | 没有 | 没有 |
| `'with-newlines'` | 对 | 没有 |
| `'with-type-group'` | 没有 | 对 |
| `'with-newlines-and-type-group'` | 对 | 对 |

组合命令是 `builtin`, (中文(简体) ), `external`, (中文(简体) ), `internal`,则 `parent`, (中文(简体) ), `sibling` 财务报告和审定财务报表 `index`编辑 `internal` 组 持有 FSD 层, 从层次的上到下排序 : `app`, (中文(简体) ), `processes`, (中文(简体) ), `pages`, (中文(简体) ), `widgets`, (中文(简体) ), `features`, (中文(简体) ), `entities`, (中文(简体) ), `shared`组合 页:1 `type` 组合 `internal` 财务报告和审定财务报表 `parent`。 。 。 .

默认情况下排序的文件 `'recommended'` 预设。 这不是固定的一部分,但它 有形状的 `src/app/providers/router.ts`:它坐落在最上层,这样它可能到达 下方的每一层, 和两个相对进口留在里面 `app`,没有切片:

```ts
import path from 'node:path';
import axios from 'axios';
import { HomePage } from 'src/pages/home';
import { Header } from 'src/widgets/header';
import { loginUser } from 'src/features/auth';
import { createUser } from 'src/entities/user';
import { formatDate } from 'src/shared/lib/format-date';
import { routes } from '../routes';
import { withAuth } from './with-auth';
```

选择一个预设 `sortImports`,修改其水平,如下所示 [严重性](https://npmcn.com/package/%40conarti/eslint-plugin-feature-sliced/#readme-severity),或者放弃 与 `sortImports: false`。 。 。 .

### 高级: 直接使用插件对象

工厂是方便. 如果你愿意自己写这三块,请输入 插件对象和规则名称并用手电线连接它们.

这个 `settings['@conarti/feature-sliced']` 密钥是可选的 : 省去它, 规则会回到 默认的地层和地段。 供应 `layers` 和它必须以正常的形式,一种 对象为 `name` 财务报告和审定财务报表 `hasSlices` 每个条目,因为规则 采取阵列是它是什么和 跳过工厂的正常化 里面的平板字符串不被理解,层层 列出无声的降解.

```js
import { plugin, RULE_NAMES } from '@conarti/eslint-plugin-feature-sliced';

export default [
  {
    name: 'feature-sliced/manual',
    plugins: {
      '@conarti/feature-sliced': plugin,
    },
    settings: {
      '@conarti/feature-sliced': {
        layers: [
          { name: 'shared', hasSlices: false },
          { name: 'entities', hasSlices: true },
          { name: 'features', hasSlices: true },
          { name: 'widgets', hasSlices: true },
          { name: 'pages', hasSlices: true },
          { name: 'processes', hasSlices: true },
          { name: 'app', hasSlices: false },
        ],
        segments: ['services'],
      },
    },
    rules: {
      [RULE_NAMES.LAYERS_SLICES]: ['error', { allowTypeImports: true }],
      [RULE_NAMES.ABSOLUTE_RELATIVE]: ['error', {}],
      [RULE_NAMES.PUBLIC_API]: ['error', { level: 'segments' }],
      [RULE_NAMES.NO_CROSS_SEGMENT_REEXPORT]: ['warn', {}],
    },
  },
];
```

完整的出口清单:

| 导出 | 仁爱 | 这是什么 |
| --- | --- | --- |
| `default` | 函数 | 工厂,价值与 `createPlugin`。 。 。 . |
| `createPlugin` | 函数 | 从上面的选项构建平面配置对象. |
| `plugin` | 对象 | 原始的 ESLint 插件 : `meta` 加号 `rules`。 。 。 . |
| `PLUGIN_NAME` | 字符串 | `'@conarti/feature-sliced'`,在 `plugins`, (中文(简体) ), `settings` 和规则ids. |
| `RULE_NAMES` | 对象 | 五个完全合格的规则标识. |
| `layers` | 数组 | 堕地. FSD 层名,为相容性保留. |
| `segments` | 数组 | 堕地. FSD 段名, 为兼容性而保留 . |
| `Severity`, (中文(简体) ), `Layer`, (中文(简体) ), `Segment`, (中文(简体) ), `ImportOrderConfigName`, (中文(简体) ), `TypedFlatConfigItem` | 类型 | 选项和返回配置的脚本类型. |

`layers` 财务报告和审定财务报表 `segments` 只为常数。 规则从设置中取出他们的列表 工厂写,所以读取或重新指定这些出口 没有什么变化.

## 与 `@x`

FSD 允许一个实体通过明确、单向的交叉输入依赖另一个实体,即 [用于交叉进口的公共 API](https://fsd.how/docs/reference/public-api/#public-api-for-cross-imports)。 。 。 . 导入切片在路径中被命名,因此仅从导入即可看出依赖性.

插件只识别包含一个图层的路径上的标记 `entities`, (中文(简体) ), 不管怎么样 `layers` 选项为 `entities/<source>/@x/<target>`,仅接受 何时 `<target>` 是进行导入的文件的切片. `absolute-relative` 对待这样的 {\\fn黑体\\fs22\\bord1\\shad0\\3ahbe\\4ah00\\fscx67\\fscy66\\2chffffff\\3ch808080}然后就离开它 `public-api` 时间 `level: 'segments'` 免除了它的责任 未知分区检查 .

有效, `src/entities/user/model/valid-cross-import.ts`。导入文件的地址是 `user` 切片和路径结束于 `@x/user`数字 :

```ts
import { sessionId } from 'src/entities/session/@x/user';
```

无效, `src/entities/product/model/invalid-cross-import.ts`中的相同路径 `product` 切片 :

```ts
import { userRef } from 'src/entities/session/@x/user';
```

> 交叉导入“ session/@x/user” 只允许从切片“ user” 中导入

目标切片不能跟着 类似路径 `src/entities/session/@x/user/types` 不是一个 交叉输入,然后回到普通的切片切片和公开API检查.

## 规则

使用 ESLint 的固定模式可修复,参见 [ESLint 命令行接口](https://eslint.org/docs/latest/use/command-line-interface)

qq提供编辑建议,一次应用一次,从未批量使用

| 规则 | 说明 | 🔧 | 💡 |
| --- | --- | --- | --- |
| [`@conarti/feature-sliced/layers-slices`](https://npmcn.com/package/%40conarti/eslint-plugin-feature-sliced/src/rules/layers-slices/README.md) | 检查层导入 |  |  |
| [`@conarti/feature-sliced/absolute-relative`](https://npmcn.com/package/%40conarti/eslint-plugin-feature-sliced/src/rules/absolute-relative/README.md) | 检查绝对路径和相对路径 |  |  |
| [`@conarti/feature-sliced/public-api`](https://npmcn.com/package/%40conarti/eslint-plugin-feature-sliced/src/rules/public-api/README.md) | 检查从公共 api 导入模块 |  | 💡 |
| [`@conarti/feature-sliced/no-cross-segment-reexport`](https://npmcn.com/package/%40conarti/eslint-plugin-feature-sliced/src/rules/no-cross-segment-reexport/README.md) | 检查同一片块内的交叉再出口 |  | 💡 |
| [`@conarti/feature-sliced/import-order`](https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/order.md) | 排序导入 `order` 规则 `eslint-plugin-import-x` fSD 层预配置 | 🔧 |  |

已知的限制: `public-api` 检查一个 `index` 直接放在层上的文件不会 当项目坐落在一个名称以点开头的目录下时起火. 见 [问题34](https://github.com/conarti/eslint-plugin-feature-sliced/issues/34)。 。 。 .

## 从 1.x 移动

| 1.x 运算 | 2.x 数据 |
| --- | --- |
| `.eslintrc`页:1 | `eslint.config.js`,仅限 ESLint 9 平面配置 |
| `"extends": ["plugin:@conarti/feature-sliced/recommended"]` | `featureSliced()` |
| `"extends": ["plugin:@conarti/feature-sliced/rules"]` | `featureSliced({ sortImports: false })` |
| `"plugins": ["@conarti/feature-sliced"]` 加上手写 `rules` | 传播 `featureSliced()`,或使用 `plugin` 财务报告和审定财务报表 `RULE_NAMES` 显示在“高级”下 |
| `eslint-plugin-import` 安装在插件旁 | 没有额外的安装, `eslint-plugin-import-x` 船舶作为附属物 |
| `@conarti/eslint-plugin-feature-sliced/import-order` 子路径及其四个配置 | 页:1 `sortImports` 选项,并带有相同的四个预设名称 |
| `import/order` 规则d | `@conarti/feature-sliced/import-order` 规则d |
| `ignorePatterns` 规则选项 | `ignoreImports` |
| `ignoreInFilesPatterns` 规则选项 | `ignoreFiles` |
| 按规则写出的严重程度 | 页:1 `severity` 选项,加上每条规则 `severity` |
| 固定的 FSD 层名 | 页:1 `layers` 选项,使用 `hasSlices` 每层 |
| 固定的 FSD 片段名称 | 页:1 `segments` 选项、扩展或替换 |
| 三个规则 | 4 FSD 规则加捆绑 `import-order`,以及新的 `no-cross-segment-reexport` 默认在 `error` |
| 无交叉进口标记 | `@x` 交叉进口 `layers-slices`, (中文(简体) ), `absolute-relative` 财务报告和审定财务报表 `public-api` |

节点18.18或更新的也需要。 1.x线在npm上作为 `@conarti/eslint-plugin-feature-sliced@1` 用于尚不能移动的项目.

## 发展

```sh
npm ci
npm run test:run      # vitest, unit suites plus the fixture integration test
npm run lint          # eslint on the repo itself
npm run type-check    # tsc, no emit
npm run knip          # unused files, exports and dependencies
npm run build         # tsup, writes dist
npm run smoke         # asserts the built ESM and CJS entries expose the expected API
npm run test:mutation # stryker, incremental
```

CI在节点22和节点22上进行类型检查、林特、克尼普、测试、建造和烟雾测试 24,重复18号和20号节点的建构和烟雾测试,并且,在每次拉出请求时,都瞄准 `master` 或者说 `main`,提示拉动请求中的承诺信息.

`tests/fixtures/basic-project` 是端到端的锚。 这是一个真实的, 故意打破的 FSD 树 每一个消息id至少带一个违反 加上一组必须保持沉默的文件, 而集成测试则用从中构建的插件在它之上运行 ESLint `src` 比较整个报告 与一个坚定的快照。 一个打破管道而不打破任何单元测试的重构器 在那里,你读吧 `tests/fixtures/basic-project/README.md` 在触摸它之前.

### 提交信件

承诺跟随 [常规武器委员会](https://www.conventionalcommits.org/)数字 : `type(scope): description`,最多100个字符的标题,以及一个用两个字符写的主题 句子,开始,巴斯卡尔或大写。 允许的类型是 `build`, (中文(简体) ), `chore`, (中文(简体) ), `ci`, (中文(简体) ), `docs`, (中文(简体) ), `feat`, (中文(简体) ), `fix`, (中文(简体) ), `perf`, (中文(简体) ), `refactor`, (中文(简体) ), `revert`, (中文(简体) ), `style` 财务报告和审定财务报表 `test`。 。 。 .

两个附加规则适用于整个消息,标题,身体和脚都一样. 它必须保持ASCII,所以 没有打印破折号,箭头, emoji或非latin文本。 它不能带归属线: 不 `Co-authored-by:` 拖车,没有线起于 `Generated with`。信件本身写,例如 作为合并、回归或 `fixup!`只要他们通过这两个规则,就跳过常规规则。 一个 所以报告还列出在真实位置旁边的常规错误 一,他们离开 一旦违法的线路被移除.

`npm ci` 财务报告和审定财务报表 `npm install` 安装一个 `commit-msg` 钩穿了 `prepare` 脚本,所以支票 此软件包所支持的每个节点版本。 钩子读取 文件 git 即将执行, 其中注释行和剪刀行下方的 diff 不包含 ; CI 读取存储的输入, 其中以散列开头的行也算数 。 CI 线条 每一次拉力请求 因为拉力请求被重新定位到主人身上 每一个都承诺土地 就是这样 用手检查范围:

```sh
npx --no -- commitlint --from origin/master --to HEAD --verbose
```

## 许可证

ISC (英语).

发现错误还是假阳性? [打开一个问题](https://github.com/conarti/eslint-plugin-feature-sliced/issues)拉动请求是 欢迎.

## 常见问题

### @conarti/eslint-plugin-feature-sliced 是什么？

特性设计方法插件

### 如何安装 @conarti/eslint-plugin-feature-sliced？

在项目目录运行 npm install @conarti/eslint-plugin-feature-sliced，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：eslint（\>=9）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @conarti/eslint-plugin-feature-sliced 支持 TypeScript 吗？

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

### @conarti/eslint-plugin-feature-sliced 支持 ESM 还是 CommonJS？

同时提供 ES Module 与 CommonJS 入口，import 和 require\(\) 都可以使用，打包工具会自动选择合适的版本。

### @conarti/eslint-plugin-feature-sliced 需要什么版本的 Node\.js？

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

### @conarti/eslint-plugin-feature-sliced 可以商用吗？

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

### @conarti/eslint-plugin-feature-sliced 的下载量有多少？

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

### @conarti/eslint-plugin-feature-sliced 还在维护吗？

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

