Настройка CSS предпроцессора в Angular с Nx

Aleksandr Serenko
F.A.F.N.U.R
Published in
4 min readAug 10, 2019

Во современных CSS framework’ах используются CSS Preprocessor’ы. И для того, чтобы эффективно их использовать, необходимо сконфигурировать CSS предпроцессор для корректной работы с monorepo.

В продолжении статей, добавим в nx monorepo поддержку SCSS. Основные задачи:

  • Должны быть общие стили и миксины доступные как в приложениях, так и в библиотеках
  • Для каждого нового экземпляра приложения должна быть возможность изменить, переопределить общие стили, которые доступны в репозитории, а также эти изменения повлияли на библиотеки.

Данными требованиями, достигается следующие:

Допустим, есть общие стили, в которых есть переменная — $rootWidth?равная по-умолчанию 1200px, которая используется для установки ширины сайта. Есть некоторая библиотека, которая использует данную переменную, для отрисовки ширины блока. Помимо этого, есть переменные отвечающие за цвет.

Есть две имплементации приложения, в одной из которых в первом приложении $rootWidth = 1600px, а во втором 800px; в первом приложении используется светлая тема (белый фон и черный текст), а во втором приложении темная тема (черный фон и белый текст).

И основная задача заключается в том, чтобы для каждого приложения, общие библиотеки, созданные в monorepo, корректно компилировали стили, и соответственно для темного приложения, библиотека имела темную тему, а для светлого — светлую.

Создание common styles

Создадим в корне monorepo папку styles. И добавим в эту папку несколько файлов со следующей структурой:

--common
----buttons.scss
----fonts.scss
----forms.scss
----typography.scss
--style.scss
--utils.scss
--variables.scss

Файл variables.scss, содержит переменные:

$default-bg: #fff !default;
$default-color: #000 !default;

Файл utils.scss содержит файл со всеми переменными и миксинами:

// Mixins
//@import './mixins';

// Variables
@import './variables';

Но так как пока нет потребности в mixins, в данном руководстве они закомментирваны.

В файле style.scss подключаются все common стили, которые должны быть при загрузке проекта.

// Variables and mixins
@import 'utils';

// Commons
@import 'common/typography';
@import 'common/buttons';
@import 'common/fonts';
@import 'common/forms';

Файлы в common переопределяют любые дефолтные стили (браузера, normalize.css или reset.css)

В buttons.scss приведен пример пустого импорта, так как в проекте еще нет кастомных кнопок:

@import '../utils';

В fonts.scss подключаются все внешние и локальные шрифты:

// prettier-ignore
@import url(//fonts.googleapis.com/css?family=Roboto:100,300,400,500,700&subset=cyrillic,cyrillic-ext);

В данном случае, подключаем шрифт Roboto с google fonts.

В forms.scss задаем стили для стандартных HTML элементов форм:

@import '../utils';

textarea {
max-width: 100%;
}

Файл typography.scss содержит стили применяемые ко всем элементам или группам элементов в приложении:

@import '../utils';

* {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

html,
body {
box-sizing: border-box;
font-size: 16px;
font-family: 'Roboto', sans-serif;
font-weight: 400;
}

a,
button {
transition: all 0.25s ease;
}

// Custom reset styles. Will be removed
html,
body {
min-width: 100%;
margin: 0;
padding: 0;
}

html {
height: 100%;
}
body {
min-height: 100%;
}

Подключение common styles в Angular

Общие стили созданы, теперь создадим файлы, которые будут использоваться для конкретного приложения, в которых при необходимости можно будет переопределить общие стили.

Склонируем последний проект и назовем его common-styles.

В папке app склонированного приложения создадим папку styles со следующими файлами:

--styles
----style.scss
----utils.scss

Файл style.scss соответственно будет основным файлом стилей для приложения, в котором будут переопределяться общие styles:

// Import app utils
@import 'utils';

// Import common styles
@import 'styles/style';

Файл utils.scss соответственно будет переопределять стили для common utils:

// Import common utils
@import 'styles/utils';

// Override common variables and mixins
$default-bg: #300a24;
$default-color: #fff;

Для того, чтобы builder Angular мог корректно компилировать стили нужно указать пути до папки styles, хотя последние версии angular/cli могут работать и без данных настроек, однако библиотеки все-таки не увидят переопределения.

Добавим в angular.json пути для common styles в architect — build — options

"stylePreprocessorOptions": {
"includePaths": ["apps/frontend/common-styles/src/styles"]
},

Теперь создадим библиотеку, которая будет отвечать за layout’ы приложения.

ng g @nrwl/angular:lib layouts

И сгенерируем компонент, назвав его base-layout:

ng g component base-layout --project=layouts

Компонент перенесем в папку libs/layouts/src/lib/components.

Создадим просто враппер над основным контентом, для того, чтобы убедиться, что переопределения стилей работают:

<div class="layout">
<router-outlet></router-outlet>
</div>

И код BaseLayoutComponent компонента:

import { ChangeDetectionStrategy, Component } from '@angular/core';

@Component({
selector: 'medium-stories-base-layout',
templateUrl: './base-layout.component.html',
styleUrls: ['./base-layout.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class BaseLayoutComponent {}

Используем следующие стили:

@import 'utils';

:host {
display: block;
padding: 30px;
}

.layout {
background-color: $default-bg;
color: $default-color;
padding: 30px;
}

Теперь запустим и посмотрим что, получилось:

ng serve frontend-common-styles

Если бы, библиотека layouts не получила бы доступ к нашим локальным переопределениям, то плашка была бы белого цвета с черным текстом.

Продублируем настройки в проект translation-state, только удалим переопределение базового цвета и фона
apps/frontend/translation-state/src/styles/utils.scss:

// Import common utils
@import 'styles/utils';

// Override common variables and mixins

И запустим и проверим:

ng serve frontend-translation-state

Как можно убедиться, библиотека layouts использовала общие стили.

Исходники

Все исходники находятся на github, в репозитории https://github.com/Fafnur/medium-stories

Common styles реализованы в проекте frontend/common-styles.

Для того, чтобы посмотреть состояние проекта на момент написания статьи, нужно выбрать соответствующий tag — common-styles.

git checkout common-styles

Предыдущие статьи:

  1. Статья о настройке Prettier, tslint и eslint в Angular
  2. Статья про LocalStorage, SessionStorage в Angular Universal
  3. Статья про мультиязычность в Angular & Universal с помощью ngx-translate
  4. Статья про Redux в Angular с помощью Ngrx. Создание Store в Angular
  5. Статья про Тестирование Ngrx State в Angular с помощью Jest

--

--

Aleksandr Serenko
F.A.F.N.U.R

Senior Front-end Developer, Angular evangelist, Nx apologist, NodeJS warlock