ОБНОВЛЕНИЕ: Этот вопрос был помечен как дубликат этого, но посмотрите приложение в конце этого ответа, чтобы узнать, что этот вопрос не задает, а какой ответ не отвечает.
Я работаю над веб-приложением, которое использует Bootstrap 3. У меня есть базовая 3-уровневая архитектура переопределения, где 1) Bootstrap _variables.scss содержит основные переменные, 2) _app-variables.scss содержит базовые переменные приложения, которые переопределяют Bootstrap _variables.scss и 3) _client-variables.scss содержит специфичные для клиента настройки, которые переопределяют _app-variables.scss. Либо # 2 или # 3 (или оба) могут быть пустыми файлами. Итак, здесь порядок переопределения:
_variables.scss // Bootstrap core
_app-variables.scss // App base
_client-variables.scss // Client-specific
Теоретически достаточно просто, но проблема возникает из-за того, что я назову "переменными зависимостями" - где переменные определяются как другие переменные. Например:
$brand: blue;
$text: $brand;
Теперь допустим, что указанные выше переменные определены в _variables.scss. Затем, скажем, в _app-variables.scss, я переопределяю только переменную $ brand, чтобы сделать ее красной: $brand: red
. Так как SASS интерпретирует код построчно, сначала он установит $ brand в синий, затем он установит $ text в синий (потому что $ brand в этот момент синий), и, наконец, он установит $ brand в красный. Таким образом, конечный результат заключается в том, что изменение $ brand впоследствии не влияет на переменные, которые основывались на старой стоимости $ brand:
_variables.scss
---------------------
$brand: blue;
$text: $brand; // $text = blue
.
.
.
_app-variables.scss
---------------------
$brand: red; // this does not affect $text, b/c $text was already set to blue above.
Но очевидно, что это не то, чего я хочу - я хочу, чтобы моя смена бренда влияла на все, что от этого зависит. Чтобы правильно переопределить переменные, я в настоящее время просто делаю полную копию _variables.scss в _app-variables.scss, а затем с этого момента делаю изменения внутри _app-переменных. И точно так же я делаю полную копию _app-variables.scss в _client-variables.scss, а затем делаю изменения в _client-variables.scss на этом этапе. Очевидно, что это не идеально (занижение) с точки зрения обслуживания - каждый раз, когда я делаю изменения в _variables.scss (в случае обновления Bootstrap) или _app-variables.scss, мне приходится вручную вносить изменения вниз стек переопределения файлов. Кроме того, мне нужно переопределить тонну переменных, которые я даже не могу переопределить.
Я обнаружил, что LESS имеет то, что они называют "отложенной загрузкой" (http://lesscss.org/features/#variables-feature-lazy-loading), где последнее определение переменной используется везде, даже перед последним определением. Я верю, что это решит мою проблему. Но кто-нибудь знает правильное решение для переопределения переменных с использованием SASS?
ДОПОЛНЕНИЕ:
Вот одна техника, которую я уже обдумал: включите файлы в обратном порядке, используя !default
для всех переменных (эта техника также была предложена в ответе на этот вопрос). Итак, вот как это закончится:
_app-variables.scss
---------------------
$brand: red !default; // $brand is set to red here, overriding _variables.scss blue.
.
.
.
_variables.scss
---------------------
$brand: blue !default; // brand already set in _app-variables.scss, so not overridden here.
$text: $brand !default; // $text = red (desired behavior)
Так что это решение почти идеально. Однако, теперь в моих файлах переопределения у меня нет доступа к переменным, определенным в Bootstrap _variables.scss, которые мне понадобились бы, если бы я хотел определить свои переопределения переменных (или мои собственные дополнительные пользовательские переменные), используя другие переменные Bootstrap. Например, я могу захотеть сделать: $custom-var: $grid-gutter-width / 2;