0

I have an application with two very large styles sheets:

userA.scss
userB.scss

One of these style sheets could look like:

@import 'something';
.d { }

These two style sheets are legacy style sheets which contain many tens of thousands of lines (yes, really) and cannot load at the same time since they conflict in their rules, as such I load them via the CSS import in each module's SCSS like so:

@import "src/assets/scss/dashboard";

Within a module's/component's scss file.

Now, the problem I am seeing is that each time I use said import Angular has to recompile and re-evaluate this file making builds times exponentially longer depending on the number of times I include each of these files in modules/components. For example: if I make one of the style sheets only load once for the application I can shave anything up to 6 minutes build time from my SaaS provided CI/CD.

I want to include these two only once each in my application.

I immediately turned to modules, however I have a router like:

const routes: Routes = [
  {
    path: 'a',
    children: [
      {
        path: 'a',
        loadChildren: () => import('./layout-c/a.module').then(m => m.LayoutModule),
      },
    ],
  },
  {
    path: 'b/:id',
    loadChildren: () => import('./layout-b/layout-b.module').then(m => m.LayoutBModule),
  },
  {
    path: 'c',
    loadChildren: () => import('./layout-c/sign-up-c/signup-c.module').then(m => m.SignupCModule)
  },
  {
    path: 'd',
    loadChildren: () => import('./layout-d/layout-d.module').then(m => m.LayoutDModule),
  },
  {
    path: 'e',
    loadChildren: () => import('./layout-admin/layout-e.module').then(m => m.LayoutEModule),
  },
  {
    path: 'f/:id',
    loadChildren: () => import('./layout-f/layout-f.module').then(m => m.LayoutFModule),
  },
  {
    path: '',
    loadChildren: () => import('./layout/layout.module').then(m => m.LayoutModule),
  },
  { path: '**', redirectTo: '/', pathMatch: 'full' }
];

And what I need is a way of using userA.scss in both path a and c and only if they are activated.

I wanted to use a common module which would be loaded once and so the SCSS only compiled once but I am really at a loss how to. I was thinking maybe I could somehow make a router group that could encompass both of these routes.

Is there anyway I can achieve this to make large style sheets only compile once?

R. Richards
  • 24,603
  • 10
  • 64
  • 64
Sammaye
  • 43,242
  • 7
  • 104
  • 146

1 Answers1

1

One possibility would be to load both through the normal angular.json approach.

To prevent them from colliding, wrap the contents of each file in a top-level selector.

userA.scss:

.userA {
    // contents of userA.scss
}

userB.scss:

.userB {
    // contents of userB.scss
}

Then apply the class to each section of your site for whichever stylesheet is needed.

There may be better ways to prefix the selectors, but the basic concept is the same.

Ryan
  • 550
  • 4
  • 9
  • Problem is that these scss contain selectors themselves, sorry, should have clarified the complexity of the scss files – Sammaye Jul 28 '22 at 18:27
  • Maybe I'm missing something, but in .scss files, you can have selectors within selectors. – Ryan Jul 28 '22 at 18:29
  • Wait, do imports work in selectors? – Sammaye Jul 28 '22 at 18:30
  • 1
    Oooh they do, ok, let me give this a go – Sammaye Jul 28 '22 at 18:31
  • Ah close, but no, there are some things that don't work like this, such as the :root selector – Sammaye Jul 28 '22 at 19:12
  • I understand your pain, working with old bloated CSS is the worst. Depending on how complex the logic is to determine which file to use, you could dynamically add the appropriate class to the HTML element. Not the simplest approach, but not the simplest problem either. – Ryan Jul 28 '22 at 19:43
  • The logic could be contained in a directive (on the HTML element) with a @HostBinding. This thread has some examples: https://stackoverflow.com/a/43820610/3736341 – Ryan Jul 28 '22 at 19:45