33

I have an angular monorepo set up via Nrwl and am using Angular Material's theming, which uses SASS.

I want the SCSS source files to import at the project level where I'll override default color variables for theming.

The problem I'm running into is that I want to import SCSS source files into other apps/libraries within my monorepo, and to projects outside of this monorepo.

I can write my imports like:

@import "../other-lib/style.scss";

...which will work for anything inside of the monorepo.

Or I can write it like this:

@import "~@my-organization/other-lib/style.scss";

...which won't work inside of my monorepo, AFAIK.

How do I get it to work in both contexts?

It's setup something like the diagram below.

enter image description here

2
  • I have exactly the same question. I can stuff them all in a top-level directory somewhere and just do the usual long winded imports. Setting up "paths" does not seem to work (you set up the path but the import statement in the stylesheet doesn't recognize it). I figured I'd try importing them into a styles.scss in a library and trying to export that, no luck here yet (though I haven't tried everything I don't think). Definitely an irksome one, the nature of sass etc. seems intuitively to be very monorepo, but the importing is extremely verbose. What's the established practice here? Commented Jul 1, 2019 at 12:42
  • For now, we're going with css variables on our project. We're also exploring css-in-js solutions for the future.
    – Kevin Beal
    Commented Jul 2, 2019 at 17:28

1 Answer 1

20

I think I might have something here, this is the solution I've adopted after some back 'n forth with the NRWL team.

I create an NX workspace by first creating a project with the angular CLI, and then adding the extensions, like so:

  • ng new myproject (cd into myproject root)
  • ng add @nrwl/workspace

In addition, as of today (July 10, 2019) I've reported a bug that, even though the workspace is already an angular type and the @nrwl install recognizes that and installs @nrwl/angular, it does not correctly configure the default schematics collection, which means that "ng" commands will not run without appending "@nrwl/angular:" before the command (e.g. "ng @nrwl/angular:g module mymod"). So you have to run the install (select scss and whatever e2e runner you want):

  • ng add @nrwl/angular

It'll tell you @nrwl/angular is already installed, but will alter the config files to recognize the angular as the default schematic collection, and your ng commands will run as expected again.

That's that for the workspace. Now create a lib:

  • ng g lib scss --directory=stylesheets

This will put a lib named scss in libs->stylesheets. In the "lib" directory of that library, dump all your scss files. We will assume you put a file "variables.scss" in that lib directory.

What this does is a couple of things:

  • When you created the library, a "paths" entry is added to your repo config. This allows you to use assets in the library by using that path instead of a long relative import. Note that just adding this entry and trying to import scss files into other scss files without the library wrapper, does not work. Evidently, you need that library to get that path to resolve.

If you look, you'll see the "paths" entry is something like this:

"@nameofrepo-nameoflib"

In order to use the scss assets in the library, in angular.json, you have to manually (not ideal but there it is) add the below fragment to the "build.options" section of EACH AND EVERY PROJECT YOU WANT TO USE IT IN.

So yes, if you have ten projects, each will have a project entry in angular.json, each of those will have a build.options block (typically ending with "scripts []", at least in my vanilla install), and you have to add this to each of those options sections (this info is out there, but I wanted to confirm, this is straight from the NRWL team):

"stylePreprocessorOptions": {
    "includePaths": ["libs/stylesheets/scss/src/lib"]
},
"extractCss": true

Now, say you've created an app, and added the above config to the entry in angular.json:

ng g app myapp

And that within this app you created a feature module and component:

(cd into apps/myapp/src)

ng g module myfeature ng g component myfeature

That will create the module and component folder and assets, etc.

NOTE: As of same date as above, there's an issue that creating a component directly this way will create a .css file, even though .scss is the selected type for the project. Make sure you rename that file and change the component's pointer to it.

Within myfeature.component.scss, you would import "variables.scss" from your lib this way:

@import "variables"

Note there is no "~" (that resolves to node_modules). And, if you have subdirectories in the "lib" directory (e.g. utils), just path to it as you'd expect:

@import "utils/somefile"

Again...you MUST configure the preproccesor options as indicated in EACH project entry in angular.json!

Another gotcha: these paths may or may not appear to resolve in your IDE. Strangely, it seems some do and some don't. Not exactly sure of the pattern here, but keep in mind that your IDE may show an error where there technically isn't one.

This is working nicely for my projects.

12
  • 3
    How can we use those variables from another library?
    – maxime1992
    Commented Sep 23, 2019 at 6:55
  • Not sure I understand, do you mean how to use style variables from one style library, in another style library? Commented Sep 24, 2019 at 10:42
  • Yes. I've got a library containing all my scss variables and I want to import them from a different library but it doesn't seem to be working
    – maxime1992
    Commented Sep 25, 2019 at 10:49
  • I'm betting it's your config. How did you create the libraries, do you see path entries for them in angular.json? Would definitely need more info on your setup. Commented Sep 25, 2019 at 12:26
  • 1
    I thought I had to use stylePreprocessorOptions for the libs but actually just putting that on the app itself worked! Thanks a lot
    – maxime1992
    Commented Sep 26, 2019 at 10:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.