компилируется...
Перейти к основному содержанию
Рекомендовать во Вконтакте Рекомендовать в Фейсбуке Рекомендовать в Твиттере

Новая система модулей в SASS

Оригинал: http://sass.logdown.com/posts/7858341-the-module-system-is-launched

Команда Sass уже много лет знает, что правило @import, одно из самых первых дополнений к Sass, было не таким хорошим, как мы этого хотели. Это вызывало массу проблем у наших пользователей:

  • Практически невозможно было определить, где изначально была определена переменная, миксин или функция, поскольку все, что определено в одной таблице стилей, было доступно для всех таблиц стилей, которые были импортированы после нее.
  • Даже если вы решили явно импортировать каждую таблицу стилей, определяющую элементы стилей, которые вы использовали, вы будете иметь дублирующий CSS и странные побочные эффекты, потому что таблицы стилей загружались с нуля каждый раз, когда они импортировались.
  • Было небезопасно использовать краткие и простые имена, потому что всегда была вероятность того, что некоторые другие таблицы стилей в других местах вашего приложения будут использовать одно и то же имя и испортят вашу логику. Для обеспечения безопасности пользователям приходилось вручную добавлять длинные, неудобные пространства имен ко всему, что они определяли.
  • У авторов библиотек не было возможности гарантировать, что их приватные хелперы не будут доступны пользователям, находящимся ниже по цепочке, что приводило к путанице и головной боли, связанной с обратной совместимостью.
  • Правило @extend могло влиять на любой селектор в любом месте таблицы стилей, а не только на те, которые его автор явно выбрал для расширения.

Мы также знали, что любая замена, которую мы хотели внедрить, должна быть спроектирована и разработана с предельной тщательностью, чтобы обеспечить прочную основу для будущего развития Sass. За последние несколько лет мы обсудили, спроектировали и разработали совершенно новую модульную систему, которая решает эти проблемы и многое другое.

Обратите внимание, что новая система модулей полностью обратно совместима со старой. Существующие функции не были удалены или устарели, и ваши текущие таблицы стилей Sass будут работать так же, как и прежде. Мы разработали модульную систему так, чтобы она была полностью совместима с @import, чтобы авторам таблиц стилей было легко переходить неё постепенно. Мы планируем в конечном итоге избавиться от @import, но только после того, как у всех будет возможность мигрировать.

@use, сердце модульной системы

Правило @use является основной заменой @import: оно делает CSS, переменные, миксины и функции из другой таблицы стилей доступными в вашей таблице стилей. По умолчанию переменные, миксины и функции доступны в пространстве имен на основе базового имени URL-адреса.

@use "bootstrap";

.element {
  background-color: bootstrap.$body-bg;
  @include bootstrap.float-left;
}

В дополнение к пространству имен, есть несколько важных различий между @use и @import:

  • @use выполняет только таблицу стилей и включает её CSS только один раз, независимо от того, сколько раз эта таблица стилей используется.
  • @use делает имена доступными только в текущей таблице стилей, а не глобально.
  • Свойства, имена которых начинаются с - или _ являются приватными для текущей таблицы стилей с @use.
  • Если таблица стилей содержит @extend, это расширение применяется только к таблицам стилей, которые она импортирует, а не к таблицам стилей, которые ее импортирует.

Обратите внимание, что селекторы заполнители (%strong-alert начинаются со знака %) не являются пространством имен, но они соблюдают приватность.

Управление пространствами имен

Хотя пространство имен правила @use по умолчанию определяется базовым именем его URL-адреса, его также можно явно указать с помощью as.

@use "bootstrap" as b;

.element {
  @include b.float-left;
}

Специальная конструкция as * также может использоваться для включения всех стилей в пространство имен верхнего уровня. Обратите внимание, что если несколько модулей предоставляют элементы с одинаковым именем и используются как *, Sass выдаст ошибку.

@use "bootstrap" as *;

.element {
  @include float-left;
}

Конфигурирование библиотек

При использовании @import, sass стили часто конфигурируются путем установки глобальных переменных с параметром !default, и другие пользовательские стили переопределяют эти значения. Поскольку переменные больше не являются глобальными при использовании @use, поддерживается более явный способ настройки библиотек: выражение with.

Старый способ:

// bootstrap.scss
$paragraph-margin-bottom: 1rem !default;

p {
  margin-top: 0;
  margin-bottom: $paragraph-margin-bottom;
}

Новый способ:

@use "bootstrap" with (

  $paragraph-margin-bottom: 1.2rem

);

Этот вариант устанавливает значение переменной $paragraph-margin-bottom равным 1,2rem, перед вычислением её значения. Блок с with допускает только те переменные, которые определены (или переданы) импортируемым модулем, и только если они определены с !default, так что пользователи защищены от опечаток.

@forward, для авторов библиотек

Правило @forward включает переменные, миксины и функции другого модуля как часть API, предоставляемого текущим модулем, не делая их видимыми для кода в текущем модуле. Это позволяет авторам библиотек разделять свою библиотеку по множеству различных файлов, не жертвуя локальностью в этих файлах. В отличие от @use, @forward не добавляет к именам пространства имен.

// bootstrap.scss
@forward "functions";
@forward "variables";
@forward "mixins";

Контроль видимости

Правило @forward может показывать только определенные имена:

@forward "functions" show color-yiq;

Он также может скрывать имена, которые предназначены для приватной библиотеки:

@forward "functions" hide assert-ascending;

Дополнительный префикс

Если вы перенаправляете дочерний модуль через модуль «все в одном», вы можете вручную добавить к этому модулю некоторое пространство имен. Вы можете сделать это с помощью конструкции as, которое добавляет префикс к каждому перенаправляемому свойству модуля:

// material/_index.scss
@forward "theme" as theme-*;

Таким образом, пользователи могут использовать модуль "все-в-одном" с хорошо продуманными именами для переменных темы:

@use "material" with ($theme-primary: blue);

или они могут использовать дочерний модуль с похожими именами:

@use "material/theme" with ($primary: blue);

Встроенные модули

Новая модульная система также добавляет встроенные модули (sass:math, sass:color, sass:string, sass:list, sass:map, sass:selector и sass:meta) для хранения всех существующих встроенных функций Sass. Поскольку эти модули (как правило) импортируются с пространством имен, теперь гораздо проще использовать функции Sass без конфликтов с простыми CSS-функциями.

Это, в свою очередь, делает гораздо более безопасным добавление новых функций в Sass. В будущем мы планируем добавить ряд удобных функций к этим модулям.

Переименованные функции

Некоторые функции во встроенных модулях имеют имена, отличные от названий глобальных функций. Встроенные функции, которые уже имели собственные пространства имен, такие как map-get(), удаляют эти пространства имен во встроенных модулях, поэтому вы можете просто написать map.get(). Аналогичным образом, adjust-color(), scale-color() и change-color() теперь включают в себя color.adjust(), color.scale() и color.change().

Мы также воспользовались этой возможностью, чтобы изменить несколько запутанных старых имен функций. unitless() теперь math.is-unitless(), и compact() теперь math.compatible().

Удаленные функции

Сокращенные цветовые функции Sass: lighten(), darken(), saturate(), desaturate(), opacify(), fade-in(), transparentize() и fade-out() имели очень непрозрачное поведение. Вместо того, чтобы плавно масштабировать связанные с ними атрибуты, они просто увеличивали их на статическую величину, так что lighten($color, 20%) возвращает белый для цвета с яркостью 85%, вместо возвращения цвета с 88% светлотой (20% ближе к полной белости).

Чтобы помочь нам встать на путь исправления, эти функции (наряду с функцией adjust-hue()) не входят в состав новых встроенных модулей. Вы все еще можете получить тот же эффект, вызывая color.adjust() - например, lighten($color, $amount) эквивалентен color.adjust($color, $lightness: $amount) - но мы рекомендуем использовать color.scale(), если это возможно из-за большей интуитивности.

В будущем мы планируем добавить функцию color.lighten() и подобные ей функции в качестве сокращения для color.scale().

meta.load-css()

Новая модульная система поставляется с новым встроенным миксином meta.load-css($url, $with: ()). Этот миксин динамически загружает модуль с заданным URL и включает его CSS (хотя его функции, переменные и миксины не доступны). Это замена для вложенного импорта, и она помогает решить некоторые сценарии использования динамического импорта без многочисленных проблем, которые могут возникнуть, если новые элементы могут быть загружены динамически.

@import совместимость

Экосистема Sass не переключится на @use в одночасье, поэтому в настоящее время она должна хорошо взаимодействовать с @import. Эта схема будет поддерживается в обоих направлениях:

  • Если файл, содержащий @import используется в @use, все его елементы в глобальном пространстве имен рассматриваются как один модуль. Далее элементы этого модуля обычно ссылаются на использование его пространства имен.

Для того, чтобы библиотеки могли поддерживать свой существующий API, ориентированный на @import, с явным пространством имен, где это необходимо, @import-совместимость позволяет добавить поддержку файлов, видимых только для @import, а не для @use. Записываются это так: "file.import.scss", и импортируются при записи @import "file".

Автоматическая миграция

Одновременно с запуском новой модульной системы мы запускаем новый автоматизированный Sass-мигратор. Этот инструмент позволяет легко перенести большинство таблиц стилей для автоматического использования новой системы модулей. Следуйте инструкциям на сайте Sass, чтобы установить его, а затем запустите его в своем приложении:

sass-migrator module --migrate-deps <path/to/style.scss>

Флаг --migrate-deps указывает на то, что мигратор должен перенести не только передаваемый файл, но и все импортируемые данные. Мигратор автоматически получит файлы, импортированные с помощью синтаксиса node_modules Webpack, но вы также можете передать явные пути загрузки с флагом --load-paths.

Если вы хотите, чтобы мигратор сообщал вам, какие изменения он будет вносить, не внося их на самом деле, передайте оба флага --dry-run и --verbose, чтобы он просто распечатывал изменения, которые он будет вносить, не сохраняя их на диск.

Миграция библиотеки

Если вы хотите перенести библиотеку Sass, предназначенную для пользователей которые будут загружать её и использовать в своих приложениях, выполните следующее:

sass-migrator module --migrate-deps --forward=all <path/to/index.scss>

Флаг --forward указывает на то, что мигратор должен добавить правила @forward, чтобы пользователи могли загружать все миксины, переменные и функции, определенные вашей библиотекой, с помощью только одного вызова @use.

Если вы добавили в библиотеку пространство имен вручную, чтобы избежать конфликтов имен, мигратор удалит его, если вы передадите флаг --remove-prefix. Вы даже можете выбрать переадресацию только тех свойств, которые изначально имели этот префикс, передав --forward=prefixed.

Планы на будущее

Команда Sass хочет предоставить достаточное количество времени, когда @use и @import могут сосуществовать, чтобы помочь экосистеме плавно перейти на новую систему. Однако полная отмена @import является конечной целью для обеспечения простоты, производительности и совместимости с CSS. В связи с этим мы планируем постепенно отказываться от поддержки @import в следующие сроки:

  • Через год после того, как Dart Sass и LibSass запустили поддержку модульной системы, или через два года после того, как Dart Sass запустит поддержку модульной системы, в зависимости от того, что наступит раньше (не позднее 1 октября 2021 года), мы отменим вызовы @import, а также глобальных функций основной библиотеки, которые можно будет сделать через модули.
  • Через год после того, как это устаревание (deprecation) вступит в силу (не позднее 1 октября 2022 года), мы полностью прекратим поддержку @import и большинства глобальных функций. Это будет включать выпуск основной версии для всех реализаций.

Это означает, что будет как минимум два полных года, когда @import и @use будут использоваться одновременно, и, вероятно, ближе к трем годам на практике.

Комментарии

Пока что нет комментариев, вы можете быть первым.
Войти или Регистрация , чтобы оставлять комментарии.

Лучшие публикации

Популярные теги

Наш сайт использует куки. Узнайте больше о нашем использовании куки: политика в отношении файлов cookie
Наш сайт существует только благодаря показу онлайн-рекламы нашим посетителям.
Пожалуйста, поддержите нас, отключив блокировку рекламы.