一个项目,多个客户端。Angular 2。

3

好的,我有一个问题,似乎找不到答案。

假设我有一个名为x的项目,将由多个客户使用,每个客户都有自己的功能,这些功能可能会共享或者不共享,并且他们拥有自己的自定义样式表和html布局。

因此,按照正常的Angular 2点击模式,我想知道是否可能实现这一点。

例如:

foo
--foo.component.css
--foo.component.html
--foo.component.spec.ts
--foo.component.ts
--client-x
----foo.component.css
----foo.component.html
--client-y
----foo.component.css
----foo.component.html
----foo.comoonent.ts

如您所见,第一级别将是基本实现。然后客户端x使用相同的功能,但只覆盖样式和html,而客户端y则覆盖所有功能以及样式和css。
请问是否有人知道这是否可行以及这是否是一个好主意。原因是,我们有多个包含基本相同代码的项目,如果在代码库中发现Bug或添加功能,则必须不断更新所有项目。我知道在Angular 1中这是可能的,因为我看过类似于此的项目结构。我相信他们使用了gulp任务来进行后期构建,但我不确定这是否足够并且也不知道如何处理它。
欢迎提供您的意见。

是的,你应该一定要看一下nx https://github.com/nrwl/nx - maxime1992
3个回答

3
我们有相同的问题,计划采用以下方法来解决,这在小型概念验证项目中已经得到了验证:
  • 有一个包含所有通用组件和模板的核心模块。
  • 每个客户端应用程序都作为子模块实现。
  • 对于每个子模块,一个监视脚本将核心组件复制到该子模块的“base”文件夹中。默认情况下,子模块声明并使用基础文件夹中的组件。

组件继承

要覆盖子组件的逻辑,请声明一个从核心组件继承的新组件。修改子模块以声明继承的组件,而不是基础文件夹中的组件。

模板继承

我们使用nunjucks,使组件模板具有继承块。

因此,对于每个可以通过子组件重写其模板的组件,我们都有一个template.html.nunj,它通过nunjucks编译为template.html。

这是通过监视脚本完成的。监视脚本还会检查每个子模块中是否有每个组件的html文件。如果有一个文件,则在基础文件夹中对应组件的templateUrl链接将被更改为指向该文件。这使我们可以仅覆盖模板,而无需重新声明component.ts文件。

样式继承

使用sass,在单独的文件中声明变量,并使用相对路径引用它们。如果需要,您可以修改继承组件的sass文件以导入核心组件的sass,然后在下面覆盖样式。


谢谢你,这看起来是最好的解决方案。我心里有类似的想法,只是不确定它是否可行,而且现在我没有时间去创建一个 POC。 - Theunis

3

目前,通过框架的方式是无法覆盖组件样式/模板

应用程序 Angular 模块应该以最小化提供自定义组件实现的工作量的方式进行结构化。如果有可能被覆盖(通常是带有其依赖项的组件)的功能,它应该包含在自己的 Angular 模块中。

所有可定制的模块都不包括在共享模块中,因此后者不包含可定制单元,并且可以按原样导入。

默认的应用程序主模块只是这些模块的包装器:

@NgModule({
  imports: [
    GenericFooModule, // customizable FooComponent
    GenericBarModule, // BarService and customizable BarComponent
    GenericSharedModule // everything else
  ],
  exports: [/* same */]
})
export class GenericAppModule {}

入口文件:

platformBrowser().bootstrapModuleFactory(GenericAppModuleNgFactory)

接着,客户端可以使用最少的WET代码重新定义它们。由于类注释继承不受支持,这意味着@Component应该被粘贴并修改:

自定义组件:

@Component({
  selector: '...', // same as original
  templateUrl: '...' // same as original, but relative path refers to different file
})
export class XFooComponent extends FooComponent {}

@NgModule({
  declarations: [XFooComponent],
  exports: [/* same */]
})
export class XFooModule {}

自定义主模块:

@NgModule({
  imports: [
    XFooModule, // customized
    GenericBarModule,
    GenericSharedModule 
  ],
  exports: [/* same */]
})
export class XAppModule {}

定制化条目:
platformBrowser().bootstrapModuleFactory(XAppModuleNgFactory)

这样可以尽可能地使客户项目保持小而DRY,从而留下很少的不一致和人为错误的空间。
否则,唯一的选择是通过使用打包程序来篡改特定于客户端的资产文件(如现有答案所建议的)。Angular CLI不支持这种做法,而且项目除了自定义样式和模板之外,总有可能需要针对客户进行修改。

在这个实现中,FooModule 只包含一个组件。如果它包含多个组件,但我只需要自定义其中一个组件,那么我是否需要在新的自定义组件中覆盖/扩展所有通用组件? - Mark C.

0
我解决类似情况的方法是创建一个 webpack 配置,其中有多个 入口点。为客户端 1 使用一个入口点,为客户端 2 使用另一个入口点。入口点中的代码可以根据客户端执行必要的配置,并在之后调用启动函数,webpack 将负责排除不需要的代码。我喜欢这种设置,因为从我的 IDE 的角度来看,所有代码都是“正在使用”的,使得重构和其他系统范围的调整更容易。
如果您正在使用 angular-cli,我认为 webpack 配置不是直接可访问的,但您可以使用“eject”生成一个。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接