Импорт SCSS относительно корня

Я занимаюсь рефакторингом приложения Angular и, перемещая компоненты в новые каталоги, я нахожу, что обработка путей @import в файлах SCSS компонентов становится немного утомительной.

Например, допустим, у меня есть файл src/_mixins.scss в корне моего приложения, а компонент src/app/my-widget/my-widget.component.scss импортирует SCSS как @import '../../mixins'; , Все хорошо.

Но затем я решаю, что my-widget.component действительно является "разделяемым компонентом" в другом компоненте my-thingy.component, поэтому я создаю shared папку в src/app/my-thingy и перемещаю все, что было в src/app/my-widget в него.

Я надеюсь, что вы все еще со мной... Итак, теперь у меня есть src/app/my-thingy/shared/my-widget и я @import '../../../../mixins' свой файл SCSS для импорта @import '../../../../mixins'.

Примечание. Это упрощенный пример. Некоторые пути становятся относительно глубокими (не каламбур... или не так?) И все это . и / немного много.

TL; DR

Было бы очень удобно, если бы с самого начала я мог просто импортировать _mixins.scss относительно корня во все файлы SCSS моих компонентов, чтобы мне не приходилось @import путями @import при рефакторинге. (Например, что-то @import '~/mixins'). Существует ли что-то подобное?

Что я пробовал (и, к сожалению, не получилось):

  1. @import '~/mixins';/** я had real hope for this one **/
  2. @import 'mixins';/** Just being overly optimistic here **/
  3. @import '~//mixins';/** Now I'm just making stuff up **/

Я понимаю, что мне уже придется изменить мои файлы модов, чтобы они указывали на новый путь компонента со всеми этими "движущимися вещами", но... эй, еще одна вещь, верно?

Ответ 1

  • Если вы используете CLI Angular, посмотрите на Глобальные стили, "stylePreprocessorOptions" вариант специально.
  • Для webpack вы можете настроить includePaths в конфигурации плагина sassLoader.
  • И он похож на gulp builds, вы передаете includePaths в sass-плагин.

Независимо от вашего инструмента построения, sass будет обрабатывать эти пути как root, поэтому вы можете импортировать их напрямую, а с помощью:

includePaths: ["anywhere/on/my/disk"]

вы можете просто @import 'styles' вместо @import 'anywhere/on/my/disk/styles'.

Ответ 2

Вы также можете использовать {} для ссылки на верхний уровень пути к проекту, поэтому что-то подобное будет работать.

@import "{}/node_modules/module-name/stylesheet";

Ответ 3

Пути определения зависят от вашей версии Angular. В нашем проекте старые версии используют angular-cli.json а новые - angular.json:

в "@angular/cli": "~ 1.7.4" используйте angular-cli.json по этому пути:

"stylePreprocessorOptions": {
    "includePaths": [
      "../src",
      "./scss"
    ]
  },

в "@angular/cli": "~ 7.0.6", используйте это:

"stylePreprocessorOptions": {
    "includePaths": [
       "./src",
       "./src/scss"
    ]
 }

Ответ 4

решение для angular-cli заключается в добавлении stylePreprocessorOptions в .angular-cli.json.

{
    "apps": [{
        ...
        "stylePreprocessorOptions": {
            "includePaths": [
                "./app/global-styles"
            ]
        },
        ...
    }]
}

если вы используете рендеринг на стороне сервера, не забудьте добавить это как для ssr и для основной сборки приложения - в противном случае вы получите NodeInvocationException: Prerendering failed because of error: Error: Cannot find module 'C:\Users\...\ClientApp\dist-server\main.bundle.js'

{
    "apps": [{
            ...
            "outDir": "dist",
            "stylePreprocessorOptions": {
                "includePaths": [
                    "./app/global-styles"
                ]
            },
            ...
        },
        {
            ...
            "name": "ssr",
            "outDir": "dist-server",
            "stylePreprocessorOptions": {
                "includePaths": [
                    "./app/global-styles"
                ]
            },
            ...
        }
    ]
}