news 2026/9/18 19:00:00

Argilla 前端目录结构全解析:从 Nuxt 页面组织到 v1 Clean Architecture 分层

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Argilla 前端目录结构全解析:从 Nuxt 页面组织到 v1 Clean Architecture 分层

Argilla 前端目录结构全解析:从 Nuxt 页面组织到 v1 Clean Architecture 分层

【免费下载链接】argillaArgilla is a collaboration tool for AI engineers and domain experts to build high-quality datasets项目地址: https://gitcode.com/GitHub_Trending/ar/argilla

本篇文章基于 Argilla 仓库中 argilla-frontend/docs/structure.md 的官方目录说明,逐层剖析 Argilla 前端(基于 Nuxt 2 + Vue 2 的 Web 应用)的完整目录体系。你将掌握 assets、components、pages、layouts、middleware、plugins、e2e、v1 等每个目录的职责边界与相互调用关系,理解 base 组件与 features 组件的分层哲学,并看懂 v1 新架构中依赖注入容器、领域层与基础设施层的真实组织方式,从而能够快速定位代码、判断新功能应该落在哪个目录。

一、顶层目录总览

structure.md给出的官方结构树完整如下:

. ├── assets │ ├── fonts │ ├── icons │ └── scss ├── database -> Vuex modules (to be removed) ├── models -> Vuex models (to be removed) ├── store -> Vuex store (to be removed) ├── components │ ├── base -> Base and stateless components │ ├── features -> Features used in just one page │ ├── annotation -> Componentes used in Annotation page │ ├── datasets -> Components to support datasets page │ ├── global -> Components used in multiple pages ex: UserAvatarComponent │ ├── login -> Components to support login page │ └── user-settings -> Components to support user settings page ├── e2e -> E2E tests ├── layouts -> Layout components ├── middleware -> Nuxt middlewares ├── pages -> Nuxt global pages ├── plugins -> Nuxt plugins ├── static -> Static resources ├── translations -> Argilla translation resources ├── v1 -> New architecture │ ├── di │ ├── domain │ ├── infrastructure │ └── store │... ├── package.json ├── package-lock.json └── .gitignore

对照当前仓库实际内容,可以观察到结构演进:文档中标记为 "to be removed" 的database(Vuex modules)、models(Vuex models)两个目录已经不存在,store(Vuex store)也整体迁移到了 v1/store 之下;原本分散在components下的annotationdatasetsgloballoginuser-settings子目录,如今统一收纳进 components/features,并在其中新增了dataset-creationhome等功能域;translations目录实际名为translation(与 nuxt.config.ts 中的langDir: "translation/"保持一致)。理解这份"文档基线 + 仓库现状"的差异,比单纯背目录更有价值——它反映了一次从 Vuex 状态管理向 Pinia/组合式 API 演进、从扁平组件目录向"基础组件 + 功能组件"两级体系演进的重构过程。

二、assets:样式与图标的统一入口

assets是构建期会被打包进应用的静态资源目录,与static(运行期原样拷贝)有本质区别。当前仓库中该目录实际包含:

  • assets/scss:全部 SCSS 样式源文件,其中abstract/存放变量、函数、混入(mixin)等抽象层定义;
  • assets/icons:由 SVG 图标生成的 JS 模块(如 assets/icons/annotation-mode.js 系列),配合 assets/icon-template.js.tmp 模板文件;
  • assets/styles.scss:全局样式入口。

这些资源在 nuxt.config.ts 中被消费:

css: ["~assets/styles.scss"], ... styleResources: { scss: "./assets/scss/abstract.scss", },

css将全局样式注入所有页面;styleResources(来自@nuxtjs/style-resources模块)则把abstract.scss中定义的 SCSS 变量与混入自动注入到每个组件的<style>中,使业务组件无需手动@import即可使用主题变量——这是目录结构与构建配置联动的典型例子。

图标生成链路同样值得注意:package.json 中的generate-icons脚本(vsvg -s ./static/icons -t ./assets/icons --tpl ./assets/icon-template.js.tmp)把static/icons下的原始 SVG 批量编译为assets/icons下的 JS 模块,供 base-icon 组件动态渲染。因此"新增一个图标"需要同时改动static/iconsassets/icons两个目录,且后者是生成产物,不应手工编辑。

三、components:base 与 features 的两级组件哲学

components是 Argilla 前端组件体系的核心,遵循"基础组件与业务组件分离"的原则,通过 nuxt.config.ts 的自动导入能力全局注册:

components: [ { path: "~/components", pattern: "**/*.vue", pathPrefix: false, level: 1, }, ],

pathPrefix: false意味着所有.vue组件都会以文件名为组件名(如base-tag目录下的文件即为BaseTag),无需在模板中手动import

3.1 base:基础且无状态的通用组件

base目录(argilla-frontend/components/base)存放"与业务无关、可复用、多为无状态"的原子组件,例如:

  • base-badgebase-tag:徽章与标签;
  • base-buttonbase-checkboxbase-switchbase-sliderbase-range:基础表单控件;
  • base-icon:图标渲染;
  • base-modalbase-tooltipbase-dropdown:浮层与弹窗;
  • base-inputbase-search-bar:输入与搜索;
  • base-toastbase-feedback:全局反馈提示;
  • base-render-markdownbase-code:Markdown 渲染与代码高亮;
  • base-progressbase-loadingbase-spinner:加载与进度展示。

这类组件的典型特征是无副作用、不直接依赖后端 API,输入输出完全由 props/events 驱动,因此可以在任何页面中安全复用。例如base-render-markdown底层借助markedmarked-highlightmarked-katex-extensiondompurify(见 package.json)实现安全的高亮与数学公式渲染,供注释(annotation)页面的指导语(guidelines)等场景使用。

3.2 features:服务于单一页面的功能组件

features目录(argilla-frontend/components/features)按"页面/业务域"组织,当前包含annotationdataset-creationglobalhomeloginuser-settings六个功能域,与 structure.md 描述的"Features used in just one page"一脉相承。以最重要的 features/annotation(99 个.vue文件、31 个.ts文件)为例,其内部按职责再次细分:

  • container:标注流程的容器组件,承担数据编排;
  • header:标注页顶部工具栏;
  • guidelines:数据集标注指导语的展示;
  • pagination:记录翻页;
  • progress:标注进度展示;
  • settings:标注设置面板;
  • shortcuts:键盘快捷键。

global(如UserAvatarComponent一类的跨页面组件)、loginhomedataset-creationuser-settings分别对应登录页、首页、新建数据集流程与用户设置页面。当新功能只属于某个页面时,应放入对应功能域;只有当组件被多个页面共用且与业务无关时,才应该上升到base

四、pages、layouts、middleware 与 plugins:Nuxt 四大约定目录

4.1 pages:文件即路由

argilla-frontend/pages 采用 Nuxt 的文件系统路由约定,关键页面包括:

  • index.vue:首页;
  • sign-in.vue:登录页,配套useSignInViewModel.ts
  • welcome-hf-sign-in.vue:Hugging Face Spaces 环境下的欢迎/登录引导页;
  • user-settings.vue:用户设置;
  • new/_id.vue:新建数据集流程(动态路由参数id);
  • dataset/_id/:数据集详情,其中settings.vue为数据集设置页,annotation-mode/为标注模式页面,useDatasetViewModel.tsuseDatasetSettingViewModel.ts分别是两级页面各自的 ViewModel。

ViewModel 模式(useXxxViewModel.ts)是 Argilla 前端的标准做法:页面组件只负责渲染,业务逻辑收敛到 ViewModel 中,再通过 v1 层的 UseCase 与 Repository 访问后端。

4.2 layouts:页面骨架

argilla-frontend/layouts 定义了四类页面骨架:Home.vue(首页布局)、AuthenticationLayout.vue(登录/认证布局)、AnnotationPage.vue(标注页全屏布局)、InternalPage.vue(内部功能页布局),外加app.vue(应用根布局)与error.vue(错误页)。不同页面通过 Nuxt 的layout属性选择不同骨架,例如标注页面使用沉浸式的AnnotationPage以最大化标注空间。

4.3 middleware:路由守卫

argilla-frontend/middleware 中的两个中间件在 nuxt.config.ts 中被全局挂载:

router: { middleware: ["route-guard", "me"], base: process.env.BASE_URL ?? "/", },
  • route-guard.ts 按路由名做访问控制:未登录访问任何页面时记录redirectTo并重定向到sign-in;已登录用户访问sign-in则跳回首页;在 Hugging Face Spaces 环境下将登录入口重定向到welcome-hf-sign-in;对oauth-provider-callback等 OAuth 回调路由做空参数拦截;
  • me.ts 通过ts-injectyuseResolve(LoadUserUseCase)加载当前用户,若后端返回 401 则触发$auth.logout()并重定向到登录页——这是路由守卫与 v1 架构协同工作的典型链路。

4.4 plugins:全局注入

argilla-frontend/plugins 在 nuxt.config.ts 中以plugins: [{ src: "~/plugins" }]整体注册。其入口 plugins/index.ts 使用require.context("./", true, /^\.\/.*\.(ts|js)$/)递归加载目录下所有插件模块并执行其默认导出,从而实现"新增插件文件即自动注册"。插件按职责分子目录:

  • axios/axios-cache.ts(API 响应缓存)与axios-global-handler.ts(全局错误处理);
  • di/:依赖注入容器初始化入口di.ts
  • directives/:自定义指令,如tooltip.directive.tsclick-outside.directive.tsbadge.directive.tsrequired-field.directive.tssvg-icon.element.ts
  • extensions/:工具扩展,如color-generator.tscopy-to-clipboard.tsformat-number.tsnotification.tsvue-draggable.ts
  • language/language-detector.tslanguage-direction.ts
  • logo/:Logo 渲染逻辑。

五、e2e:Playwright 端到端测试

argilla-frontend/e2e 存放基于 Playwright 的端到端测试(playwright.config.ts),与 package.json 中的e2e/e2e:silent/e2e:report脚本对应,并在postgenerate阶段(nuxt generate后)自动执行静默回归测试。

测试目录按页面划分:annotation-mode-page(标注模式,含 autosave、mac 快捷键、元数据筛选与排序等专项 spec)、dataset-setting-pagedatasets-pagelogin-pageuser-setting-pagecommon/目录则提供 API Mock 工具(dataset-api-mock.tsrecord-api-mock.tsquestion-api-mock.tsfield-api-mock.tsmetadata-api-mock.tslogin-and-wait-for.ts),使 E2E 测试可以脱离真实后端独立运行。各 spec 目录下的__screenshots__用于维护 Playwright 视觉回归基线。

六、static 与 translation:静态资源与多语言

  • argilla-frontend/static 存放运行期原样暴露的静态资源:fonts/(Raptor 主题字体)、icons/(与assets/icons对应的 SVG 源文件)、images/(Logo、登录页截图、帮助信息图)、js/handlebars.min.js,以及favicon系列与site.webmanifest(在 nuxt.config.ts 的head中被引用)。
  • argilla-frontend/translation 是 Argilla 的多语言资源目录,提供en.jsde.jses.jsja.js四种语言文件,与 nuxt.config.ts 的@nuxtjs/i18n配置一一对应(langDir: "translation/"defaultLocale: "en"fallbackLocale: "en"strategy: "no_prefix"、关闭浏览器语言自动探测)。新增语言只需在此目录添加语言文件并在i18n.locales注册。

七、v1:面向 Clean Architecture 的新架构

v1是 Argilla 前端正在演进的新架构(argilla-frontend/v1),替代以 Vuex 为中心的旧模式,其核心是"依赖注入 + 分层职责"。整体分为四层:

7.1 di:依赖注入容器

argilla-frontend/v1/di/di.ts 中的loadDependencyContainer(context)是 v1 架构的心脏:它基于ts-injectyContainer.register(dependencies),将全部 Repository 与 UseCase 显式注册进容器。每个 Repository 注入useAxiosExtension(context)提供的 Axios 实例,UseCase 则声明其依赖的 Repository 或 Storage:

register(GetDatasetsUseCase) .withDependencies(DatasetRepository, useDatasets) .build(), register(LoadRecordsToAnnotateUseCase) .withDependencies( GetRecordsByCriteriaUseCase, GetDatasetProgressUseCase, GetUserMetricsUseCase, useRecords ) .build(),

这种注册表式的写法让"组件 → UseCase → Repository → HTTP"的依赖链一目了然,也便于单元测试中替换依赖实现。

7.2 domain:纯业务领域层

argilla-frontend/v1/domain 分为四部分:

  • entities/(84 个 TS 文件):领域实体模型,如dataset/record/user/workspace/question/field/metadata/vector/等;
  • usecases/(36 个 TS 文件):业务用例,如get-datasets-use-case.tssubmit-record-use-case.tssave-draft-use-case.tsbulk-annotation-use-case.tsload-records-to-annotate-use-case.tsdataset-setting/下的一系列配置更新用例;同目录的*.test.ts(如get-dataset-fields-grouped-use-case.test.tsoauth-login-usecase.test.ts)展示了对 UseCase 的单元测试方式;
  • services/:领域服务接口(如 v1/domain/services 中的IDatasetRepository),定义 Repository 的抽象契约;
  • events/:领域事件定义。

7.3 infrastructure:基础设施实现

argilla-frontend/v1/infrastructure 是 domain 层的实现落地:

  • repositories/(19 个 TS 文件):如 DatasetRepository.ts,直接面向后端 API。以数据集为例,createPOST /v1/datasetspublishPUT /v1/datasets/{id}/publishimport/export/v1/datasets/{id}/import/exportupdatePATCH /v1/datasets/{id}、进度查询走GET /v1/datasets/{id}/progress(配合largeCache()),并在写操作后调用revalidateCache使AxiosCache缓存失效。错误统一映射为DATASET_API_ERRORS常量中的语义化错误码,供上层做用户提示;
  • services/(23 个 TS 文件):如useRunningEnvironmentuseLocalStorageuseAxiosExtensionuseRoutesuseRole等横切能力;
  • storage/(6 个 TS 文件):Pinia 状态存储,如DatasetStorageRecordsStorageDatasetsStorageMetricsStorageDatasetSettingStorageTeamProgressStorage
  • events/:基础设施层事件处理器(如UpdateMetricsEventHandlerUpdateTeamProgressEventHandler);
  • types/:后端响应类型定义。

7.4 store:状态管理

v1/store 中的create.tsnon-reactive.ts提供状态创建工具,配合@pinia/nuxt(nuxt.config.ts 中disableVuex: false,表明当前仍兼容 Vuex)完成从 Vuex 向 Pinia 的渐进迁移,这也印证了 structure.md 中"Vuex store to be removed"的演进方向。

八、命名规范:kebab-case、PascalCase 与 camelCase

argilla-frontend/docs/conventions.md 定义了全仓库统一的命名约定:

  • 文件夹名:kebab-case,例如base-tagdataset-creation
  • 组件名:PascalCase,例如BaseTag.vueUserAvatarComponent.vue
  • 类名:PascalCase,例如Question.tsDatasetRepository.ts
  • 变量/常量名:camelCase,例如firstName: string

这套约定与第 3 节所述的组件自动导入机制深度耦合:由于pathPrefix: falsebase-tag目录下的BaseTag.vue恰好能被 Nuxt 识别为<base-tag>组件;Vue 官方也要求组件注册名与文件名保持 PascalCase 一致。遵循此规范即可保证"文件名 → 组件名 → 模板标签"三者无缝映射。

九、目录、配置与请求代理的联动

最后,将目录结构放回 nuxt.config.ts 这一"总调度"中看全貌:

  • ssr: false表明 Argilla 前端是纯客户端渲染(SPA),generate.dir输出到DIST_FOLDER(默认dist);
  • Axios 采用proxy: true/api//share-your-progress两个路径被代理到后端地址BASE_URL(默认http://0.0.0.0:6900,可通过环境变量API_BASE_URL覆盖),前端代码中实际请求如/v1/datasets即经由此代理转发;
  • auth策略配置了local策略、redirect: { login: "/sign-in", logout: "/sign-in" },与pages/sign-in.vue、middleware 中的重定向逻辑相互印证;
  • publicRuntimeConfig暴露clientVersion(取自 package.json 版本)与文档站链接,供前端运行时读取。

十、写给开发者的目录导航建议

结合以上分析,在 Argilla 前端做功能开发时的目录导航路径可以概括为:

  1. 新增页面→ 在 pages 按路由创建.vue+ 对应useXxxViewModel.ts,需要新骨架时在 layouts 增加布局;
  2. 页面专属 UI→ 在 components/features 对应功能域下新增组件;通用无状态组件→ 放到 components/base;
  3. 业务逻辑→ 在 v1/domain/usecases 新增 UseCase,并在 v1/di/di.ts 注册依赖;访问后端→ 在 v1/infrastructure/repositories 实现 Repository,接口契约定义在 v1/domain/services;
  4. 状态共享→ 在 v1/infrastructure/storage 定义 Pinia 存储;
  5. 路由拦截→ 修改 middleware;全局能力→ 在 plugins 对应子目录新增插件模块;
  6. 样式与图标→ SCSS 放 assets/scss,图标 SVG 源文件放 static/icons 后执行npm run generate-icons
  7. 文案→ 在 translation 各语言文件同步添加;
  8. 回归保障→ 单元测试跟随 UseCase/组件,端到端场景补充到 e2e。

掌握这份目录地图,你就具备了在 Argilla 前端代码库中"按图索骥"的能力,无论是排查标注流程的 bug、新增数据集设置项,还是理解用户登录与路由守卫的完整链路,都能快速定位到对应的组件、UseCase 与 Repository。

【免费下载链接】argillaArgilla is a collaboration tool for AI engineers and domain experts to build high-quality datasets项目地址: https://gitcode.com/GitHub_Trending/ar/argilla

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/18 18:58:39

VSCode与Gitee保姆级教程:从零配置到代码推送与团队协作

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/18 18:56:43

IDEA代码提示慢?内存、索引、插件三管齐下,补全延迟压到50ms

你是不是也有过这种体验&#xff1a;项目打开以后&#xff0c;IDEA 底部一直显示 Indexing…&#xff0c;代码高亮正常&#xff0c;但敲代码的时候键盘按下去&#xff0c;补全列表要过一秒才弹出来。遇到大一点的接口&#xff0c;联想半天&#xff0c;偶尔连类名都提示不出来&a…

作者头像 李华
网站建设 2026/9/18 18:53:03

定压功放与定阻功放的区别、混接危害及广播系统配置排查指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华