首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >面向企业项目的角度项目结构

面向企业项目的角度项目结构
EN

Stack Overflow用户
提问于 2019-07-08 15:23:43
回答 4查看 11.2K关注 0票数 3

我即将开始一个相当大的项目,它将使用角作为它的前端,我有一个关于如何管理它的增长以最大化可维护性的问题。

到目前为止,对于每个角度的项目,我都有一个视图文件夹,它模拟路由层次结构,我的模块结构是基于业务特性分组的。这已经很好地与入职新的发展,并为这些中小型应用程序的维护目的。

我的问题主要集中在什么时候在大型企业应用程序中使用模块。

我最近听说过每页创建一个模块和/或每个组件创建一个模块。这种方法似乎需要大量的前期开销,但在创建测试和长期维护方面节省了很多。

我在angular.io风格指南中没有看到任何关于这种或那种方式的指导,但我想从构建了企业大小的角度应用程序的人那里知道,他们是否找到了一种适合他们的特定方法。

更新我在这里得到了很多很好的答案。我相信大家都强调了模块的共同点,并强调了核心、共享(以及bryan提到的资源)的额外模块。我还将将路由视图移动到它们各自的功能文件夹中,而不是当前使用的“视图”文件夹。在阅读了下面的答案之后,随着应用程序的发展,“视图”文件夹可能会变得很难管理。

有人还建议我读一读Nrwl正在做的事情,于是我就这么做了,并对他们将库作为独立应用程序的使用方式感到好奇。MonoRepo模式手册(免费)。他们有很多很好的建议,这些建议和大家在这里说的一样,他们增加了将跨平台的通用功能抽象到库中。由于我确信我正在开发的应用程序将需要针对网络世界以外的移动设备,这似乎也是一个好主意。

感谢每一个花了时间详细回答的人。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2019-07-08 18:40:54

这里有很多很好的答案,我发现在构建更大的应用程序时,我发现了一些细微的差异,而到目前为止还没有提到,这就是特性和资源之间的区别。功能是应用程序所做的事情,资源是应用程序使用的东西。一个特性可以使用一个或多个资源,我认为这一点在您的项目结构中很重要。

通常情况下,我会有这样的东西:

代码语言:javascript
运行
复制
app/
  core/
    ... core stuff like nav bars and single use components or core services...
  app-shared/ (prefix it!!!!)
    ... shared app utilities like tables, accordions, validators, form helpers, pipes etc ...
  resource1/ <- represents some backend resource usually
    resource1.model <- the models
    resource1-model.service <- API interaction layer, single http calls
    resource1-domain.service <- abstraction for everything I can do with this resource (think combinations of multiple model service calls or model service calls with common defaults)
    views/
      ... here we have all the components (data views, forms etc) that concern only this resource and the needed view services ...
  ... rinse repeat for all app resources ...
  feature1/ <- this is an application feature that combines multiple resources or possibly only uses a single resource. this is pretty much primarily a page of your app
    feature1-application.service <- this combines the various resources needed for this feature
    feature1-container.component <- the prime container for this feature. does the service layer interactions and holds the views of this feature or the needed resource views
    views/ <- maybe not needed depending on the feature
      ... here is where we have components and view services that are part of this feature that combine multiple resources, these can contain resource views if needed ...
  ... rinse repeat for all app features ...

注:

  1. 模型服务是仅针对单个资源的API交互,它们调用API上的一个和唯一一个操作。
  2. 域服务采用模型服务,并使它们对开发人员来说非常有用和容易。可以注入紧密相关的子资源模型服务。
  3. 应用程序服务组合多个域服务
  4. 视图服务从域或应用程序服务获取数据,并为特定视图构建视图模型(请永远不要将后端模型直接传递到模板!!如果/当后端模型被重构时你会恨自己的..。与此相关,使模板尽可能简单。没有确定按钮是否应该显示的复杂模板表达式,构建一个带有"showButton“属性的视图模型并将其分配给它!)
  5. 资源通常不会有路由,除非是喜欢路由模式,如果你喜欢这样的事情。功能实际上是您的应用程序结构,路由,主要部分将指向主要容器,然后视图将是子视图(如果需要),但他们使用的资源视图。
  6. 如果你做得对,理论上你应该可以将你的资源直接提升到另一个使用相同资源的应用程序中(当然还有一些样式)。
  7. 您可能不需要特性中的任何子视图的原因是容器可能足够了。假设您有一个具有数据列表组件的教师资源和一个具有数据视图组件的学校资源,并且您想要一个同时显示这些内容的特性,这里的容器只需要定位这两个资源视图,并通过功能应用程序服务促进它们之间的任何交互。容器不显示数据,也不具有UX,它们只保存执行这些操作的视图。
  8. 您还经常使用单一资源功能,以便使您的功能更好地匹配您真正的应用程序结构,并提供灵活性,以便在将来为该功能添加更多的资源。
  9. 在共享子资源的情况下,紧密相关的资源视图可能以不同的资源视图结束。想一想,如果有一个标签资源,有一个特殊的多选择自动完成形式。这是一个紧密耦合的共享子资源,可以出现在多个其他资源上,因此为了简单起见,它当然可以在资源视图中结束,尽管它们通常是每个资源视图中的单个资源。
  10. 最重要的是:当你开始构建的时候,你会发现你只是在构建一些奇怪的一一对应的其他服务(IE你的域名看起来就像它只是包装你的模型,你的应用程序看起来就像它封装了你的域名),但是随着应用程序的发展,你会感激你提前一次在构建这些层上进行了投资。我从企业前端开发中学到的是,需求几乎每天都在变化,在他们看到需求付诸实施之前,他们永远无法确定自己想要什么。这些抽象层提供了对不断变化的环境做出快速反应所需的灵活性,同时仍然可以很容易地对代码库进行推理。
票数 9
EN

Stack Overflow用户

发布于 2019-07-08 16:25:58

首先:多年来,我已经开发了一些企业应用程序,并且看到了一些有用的东西,也看到了一些我希望从未尝试过的东西。好消息是:重构/开发工具现在非常好,当您发现项目结构变得难以控制时,您可以在项目结构中间切换。唯一的坏消息是:它将产生合并噩梦,这将考验你的git-fu。

风格指南确实提到了按功能分列的文件夹,这听起来就像你已经在做的事情。我会坚持你目前正在做的事情,并且应该扩大规模。你已经有了它的经验,它是有效的,尝试一些完全不同的东西,你第一次运行一个更大的应用程序听起来像是一个灾难的处方。

主要要避免的是有一个不必要的复杂文件夹结构,但实际上并不反映您的应用程序的结构。例如,如果您有一个配置文件管理部分,不要将它放在/dashboard/user/components/profile/edit或类似的任意设置中,除非它实际上模仿了您的应用程序结构。这似乎是显而易见的,但人们总是这样做,这使得您的代码不易被发现。我认为电梯的概念涵盖了这一点:

Do构造应用程序,这样您就可以快速定位代码,一眼就可以识别代码,保持尽可能平坦的结构,并尽量保持干燥。 Do定义了遵循这四个基本准则的结构,按重要性顺序列出。 为什么? LIFT提供了一个一致的结构,它可以很好地扩展,是模块化的,并且可以通过快速找到代码来提高开发人员的效率。要确认您对某一特定结构的直觉,请问:我能快速打开并在所有相关文件中开始这项功能吗?

它还提到尽可能保持一个扁平的文件夹结构:

Do尽可能地保持平面文件夹结构。 考虑在文件夹到达七个或更多文件时创建子文件夹。 考虑配置IDE以隐藏分散注意力的无关文件,例如生成的.js和.js.map文件。 为什么?没有人想通过七个文件夹级别搜索文件。平面结构易于扫描。

这是大型项目中最关键的一点。当你在一个有20个模块的应用程序上工作时,一个不必要的复杂的文件夹结构是一个轻微的烦恼。当您到达150个模块时,当您打开IDE时,您会本能地畏缩。总体结构准则是项目的良好起点,并演示了何时保留/feature/与何时使用子功能文件夹。

关于每个组成部分的模块:

Do为每个功能区域创建一个NgModule。 为什么? NgModules使延迟加载可路由特性变得容易。 为什么? NgModules使隔离、测试和重用特性变得更加容易。

您可以扩展它以表示您应该为每个组件创建一个模块,但是我实际上会避免它,除非您对给定的模块有特定的需求。同样--在我的经验中,为自己创建开销甚至会使变得更麻烦,因为项目越大,越麻烦。那些在小项目中看起来有点烦人的事情在大型项目中变成了噩梦。

最后注意事项:随时准备改变。你和你的同事可以花一周的时间规划你的项目结构,但一旦你真正开始使用它,你就会发现它是错误的。在你的第一次尝试中很难做到百分之百的正确。慢慢地迭代会更容易,直到你到达接近完美的东西为止。

我的项目通常是这样的:

代码语言:javascript
运行
复制
app/
| core/ 
| | constants/         // Keep all constants in a single place and avoid magic IDs/strings.
| | |-http-status-codes.enum.ts
| | guards/            // I like to group my guards in a single place
| | http-interceptors/ // Same with interceptors
| | pipes/             // Some pipes might be section-specific but they are usually core
| | services/          // Core services. Utilities, error handling, etc.
| | |-error-handler.service.ts
| | validators/
| section1/
| | models/
| | sub1/              // I try not to nest too deeply
| | |-sub1.component.ts|html|css|spec.ts
| |-section1-routing.module.ts // Routing by section
| |-section1.component.ts|html|css|spec.ts
| |-section1.module.ts  // Module per section for lazy loading, etc.
| |-section1.service.ts // Section-specific service
| shared/
| | models/
| | app-modal-dialog/
| | my-awesome-widget/
| | some-custom-input/
|-app.component.ts|html|css|spec.ts
|-app.module.ts
|-app-routing.module.ts
assets/             // Static content
environments/
|-environment.x.ts  // Stripe public keys, etc.

再说一遍-这与风格指南非常一致。

票数 6
EN

Stack Overflow用户

发布于 2019-07-08 16:03:08

首先,在构建应用程序时,我尝试使用LIFT准则:

  • 定位我们的代码很容易
  • 一目了然地识别代码
  • 平面结构,只要我们能
  • 尽量保持干燥(不要重复)

那么我的文件夹结构就像:

代码语言:javascript
运行
复制
app/
  core/
    models/             // All models
    not-found/          // A core feature (not-found component for example)
    ...
    core.module.ts
  feature1/             // Feature 1 folder
    sub-feature1-1/     // A sub feature for the feature 1
    sub-feature1-2/     // A sub feature for the feature 1
    feature1.service.ts
    feature1.module.ts
  feature2/             // Feature 2 folder
    sub-feature2-1/     // A sub feature for the feature 2
    sub-feature2-2/     // A sub feature for the feature 2
    feature1.service.ts
    feature1.module.ts
  shared/
    card/               // A shared feature (card component for example)
    ...
    shared.module.ts
  app-routing.module.ts
  app.component.html
  app.component.scss
  app.component.spec.ts
  app.component.ts
  app.module.ts

在这种结构中,我总是尝试在子特性上保持一个级别。所有功能都应尽可能独立,并且只应承担一项责任。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56938106

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档