feature-sliced-design
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseFeature-Sliced Design Architecture
Feature-Sliced Design 架构
Overview
概述
Provides guidance for implementing Feature-Sliced Design (FSD v2.1) in Next.js applications. FSD organizes code into a layered hierarchy that prevents circular dependencies and promotes maintainability.
本文提供在Next.js应用中实现Feature-Sliced Design(FSD v2.1)的指导方案。FSD通过分层结构组织代码,可避免循环依赖并提升可维护性。
Next.js Customization (Only Difference from Official FSD)
Next.js 定制适配(与官方FSD的唯一区别)
This skill adapts FSD for Next.js App Router with one structural choice:
| Official FSD | This Skill (Next.js) |
|---|---|
| |
| |
| Separate routing layer | Next.js file-based routing ( |
src/app/layout.tsxpage.tsxpage.tsx@/viewsReference files (load as needed):
- layers-and-segments.md — Layer definitions, slices (zero coupling, slice groups), segment patterns, migration
- public-api.md — Public API rules, @x cross-imports, shared/ui structure, circular imports
- code-smells.md — Desegmentation, generic folders anti-patterns
- examples.md — Full examples: layers, auth patterns, types, API requests
- react-query.md — React Query + FSD: Query Factory, pagination, QueryProvider
- monorepo.md — (Optional) Turborepo + FSD structure
本方案针对Next.js App Router对FSD进行了适配,主要结构差异如下:
| 官方FSD | 本方案(适配Next.js) |
|---|---|
| |
| |
| 独立的路由层 | Next.js 基于文件的路由( |
src/app/layout.tsxpage.tsxpage.tsx@/views参考文件(按需查阅):
- layers-and-segments.md — 分层定义、切片(零耦合、切片组)、分段模式、迁移指南
- public-api.md — 公共API规则、@x跨模块导入、shared/ui结构、循环依赖处理
- code-smells.md — 反模式示例:分段缺失、通用文件夹滥用
- examples.md — 完整示例:分层结构、鉴权模式、类型定义、API请求
- react-query.md — React Query + FSD:查询工厂、分页、QueryProvider配置
- monorepo.md — (可选)Turborepo + FSD 结构方案
Purpose
设计目标
Feature-Sliced Design (FSD) is an architectural methodology for organizing frontend applications into a standardized, scalable structure. It provides clear separation of concerns through a layered hierarchy that prevents circular dependencies and promotes maintainability.
Feature-Sliced Design(FSD)是一种前端应用架构方法论,通过标准化的可扩展结构组织代码。它通过分层结构清晰划分职责,避免循环依赖并提升可维护性。
Why use FSD
为何选择FSD
- Scalability: Grows naturally as your application expands
- Maintainability: Clear boundaries make refactoring safer
- Team collaboration: Consistent structure enables parallel development
- Onboarding: New developers understand architecture quickly
- 可扩展性:随应用规模增长自然适配
- 可维护性:清晰的边界让重构更安全
- 团队协作:统一结构支持并行开发
- 新人上手:新开发者可快速理解架构
Unified src/app/
structure
src/app/统一的src/app/
结构
src/app/Both Next.js App Router and FSD App layer live in . Next.js recognizes , , etc. inside , so all code stays under without a root-level folder, aligning with FSD v2.1.
src/app/layout.tsxpage.tsxsrc/app/src/app/Next.js App Router和FSD App层均位于****目录下。Next.js可识别内的、等文件,因此所有代码都在目录下,无需根目录级别的文件夹,与FSD v2.1规范对齐。
src/app/src/app/layout.tsxpage.tsxsrc/app/Custom 'views' layer
自定义的'views'层
This skill uses 'views' instead of the standard FSD 'pages' layer. Page business logic goes in ; routing structure stays in .
/src/views/src/app/本方案使用'views'层替代标准FSD的'pages'层。页面业务逻辑存放于;路由结构保留在中。
/src/views/src/app/When to Use
适用场景
Apply Feature-Sliced Design when:
- Starting new Next.js projects that require clear architectural boundaries
- Refactoring growing codebases that lack consistent structure
- Working with multi-developer teams needing standardized organization
- Building applications with complex business logic requiring separation of concerns
- Scaling applications where circular dependencies become problematic
- Creating enterprise applications with long-term maintenance requirements
- (Optional) Developing monorepo applications (Turborepo, etc.) — see monorepo.md
在以下场景中应用Feature-Sliced Design:
- 启动需要清晰架构边界的全新Next.js项目
- 重构缺乏统一结构的大型代码库
- 多开发者团队协作,需要标准化的代码组织方式
- 构建业务逻辑复杂、需要职责分离的应用
- 解决循环依赖问题的规模化应用
- 构建需要长期维护的企业级应用
- (可选)开发monorepo应用(Turborepo等)——详见monorepo.md
Core Principles (FSD v2.1)
核心原则(FSD v2.1)
Layer Hierarchy
分层结构
FSD v2.1 organizes code into 7 layers (from most to least responsibility/dependency):
- app - App-wide matters (entrypoint, providers, global styles, router config)
- processes - Deprecated; move contents to and
featuresapp - views - Page-level business logic (custom naming; standard FSD uses 'pages')
- widgets - Large self-sufficient UI blocks
- features - Main user interactions and business value
- entities - Business domain objects and models
- shared - Foundation (UI kit, API client, libs, config)
You don't have to use every layer — add only what brings value. Most projects use at least Shared, Pages (or views), and App.
FSD v2.1 pages-first: Start with pages/views; keep most logic there. Extract to features/entities only when code is reused across several pages.
Import rule: A module can only import from layers strictly below it.
┌─────────────────┐
│ app │ ← Can import from all layers below
├─────────────────┤
│ views │ ← Can import: widgets, features, entities, shared
├─────────────────┤
│ widgets │ ← Can import: features, entities, shared
├─────────────────┤
│ features │ ← Can import: entities, shared
├─────────────────┤
│ entities │ ← Can import: shared only
├─────────────────┤
│ shared │ ← Cannot import from any FSD layer
└─────────────────┘FSD v2.1将代码分为7层(按职责/依赖程度从高到低排序):
- app - 应用全局内容(入口、提供者、全局样式、路由配置)
- processes - 已废弃;将内容迁移至和
features层app - views - 页面级业务逻辑(自定义命名;标准FSD使用'pages')
- widgets - 大型独立UI块
- features - 核心用户交互与业务价值模块
- entities - 业务领域对象与模型
- shared - 基础层(UI组件库、API客户端、工具库、配置)
无需使用所有分层——仅添加能带来实际价值的层。大多数项目至少会使用Shared、Pages(或views)和App层。
FSD v2.1 以页面/视图优先:从页面/视图开始构建,将大部分逻辑保留在该层。仅当代码需要在多个页面复用时,再提取至features/entities层。
导入规则:模块仅能从严格下层的模块导入。
┌─────────────────┐
│ app │ ← 可导入所有下层模块
├─────────────────┤
│ views │ ← 可导入:widgets、features、entities、shared
├─────────────────┤
│ widgets │ ← 可导入:features、entities、shared
├─────────────────┤
│ features │ ← 可导入:entities、shared
├─────────────────┤
│ entities │ ← 仅可导入:shared
├─────────────────┤
│ shared │ ← 不可导入任何FSD分层模块
└─────────────────┘'Views' vs 'Pages' Layer
'Views'层 vs 'Pages'层
- : Next.js routing + FSD App layer —
src/app/,layout.tsx, route groups, providers, styles.page.tsximports frompage.tsxand renders.@/views - : Page business logic, component composition — View components, models, API calls. Composes widgets, features, entities.
src/views/
- :Next.js路由 + FSD App层 — 包含
src/app/、layout.tsx、路由组、提供者、样式。page.tsx从page.tsx导入并渲染组件。@/views - :页面业务逻辑、组件组合 — 视图组件、模型、API调用。组合widgets、features、entities模块。
src/views/
Slices and Public API
切片与公共API
Slices are domain-based partitions within layers (except app and shared). Examples: , , , .
views/dashboardwidgets/headerfeatures/authentities/user- Zero coupling, high cohesion — Slices should be independent (no same-layer imports) and contain related code.
- Slice groups — Related slices can live in a folder, but no code sharing between them inside that folder.
- Each slice exports through . Use explicit exports — avoid
index.ts. Consumers import from public API only.export * from
See public-api.md for circular import rules, shared/ui structure, and @x cross-imports.
切片是分层内基于领域的分区(app和shared层除外)。示例:、、、。
views/dashboardwidgets/headerfeatures/authentities/user- 零耦合、高内聚 — 切片应保持独立(同层内禁止跨切片导入),且包含相关联的代码。
- 切片组 — 相关切片可存放在同一文件夹下,但文件夹内的切片之间禁止共享代码。
- 每个切片通过导出内容。使用显式导出——避免
index.ts语法。消费者仅能从公共API导入内容。export * from
关于循环导入规则、shared/ui结构、@x跨模块导入的详细说明,请查阅public-api.md。
Segments
分段
Segments group code by purpose (why), not essence (what). Avoid , , , — use purpose-based names.
componentshookstypesutils- ui/ - React components, visual elements
- model/ - Business logic, state management, TypeScript types
- api/ - API clients, data fetching, external integrations
- lib/ - One area of focus per library; document in README
- config/ - Configuration constants, feature flags
Shared layer segments: , , , , ,
apiuilibconfigi18nroutes分段按**用途(why)**而非本质(what)对代码进行分组。避免使用、、、这类通用命名——使用基于用途的命名。
componentshookstypesutils- ui/ - React组件、视觉元素
- model/ - 业务逻辑、状态管理、TypeScript类型
- api/ - API客户端、数据获取、外部集成
- lib/ - 每个文件聚焦一个工具库;在README中说明用途
- config/ - 配置常量、功能开关
Shared层的分段:、、、、、
apiuilibconfigi18nroutesNaming Conventions
命名规范
| Target | Convention | Example |
|---|---|---|
| Folders, slices | kebab-case | |
| Component files | kebab-case | |
| Hook files | camelCase | |
| Store files | camelCase | |
| Function/API collections | camelCase | |
| 目标 | 规范 | 示例 |
|---|---|---|
| 文件夹、切片 | kebab-case | |
| 组件文件 | kebab-case | |
| Hook文件 | camelCase | |
| 状态管理文件 | camelCase | |
| 函数/API集合 | camelCase | |
FSD with Next.js App Router
FSD 与 Next.js App Router 结合
Next.js recognizes routing files inside . All FSD layers live under ; no root-level folder.
src/app/src/app/File organization:
my-nextjs-app/
├── src/
│ ├── app/ # Next.js routing + FSD App layer
│ │ ├── layout.tsx
│ │ ├── page.tsx
│ │ ├── dashboard/page.tsx
│ │ ├── providers/
│ │ └── styles/
│ ├── views/
│ ├── widgets/
│ ├── features/
│ ├── entities/
│ └── shared/
│ ├── ui/
│ ├── lib/
│ └── api/
└── package.jsonRouting pages import from views:
typescript
// src/app/dashboard/page.tsx
import { DashboardView } from '@/views/dashboard';
export default function DashboardPage() {
return <DashboardView />;
}(Optional) Monorepo: See monorepo.md
For full directory structure and layer examples, see references.
Next.js可识别内的路由文件。所有FSD分层均位于目录下;无根目录级别的文件夹。
src/app/src/app/文件组织结构:
my-nextjs-app/
├── src/
│ ├── app/ # Next.js路由 + FSD App层
│ │ ├── layout.tsx
│ │ ├── page.tsx
│ │ ├── dashboard/page.tsx
│ │ ├── providers/
│ │ └── styles/
│ ├── views/
│ ├── widgets/
│ ├── features/
│ ├── entities/
│ └── shared/
│ ├── ui/
│ ├── lib/
│ └── api/
└── package.json路由页面从views层导入组件:
typescript
// src/app/dashboard/page.tsx
import { DashboardView } from '@/views/dashboard';
export default function DashboardPage() {
return <DashboardView />;
}(可选)Monorepo方案:详见monorepo.md
完整的目录结构和分层示例,请查阅references。
Workflow
实施流程
Step 1: Set Up Layer Directories
步骤1:创建分层目录
bash
mkdir -p src/{app,views,widgets,features,entities,shared}
mkdir -p src/app/{providers,styles,config}
mkdir -p src/shared/{ui,lib,api,config}bash
mkdir -p src/{app,views,widgets,features,entities,shared}
mkdir -p src/app/{providers,styles,config}
mkdir -p src/shared/{ui,lib,api,config}Step 2: Create First Entity
步骤2:创建第一个Entity
Start with entities (bottom layer). Define core business models in and API in . Export via .
entities/{name}/model/entities/{name}/api/index.ts从最底层的entities层开始。在中定义核心业务模型,在中定义相关API。通过导出内容。
entities/{name}/model/entities/{name}/api/index.tsStep 3: Build Features Using Entities
步骤3:基于Entity构建Feature
Create features in . Features import from entities and shared only.
features/{name}/在中创建功能模块。Features层仅可从entities和shared层导入内容。
features/{name}/Step 4: Compose Widgets from Features
步骤4:基于Feature构建Widget
Build composite widgets in . Widgets can import from features, entities, shared.
widgets/{name}/在中创建复合UI块。Widgets层可从features、entities、shared层导入内容。
widgets/{name}/Step 5: Assemble Views
步骤5:组装View
Create page-level views in . Views compose widgets, features, entities.
views/{name}/在中创建页面级视图。Views层组合widgets、features、entities模块。
views/{name}/Step 6: Connect to App Router
步骤6:对接App Router
Wire views to Next.js routing. imports from .
page.tsx@/views/{slice}将views层与Next.js路由关联。从导入组件。
page.tsx@/views/{slice}Import Rules
导入规则
Allowed
允许的导入
- Layer importing from layer below
- Any layer importing from shared
- Slice importing different slice in lower layer
- 上层模块导入下层模块
- 任意层导入shared层模块
- 下层模块中的切片导入同层其他切片
Forbidden
禁止的导入
- Layer importing from same or higher layer
- Cross-slice imports within same layer
- Shared importing from FSD layers
- 模块导入同层或上层模块
- 同层内跨切片导入
- shared层导入任何FSD分层模块
Fixing Circular Dependencies
循环依赖修复方案
- Extract shared logic to lower layer (entities or shared)
- Create higher layer (widget) that imports both
- Review if slice should be split
- 将共享逻辑提取至更低层级(entities或shared层)
- 创建更高层级的模块(如widget)来导入存在循环依赖的模块
- 评估是否需要拆分现有切片
Public API Enforcement
公共API强制执行
Always use to control exports. Import from public API only:
index.tstypescript
// ✅ Correct
import { LoginForm } from '@/features/auth';
// ❌ Wrong (deep import)
import { LoginForm } from '@/features/auth/ui/LoginForm';始终通过控制导出内容。仅从公共API导入:
index.tstypescript
// ✅ 正确写法
import { LoginForm } from '@/features/auth';
// ❌ 错误写法(深层导入)
import { LoginForm } from '@/features/auth/ui/LoginForm';Migration Strategy (Bottom-up)
迁移策略(自底向上)
- Start with shared layer — extract UI, lib, API client
- Define entities — business domain objects
- Extract features — user interactions
- Build widgets — composite UI blocks
- Organize views — move page logic from page files
- Configure app layer — providers, styles
Migrate incrementally; run tests after each layer.
- 从shared层开始——提取UI组件、工具库、API客户端
- 定义entities层——业务领域对象
- 提取features层——用户交互模块
- 构建widgets层——复合UI块
- 组织views层——将页面逻辑从路由文件中迁移
- 配置app层——提供者、样式
采用增量迁移方式;完成每一层迁移后运行测试。
Best Practices
最佳实践
- No cross-slice imports within same layer
- Export through ; avoid
index.ts; use explicit exportsexport * from - shared/ui: per-component index for tree-shaking (see public-api.md)
- Avoid generic folders/files: ,
types.ts,utils.ts— use domain names (see code-smells.md)components/ - Colocate tests next to implementation
- Keep slices focused; avoid "god slices"
- Name by domain: not
features/product-searchfeatures/search-bar-component - Use TypeScript strict mode
- 同层内禁止跨切片导入
- 通过导出;避免
index.ts;使用显式导出export * from - shared/ui:为每个组件单独创建index文件以支持tree-shaking(详见public-api.md)
- 避免使用通用文件夹/文件命名:、
types.ts、utils.ts——使用基于领域的命名(详见code-smells.md)components/ - 测试文件与实现文件放在同一目录下
- 保持切片聚焦;避免“上帝切片”
- 按领域命名:而非
features/product-searchfeatures/search-bar-component - 启用TypeScript严格模式
Troubleshooting
问题排查
Import path issues: Configure path aliases in — see Configuration below.
tsconfig.jsonBuild errors: Clear , run , restart dev server.
.nextnpm install导入路径问题:在中配置路径别名——详见下方配置部分。
tsconfig.json构建错误:清理目录,运行,重启开发服务器。
.nextnpm installConfiguration
配置说明
TypeScript Path Aliases
TypeScript 路径别名
json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/app/*": ["src/app/*"],
"@/views/*": ["src/views/*"],
"@/widgets/*": ["src/widgets/*"],
"@/features/*": ["src/features/*"],
"@/entities/*": ["src/entities/*"],
"@/shared/*": ["src/shared/*"]
}
},
"include": ["src"]
}json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/app/*": ["src/app/*"],
"@/views/*": ["src/views/*"],
"@/widgets/*": ["src/widgets/*"],
"@/features/*": ["src/features/*"],
"@/entities/*": ["src/entities/*"],
"@/shared/*": ["src/shared/*"]
}
},
"include": ["src"]
}ESLint (Optional)
ESLint(可选)
javascript
'no-restricted-imports': ['error', {
patterns: [{
group: ['@/views/*', '@/widgets/*'],
message: 'Features cannot import from views or widgets',
}],
}]javascript
'no-restricted-imports': ['error', {
patterns: [{
group: ['@/views/*', '@/widgets/*'],
message: 'Features cannot import from views or widgets',
}],
}]Reference Files
参考文件
Documentation Library
文档库
Load these resources as needed during development:
Core FSD Reference
- layers-and-segments.md — Layers, slices (zero coupling, slice groups), segments, @x cross-reference, migration (including v2.0→v2.1)
- public-api.md — Public API rules, @x cross-imports, circular imports, shared/ui tree-shaking, Steiger
- code-smells.md — Desegmentation, generic folder/file anti-patterns
Implementation Examples
- examples.md — Full examples: each layer, page layouts, auth, types/DTOs, API requests, domain-based files
Optional
- react-query.md — React Query + FSD: Query Factory, pagination, QueryProvider
- monorepo.md — Turborepo + FSD structure
External
开发过程中按需查阅以下资源:
核心FSD参考
- layers-and-segments.md — 分层、切片(零耦合、切片组)、分段、@x跨模块引用、迁移指南(含v2.0→v2.1)
- public-api.md — 公共API规则、@x跨模块导入、循环依赖、shared/ui tree-shaking、Steiger模式
- code-smells.md — 反模式示例:分段缺失、通用文件夹/文件滥用
实现示例
- examples.md — 完整示例:各分层结构、页面布局、鉴权、类型/DTO、API请求、领域化文件
可选内容
- react-query.md — React Query + FSD:查询工厂、分页、QueryProvider配置
- monorepo.md — Turborepo + FSD 结构方案
外部资源
- FSD 官方文档 | 分层 v2.1 | 公共API | Next.js 指南 | v2.0→v2.1 迁移指南 | React Query 指南 | FSD 示例项目