如何制作一个可主题化的Angular Material NPM模块? [英] How can I make a theme-able Angular Material NPM module?

查看:136
本文介绍了如何制作一个可主题化的Angular Material NPM模块?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以构建使用 Angular Material 的npm模块,并允许对其定义的组件进行样式设置通过消费应用程序的自定义主题?

Is it possible to build an npm module that uses Angular Material and allows the components it defines to be styled by the consuming app's custom theme?

作为示例,假设我创建了一个包含具有以下模板的组件的npm模块:

As an example, say I create an npm module that includes a component with the following template:

<button mat-raised-button color="accent">Click me!</button>

是否可以将此组件导入两个不同的应用程序,每个应用程序定义一个自定义的Angular Material主题,并让按钮呈现当前应用主题的重音颜色?

Is it possible to import this component into two different apps, each of which defines a custom Angular Material theme, and have the button take on the "accent" color of the current app's theme?

目前,我正在使用 ng-packagr 构建Angular友好的npm模块。但是,据我所知,这个模块包含一个 .scss 编译阶段作为打包过程的一部分,这意味着模块中定义的任何样式都失去了它们的能力。由使用该模块的应用程序中的主题定制。

Currently, I'm using ng-packagr to build Angular-friendly npm modules. However, as far as I can tell, this module includes a .scss compilation stage as part of the packaging process, which means any styles defined in the module lose their ability to be customized by a theme in an app that uses the module.

推荐答案

确实,这是可能的。这个问题与Angular无关,它适用于那里的任何其他框架。

Indeed, it is possible. The question just doesn't relate to Angular, it applies to any other framework out there.

在此之前,你需要了解依赖倒置的概念。假设您正在构建应用 App1 App2 ,并使用包含可重用组件的npm模块 lib 。您的应用程序构建在 lib 之上,这意味着您的应用程序是更高级别的模块, lib 是更低级别的模块。

Before that, you need to glace over the concept of dependency inversion. Say you are building your apps App1 and App2 and use an npm module lib which contains your reusable component. Your apps are built on top of lib meaning your apps are higher level module and lib is lower level module.

如果您认为 lib 是自包含的,那么理想情况下,它应该在 App1 或<中使用时执行相同的操作code> App2的。但是你的要求是 - lib 应该根据应用程序有不同的行为(在这种情况下为样式)。这意味着您希望更高级别的模块就较低级别模块的行为方式做出一些决定。所以你正在反转依赖,那就是依赖倒置原则。详细了解维基百科上的DIP

If you consider your lib is self-contained then ideally, it should perform same be it used in App1 or App2. But your requirements are - lib should have different behavior (styling in this case) as per the app. It means that you want the higher level module to make some decisions on how the lower level module should behave. So you are inverting dependency and that is dependency inversion principle. Read more about DIP on wikipedia.

现在要实现DIP,您需要从库中公开某种端口/扩展,并且为了样式化目的,最简单的方法是公开SCSS mixins 。但是如果您使用任何构建工具(如Webpack,汇总或ng-package),那么它们将始终生成已编译的分发。您将不得不编写一些额外的node.js脚本来打包源代码(此处为SCSS)以及已编译的代码。这些脚本将在编译/捆绑步骤中执行。

Now to achieve DIP, you will need to expose some sort of port/extension from your library and for styling purpose, the simplest way is to expose SCSS mixins. But if you use any build tool like Webpack, rollup or ng-package, then they will always generate compiled distributions. You will have to write some extra node.js scripts to package your source code (SCSS here) along with the compiled code. These scripts will be executed during compilation/bundling step.

在我的工作中,我有类似的要求。您应该遵循一些指导原则:

At my work, I am having similar requirements. There are some guidelines you should follow:


  1. 库中的组件应该是开箱即用的一些默认样式。

  2. 默认情况下,库的用户不必每次都自定义组件。

  3. 从样式组件中公开mixins。

  4. 在mixins中,不要放置任何硬编码的首选项。

  5. 开发可主题化的组件时,请从默认开始。覆盖应用程序中组件使用的默认CSS类。清空公共自定义点/属性,然后将其放回到库的下一个版本中。不要在库中进行前期开发。它通常会导致返工。

  1. Components from a library should work out of the box with some default styling.
  2. By default, a user of the library should not have to customize the component each time.
  3. Expose mixins from the components for styles.
  4. Within mixins, do not put any hardcoded preferences.
  5. When developing a themeable component, start with default. Override default CSS classes used by the component within your applications. Chalk out the commons customizations points/properties and then put it back into the next version of the library. Don't do upfront development within a library. It often results in rework.

我们有一个企业级应用程序。共有5个不同的应用程序和一个私有发布的npm模块,为所有这五个应用程序提供公共组件。但是有一些组件需要采用不同的样式,正如我所说的,首先在我们的应用程序中覆盖类,然后一旦感觉通用到足以放入通用模块,我们就把它放在下一个版本中。

We have an enterprise level apps. There are total 5 distinct apps and one privately published npm module that provides commons components to all these five apps. But there are some components which need to be styled differently which as I said, first override classes in our apps, and then once it feels generic enough to put into common module, we then put it in next release.

这篇关于如何制作一个可主题化的Angular Material NPM模块?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆