是否可以构建一个使用Angular Material的npm模块,并允许其定义的组件由消费应用程序的自定义主题设置样式?
作为一个例子,假设我创建了一个包含具有以下模板的组件的npm模块:
<button mat-raised-button color="accent">Click me!</button>
是否可以将此组件导入两个不同的应用程序,每个应用程序定义a custom Angular Material theme,并使按钮采用当前应用程序主题的“重音”颜色?
目前,我正在使用ng-packagr来构建Angular友好的npm模块。但是,据我所知,这个模块包含一个.scss
编译阶段作为打包过程的一部分,这意味着模块中定义的任何样式都失去了使用应用程序中的主题自定义的能力。模块。
答案 0 :(得分:1)
Angular Material Theming Your Own Components指南部分涵盖了如何执行此操作的基本要点。除了主题组件之外,库(“npm模块”)还需要为Angular Material库通过其angular-material-theme()
mixin提供的所有样式提供入口点。这通常通过定义一个mixin来定义样式并调用所有组件主题mixins来完成,而不是创建一个带样式定义的样式表文件。 mixin将主题作为参数,并使用该主题定义其自己的所有样式以及将其应用于其任何组件。例如,您的库可能有自己的_theme.scss
文件,任何消费应用程序都可以导入该文件,这将定义mixin:
@import '~@angular/material/theming';
@import './components/my-component/_my-component-theme'; // component theming file with mixin
@mixin library-theme($theme) {
@include angular-material-theme($theme); // angular material
@include my-component-theme($theme); // component theming
// define non-component styles
}
消费应用程序需要导入库的主题文件,创建自己的主题,然后调用库的主题混合。
显然有更多细节,但这些是基础知识。作为参考,我建议您通过GitHub查看Angular Material如何自己的theming。
答案 1 :(得分:1)
确实,这是可能的。这个问题与Angular无关,它适用于那里的任何其他框架。
在此之前,您需要了解依赖倒置的概念。假设您正在构建应用 App1 和 App2 ,并使用包含可重用组件的npm模块 lib 。您的应用程序构建在 lib 之上,这意味着您的应用程序是更高级别的模块, lib 是更低级别的模块。
如果您认为lib
是自包含的,那么理想情况下,它应该与App1
或App2
中使用的相同。但是你的要求是 - lib 应该根据应用程序有不同的行为(在这种情况下为样式)。这意味着您希望更高级别的模块就较低级别模块的行为方式做出一些决定。所以你正在反转依赖,那就是依赖倒置原则。详细了解DIP on wikipedia。
现在要实现DIP,您需要从库中公开某种端口/扩展,并且出于样式目的,最简单的方法是公开SCSS mixins 。但是如果您使用任何构建工具(如Webpack,汇总或ng-package),那么它们将始终生成已编译的分发。您将不得不编写一些额外的node.js脚本来打包源代码(此处为SCSS)以及已编译的代码。这些脚本将在编译/捆绑步骤中执行。
在我的工作中,我有类似的要求。您应该遵循一些指导原则:
我们有一个企业级应用程序。共有5个不同的应用程序和一个私有发布的npm模块,为所有这五个应用程序提供公共组件。但是有一些组件需要采用不同的样式,正如我所说的,首先在我们的应用程序中覆盖类,然后一旦感觉通用到足以放入通用模块,我们就把它放在下一个版本中。