十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Lightdash 前端架构指南:React + Vite 的 Feature-Driven 目录结构与工程实践

Lightdash 前端架构指南:React + Vite 的 Feature-Driven 目录结构与工程实践 Lightdash 前端架构指南React Vite 的 Feature-Driven 目录结构与工程实践【免费下载链接】lightdashAgentic BI. Analytics at the speed of code ⚡️项目地址: https://gitcode.com/GitHub_Trending/li/lightdash本篇技术指南以 Lightdash 仓库中 packages/frontend/README.md 为骨架系统讲解其前端包lightdash/frontend的开发入门方式、核心技术栈选型以及基于 Feature-driven 思想设计的目录分层规范UI / Features / API / Pages 四大顶层模块。读完本文你将掌握 Lightdash 前端源码的组织逻辑、各层级的职责边界与 lint 约束并能结合仓库中的真实实现如 SQL Runner、用户功能模块与 API 客户端快速定位代码、开展二次开发。1. 入门指南如何启动前端开发环境1.1 不要单独运行该包前端包不应该被隔离运行。原因在于 Lightdash 是一个全栈单仓库monorepo前端需要与后端 API、数据库、dbt 项目联动才能完成登录、查询、渲染等完整链路。正确做法是遵循仓库根目录贡献文档中 Setup development environment 一节即packages/frontend/README.md的原始指引其指向的文档相对位置为仓库根目录的.github/CONTRIBUTING.md的步骤启动整套开发环境。1.2 包内可用的脚本命令虽然不应单独运行但作为包本身packages/frontend/package.json 中定义了完整的开发、构建与质量校验脚本供在完整环境中按需执行命令作用pnpm dev以 Vite 启动本地开发服务器热更新pnpm build执行vite build产出生产构建pnpm serve以vite preview预览生产构建产物pnpm test/pnpm test-watch运行 vitest 单元测试 / 监听模式pnpm typecheck基于 tsconfig.json 执行 TypeScript 类型检查pnpm lint/pnpm fix-lint使用 oxlint 检查 / 修复./srcpnpm format/pnpm fix-format使用 oxfmt 检查 / 修复代码格式pnpm storybook/pnpm build-storybook启动 / 构建 Storybook 组件开发环境pnpm build-sdk通过 rollup 构建前端 SDK 产物pnpm release发布 SDK 到 npmsdk目录从脚本可以看出该包同时承担了 Lightdash 前端应用与嵌入式 SDK 的构建职责这也是build-sdk、check:sdk-csp等命令存在的直接原因。2. 核心技术栈原文档列出了前端包依赖的五大核心库结合 package.json 的版本信息可归纳如下技术版本以当前仓库为准在项目中的角色React19.3.0UI 基础框架含 React DOMVite8.0.16构建工具与开发服务器Mantine9.6.0组件库core/dates/form/hooks/modals/notifications/tiptap/code-highlightReact Querytanstack/react-query4.36.1服务端状态管理与数据请求缓存EChartsecharts echarts-for-react5.6.0图表渲染在核心五件套之外仓库实际还引入了与业务强相关的大量依赖理解它们有助于读懂源码状态管理reduxjs/toolkit、react-redux、reselect全局状态、use-context-selector局部状态按需订阅路由react-routerv7数据表格tanstack/react-table、tanstack/react-virtualSQL 编辑器monaco-editor、monaco-sql-languages、popsql/monaco-sql-languages、monaco-editor/react可视化补充vega、vega-lite、react-vega、react-grid-layout、leaflet地图、d3-geo/d3-scale/d3-time、topojson-client、h3-js六边形网格文档/富文本tiptap/*、uiw/react-md-editor、remark-*、rehype-*导出jspdf、html2canvas-pro、csv-stringifyAI 能力ai、streamdown与仓库 Agentic BI 定位相关权限casl/ability、casl/react监控sentry/react、rudder-sdk-js产品分析、react-use-intercom。这些依赖分布在 package.json 的dependencies约 120 个运行时依赖与devDependencies构建、测试与 lint 工具中是理解前端架构广度的第一手资料。3. 架构总览Feature-Driven 目录结构原文档给出了前端包的标准目录骨架- UI - Molecules - Organisms - Features - User - Hooks - Components - Modals - Utils - Providers - Organization - Project - Chart - Dashboard - Space - Visualization - API - Pages注意原文档明确标注——任何不符合该结构的文件夹都应被视为 legacy 代码并应在重构中逐步收敛。这套结构的设计动机在原文档中有明确交代它提供了两个入口通过features或pages进入代码降低了新开发者学习代码库的认知负担同时消除了抽象的全局文件夹如笼统的components/、utils/避免出现什么都能往里扔的垃圾场效应。其设计灵感来自 Feature-driven folder structure。3.1 顶层目录速览对照 packages/frontend/src 的实际目录可以看到架构落地后的真实面貌顶层目录说明仓库实际状态ui/按 Atomic Design 划分的 Molecules / Organisms对应实际目录中的components/见下文说明features/按业务领域组织功能代码features/下约 40 个领域文件夹见 4.2api/API 客户端与类型实际位于 src/api另有全局的 src/api.tspages/与路由一一对应的页面组件src/pages 约 60 个页面文件components/全局共享组件含大量可视化组件src/components需要说明的是仓库顶层还额外存在hooks/、providers/、utils/、theme/、styles/、types/、stories/、testing/等目录它们支撑起路由、主题、测试与全局工具函数等横切能力可视作对原文档四层骨架的补充实现。4. 深入四层架构4.1 UI 层受 Atomic Design 启发的分层UI 层借鉴了 Atomic Design 的分层思想但针对 Lightdash 的实际情况做了裁剪Atoms已废弃不设此目录原文档用删除线明确标注不需要 Atoms 目录。原因是 Mantine 组件库已经完整覆盖了原子级组件按钮、输入框、文本等团队无需自行维护这一层。这正是技术选型直接影响目录结构设计的典型例证——选对了组件库就能省掉一整层代码。Molecules分子组件Molecules 由一个或多个原子组件组合而成只包含完成自身功能所需的最少逻辑与状态。典型示例包括表单字段、卡片等由多个原子组件复合而成的 UI 元素。约束规则复用性组件将被多个地方复用无内部状态不能管理内部 state。Lint 限制不能从代码库其余部分导入文件保证 Molecule 的纯粹性与可移植性。Organisms组织组件Organisms 由一个或多个分子/原子组件组合而成体量更大为 UI 提供结构感。典型示例包括页头header、页脚footer、侧边栏sidebar。约束规则允许管理基础内部状态例如const isOpen useStateboolean()允许复用分子组件。Lint 限制只能从 Molecules 导入文件形成严格的依赖方向Organisms → Molecules → Mantine 原子组件防止层级倒挂。真实落地components 目录的可视化组件群在仓库中UI 层组件群集中在 packages/frontend/src/components可以看到大量符合分子/组织定位的组件目录例如SimpleChart/、SimpleTable/、SimpleStatistic/、SimpleGauge/、SimpleMap/、SimplePieChart/、SimpleSankey/、SimpleTreemap/通用可视化组件VisualizationConfigs/图表配置面板DashboardTiles/、MinimalDashboardTabs/仪表盘瓦片相关NavBar/、NavBarLayout.tsx、AboutFooter.tsx典型的 Organism 示例导航栏、布局、页脚ExportResults/、ExportSelector/、Download/导出能力common/跨功能共享的基础组件。这些组件与 ECharts、Vega 等可视化库结合如EChartsReactWrapper.tsx构成 Lightdash 图表渲染的 UI 基座。4.2 Features 层按知识领域组织的功能域Features 层是这套架构的灵魂。原文档给出的组织原则是为应用的每个主要功能即知识领域 knowledge domain建立一个文件夹。一个很好的判断依据是看后端 API 路由如何划分例如org、user、project、chart、dashboard此外一些体量较大的 UI 功能例如visualizations也值得拥有独立文件夹。每个功能域内部应包含hooks、components、modals、utils、provider子目录。对照仓库 packages/frontend/src/features这一原则落地为约 40 个领域目录包括apps/、chartTypes/、comments/、contentAsCode/、dashboardFilters/、dashboardTabs/、dateZoom/、directAccess/、documents/、errorBoundary/、explorer/、export/、externalConnections/、externalSources/、funnelBuilder/、learn/、mergeQuery/、metricsCatalog/、notifications/、omnibar/、organizationDesigns/、parameters/、preview/、projectGroupAccess/、promotion/、pullRequests/、queryHistory/、queryRunner/、recentlyDeleted/、roleSets/、scheduler/、scopeTours/、sourceCodeEditor/、sqlRunner/、sync/、tableCalculation/、users/、virtualView/。可以看到除user、project、chart、dashboard等与 API 路由对齐的领域外sqlRunner、explorer、metricsCatalog、funnelBuilder等大型 UI 功能也都拥有独立领域目录与文档big UI features deserve their own folder的原则完全吻合。以 users 域为例的结构验证packages/frontend/src/features/users 下的结构精确复现了文档要求components/包含LoginLanding.tsx、LoginWithEmailOtp.tsx及对应的.test.tsx测试文件hooks/用户相关的自定义 Hookutils/用户域工具函数。以 sqlRunner 域为例看子目录的完整形态packages/frontend/src/features/sqlRunner 是大型功能域的代表子目录结构更为丰满components/SqlEditor.tsx、Sidebar.tsx、Tables.tsx、SqlRunnerChart.tsx、SaveSqlChartModal.tsx、WriteBackToDbtModal.tsx等 20 余个组件覆盖编辑器、表目录、图表渲染、保存/更新/删除、写回 dbt 等完整交互hooks/11 个 Hook如useTables.tsx、useTableFields.tsx、useSqlQueryRun.tsx、useSavedSqlCharts.tsx、useSqlRunnerShareUrl.ts、useGithubDbtWriteBack.tsx充分体现数据请求逻辑集中在 hooks 子目录的约定store/Redux store 切片runners/、utils/、constants.ts、index.ts。这套结构让开发者在面对SQL Runner 的数据从哪来时直接进hooks/找useSqlQueryRun面对SQL Runner 的界面在哪时直接进components/找SqlEditor检索成本极低。4.3 API 层与后端路由一一对应的纯函数客户端API 层承担的是与后端交互所需的最小端点endpoint与类型。原文档的三条铁律文件与后端 router/controller 文件一一对应必须是纯函数pure functions不包含 hooks——hooks 应定义在对应 feature 的hooks子目录中。Lint 限制不能从 FE 代码库其余部分导入文件保持 API 客户端作为前端最薄的外层的独立性。仓库中的真实实现全局 API 基础设施位于 packages/frontend/src/api.ts配合 src/api.test.ts 的测试覆盖按端点组织的客户端位于 packages/frontend/src/api例如 src/api/csv.ts 展示了典型形态import { type ApiDownloadCsv, type ApiScheduledDownloadCsv, } from lightdash/common; import { lightdashApi } from ../api; export const getCsvFileUrl async ({ jobId }: ApiScheduledDownloadCsv) lightdashApiApiDownloadCsv({ url: /csv/${jobId}, method: GET, body: undefined, });这段代码同时印证了三条铁律类型来自共享包lightdash/commongetCsvFileUrl是纯异步函数、不含任何 hook文件与后端csv相关的 controller 路由对应。类型定义集中在lightdash/commonpackages/common/src/types实现了前后端类型共享。4.4 Pages 层与网站路由 1 对 1 的页面组件Pages 层的要求最简洁也最严格与网站路由一一对应。这意味着src/pages下的每个文件都应能在路由表中找到归属。对照 packages/frontend/src/pages 与路由入口src/AppRoutes.ts、src/Routes.tsx可以看到页面与业务路由的高度对应认证类Login.tsx、Register.tsx、PasswordRecovery.tsx、PasswordReset.tsx、VerifyEmail.tsx、Invite.tsx项目类Projects.tsx、CreateProject.tsx、OnboardingDataSource.tsx、OnboardingDbt.tsx查询类Explorer.tsx、SavedExplorer.tsx、SqlRunner.tsx、ViewSqlChart.tsx、QueryHistory.tsx仪表盘类Dashboard.tsx、DashboardHistory.tsx、DashboardVersionComparison.tsx、SavedDashboards.tsx空间类Spaces.tsx、Space.tsx、SharedWithMe.tsx内容类Documents.tsx、Document.tsx、SavedApps.tsx、Learn.tsx、MetricsCatalog.tsx设置类Settings.tsx、OrganizationSetup.tsx、UserActivity.tsx嵌入/最小化视图MinimalApp.tsx、MinimalDashboard.tsx、MinimalSavedExplorer.tsx、MinimalSqlChart.tsx、AppGenerate.tsx、AppPreviewTest.tsx对应 SDK 嵌入场景。页面组件通常只做组合工作从features拉取领域组件、从api调用数据再交给 UI 层渲染从而让页面成为架构中最薄的一层。5. 双入口设计为什么 Pages 与 Features 是并行的原文档强调这套结构提供了两个入口features或pages这是 Feature-Driven 结构的核心收益之一面向业务的入口features当你关心某个业务功能怎么实现比如用户邮箱登录的 OTP 校验逻辑直接进入 src/features/users不必先理解路由再反推组件面向导航的入口pages当你关心某个 URL 渲染什么直接进入 src/pages文件名即路由名例如打开/sql-runner就能找到 SqlRunner.tsx。与此同时文档也强调了消除抽象全局文件夹的价值在传统 React 工程里components/与utils/往往是最大的垃圾场而 Feature 目录让每个模块自带hooks/components/modals/utils/providers子目录职责随功能内聚重构与删除的成本更低。6. 如何读懂并扩展这套架构6.1 阅读源码的推荐路径先看页面从 src/pages 入手找到对应路由的页面组件再看功能域顺着页面引用的组件进入 src/features 对应领域阅读其components与hooks追数据流从hooks里的请求 Hook如useSqlQueryRun跟踪到 src/api 的纯函数客户端再向上对应后端 controller 路由看共享类型前后端共享的请求/响应类型定义在 packages/common/src/types由lightdash/common包统一导出。6.2 新增功能的放置建议遵循仓库约定新增页面 → src/pages 新增文件并在 src/AppRoutes.ts 等路由入口登记新增业务功能 → 在 src/features 下新建领域目录内部按components/hooks/modals/utils/providers组织新增后端接口调用 → 在 src/api 添加与后端 controller 对应的纯函数类型从lightdash/common复用通用可视化/UI 组件 → src/components 下的对应子目录。6.3 质量保障类型检查pnpm typecheck单元测试vitest Testing Librarysrc/testing大量组件与 Hook 均带.test.tsx/.test.ts用例如 AppRoutes.test.ts、WriteBackToDbtModal.test.tsxLint / 格式oxlint oxfmt见 package.json 的 scripts组件开发环境Storybook配置文件位于 src/stories。7. 总结packages/frontend的架构核心可以概括为一句话用 Feature 目录收敛业务复杂度用分层 lint 约束保证依赖方向用双入口Pages/Features降低认知负担。UI 层砍掉 Atoms 直接基于 Mantine 构建Features 层按知识领域自包含组织API 层保持与后端路由 1 对 1 的纯函数形态Pages 层与路由严格对应——四层各司其职配合 React Query、Redux、ECharts/Vega 等技术栈共同支撑起 Lightdash 这个 Agentic BI 产品的前端体验。对于任何计划为 Lightdash 贡献前端代码的开发者而言遵循这套目录结构与 lint 约束是快速融入代码库、避免产生 legacy 代码的最有效方式。【免费下载链接】lightdashAgentic BI. Analytics at the speed of code ⚡️项目地址: https://gitcode.com/GitHub_Trending/li/lightdash创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表