В Rails 3.1 невозможно ли вообще избежать дублирования копий таблиц стилей? - программирование
Подтвердить что ты не робот

В Rails 3.1 невозможно ли вообще избежать дублирования копий таблиц стилей?

Я столкнулся с проблемой расстраивания при попытке совместного использования переменных и микшинов в стилях стилей Sass.

Если я использую @import для включения глобальной таблицы стилей, которая включает в себя глобальные цвета, mixins и т.д., она снова включается, когда Rails объединяет все таблицы стилей, указанные в файле манифеста.

В качестве альтернативы, если мой файл манифеста не содержит глобальную таблицу стилей, но несколько файлов в манифесте импортируют его, глобальная таблица стилей будет по-прежнему включаться более одного раза. <Сильного > GAH.

Как вы можете обойти это? У Сасса есть секретные охранники? Я делаю что-то ужасно неправильно?

4b9b3361

Ответ 1

Я не понимаю, почему это проблема для вашего конкретного вопроса. Объявления переменных и микширования не должны приводить к какому-либо селектору или блокам объявлений в созданном файле css. Однако, когда вы используете mixins для нескольких селекторов, соответствующие объявления включаются для каждого такого селектора. Так SASS обрабатывает его.

До тех пор, пока это только переменные и mixins, не имеет значения, включены ли они несколько раз в файл манифеста, поскольку это не влияет на скомпилированный файл. На сайте node я считаю, что это хороший стиль, который SASS заставляет вас явно объявлять зависимости каждого файла.

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

Например, при использовании bootstrap-sass, только определения mixins и переменных могут быть добавлены в область с помощью;

@import "bootstrap/variables";
@import "bootstrap/mixins";

Ответ 2

Вы можете обойти это, сделав следующее:

/* 
 * application.css.scss
 *= require_self
 * ----> Note the missing = require_tree 
*/  

@import "global.css.scss"; // Defines global mixins etc
@import "users.css.scss"; // Uses mixins defined in _global.css.scss

Затем не импортировать global.css.scss внутри users.css.scss или любые другие зависимые файлы.

Если вы еще этого не сделали, проверьте Ryan Bates screencast на SASS и звездочки в рельсах 3.1, это то, что он делает для решения этой проблемы проблема.

Ответ 3

Пока, пока SASS 4 не будет выпущен, я предпочитаю модифицировать строки импорта примерно так:

@if not-imported("font") { @import "font"; }

Вам понадобится функция с именем not-imported, а затем, конечно, выглядит так:

$imported-once-files: () !default;

@function not-imported($name) {
  $module_index: index($imported-once-files, $name);
  @if (($module_index == null) or ($module_index == false)) {
    $imported-once-files: append($imported-once-files, $name);
    @return true;
  }
  @return false;
}

Это прекрасно работает и поддерживает совместимость с другими инструментами (например, StyleDocco). Я написал об этом, здесь

Ответ 4

В настоящее время невозможно использовать SASS для динамического включения файлов. @import не может использоваться в директивах управления (например, @if) или mixins, использование переменной в директиве import является ошибочным синтаксисом, и нет никакой директивы для окончательного завершения файла раньше (эффективно позволит условный импорт). Однако вы можете решить свою проблему, изменив структуру своих правил стиля.

Примечание

Существует плагин SASS, который будет изменять @import только включать файлы один раз. Тем не менее,

  • В вашем коде будет добавлена ​​зависимость от среды
  • Нам всем было бы лучше понять, как правила стиля должны быть структурированы, что позволит избежать любых повторяющихся правил.
  • @import может скоро устарел. Команда SASS планирует "крупномасштабная редизайн импорта ", поэтому защита повторного импорта может быть частью будущих версий SASS, поскольку популярныйзапрошенная функция.

Решение

Если у вас есть стили, которые условно включены из нескольких файлов, они не являются "глобальными" стилями. Эти стили должны быть инкапсулированы в mixins, в файлах "module" или "library". Основная идея заключается в том, что при импорте одного такого файла не будет выводиться какой-либо css. Таким образом, вы можете импортировать эти файлы избыточно, чтобы вы могли использовать микшины везде, где они вам нужны.

Если вам нужно сделать это с помощью переменных, то:

  • Обязательно определите переменные перед включением mixins, иначе они будут доступны только в области mixin . Хороший способ сделать это - определить все переменные по умолчанию в файле vars.sass и импортировать их вместе с импортированными модулями/библиотеками, чтобы переменные были доступны по всему миру.
  • Определите переменные с помощью !default в mixin, поэтому его можно переопределить еще до вызова mixin (например, в файле vars.sass).

Если у вас есть стили верхнего уровня, которые вы хотите обеспечить, определены без жестких правил включения, вы можете использовать этот mixin:

$was-defined: () !default;
@mixin define-once($name) {
    @if not index($was-defined, $name) {
        $was-defined: append($was-defined, $name);
        @content;
    }
}

// Example:
@include define-once('body-typography') {
    body {
        font-size: 100%;
        line-height: 2em;
        color: #444;
        font-family: monospace;
    }
}

Для более эффективной практики структурирования вашего кода, например, этой статьи.