0
votes

Background: I have a package with Angular (5.0.0, Dart 2.0.0) components (let's call it my_components) that I use in many customer projects (app_1, app_2, ...). These apps must override some CSS properties (e.g. colors) of almost every component I have to reflect the customers corporate identity. The obvious choice here would be to define the values as SASS variables in a _variables.scss file in the app_n packages. (I can't use CSS custom properties because IE support is required (I know IE is not officially supported by Angular)) The problem here is that the component scss files must import the _variables.scss file, so my_components would need a dependency on app_n, which isn't possible.

I tried to solve this the following way: In my_components I have a file lib/_variable.default.scss. The component scss files still contain the line @import package:my_components/_variables.scss. I wrote an InjectAssetsBuilder that runs on the .default.scss file extension and produces .scss files. The builder is configurable and expects a mapping 'my_components|lib/_variables.scss': 'app_n|web/variables.scss' in the build.yaml configuration of app_n. The builder is supposed to be triggered by the .default.scss file, then place the customized file right next to it, so it can be found by the component imports.

However, I can't get it to work. If I set auto_apply to all_packages (in the builder definitions of my_components), the builder doesn't receive the mapping configuration (from the build targets section in app_n). If I set auto_apply to none, the builder no longer takes my_components as an input, so it can't see and be triggered by the .default.scss file.

If anyone has worked on a similar problem before (or has another idea how app_n can inject SASS variables into the my_components dependency), I'd love to hear their thoughts. Otherwise, I'd be grateful if someone could explain to me how build configurations are scoped:

  1. Why doesn't the auto_apply: all_packages builder see the configuration in app_n?
  2. Why is the builder from the target definition in app_n unable to see assets in my_components?

If you think I made a mistake with the configuration, I can try to extract a minimal example.

2

2 Answers

1
votes

I don't believe generating sources into a package that you depend on is a fully supported option in the build system.

In the angular_components package we have taken an alternative approach for the components we share across different client apps. We have settled on a system of overriding styles that can be applied to change the appearance.

A shared component is built with a set of good default styles. The shared component also offers a _mixins.scss file that contains a set of Sass mixins for client apps to import. The mixins are designed to correctly override all the styles needed to change the theme of a component.

For example here is the mixin that allows you to change the style of a radio button.

0
votes

It turned out I had some errors in my build.yaml configuration and the builder itself, but I finally got it running. I published my solution on pub: https://pub.dartlang.org/packages/inject_assets_builder

The README contains instructions for a full working example.

If you use the same component in multiple places in your app and only want to style some of them, nshanans answer is the better choice.