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

查看:29
本文介绍了如何制作可主题化的 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.

在此之前,您需要先了解一下依赖倒置的概念.假设您正在构建应用 App1App2,并使用包含可重用组件的 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 是自包含的,那么理想情况下,它在 App1App2 中使用时的性能应该相同.但是您的要求是 - 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 混合.但是,如果您使用任何构建工具,如 Webpack、rollup 或 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. 从样式的组件中公开混合.
  4. 在 mixin 中,不要放置任何硬编码的首选项.
  5. 在开发可主题化的组件时,从默认开始.覆盖应用程序中组件使用的默认 CSS 类.写出公共定制点/属性,然后将其放回库的下一个版本中.不要在库中进行前期开发.这通常会导致返工.

我们有企业级应用.总共有 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天全站免登陆