Статьи

Как эффективно использовать предупреждения и ошибки в Sass

Ниже приведен небольшой отрывок из нашей книги « Jump Start Sass» , написанной Уго Жирауделем и Мириам Сюзанн. Это руководство для начинающих Sass. Члены SitePoint Premium получают доступ к своему членству, или вы можете купить копию в магазинах по всему миру.

Наше невероятное путешествие по Sass медленно подходит к концу, и пока вы отлично справляетесь! Перед рассмотрением архитектуры проекта осталась одна техническая глава, и тогда вы будете полностью готовы написать код Sass в своих собственных проектах.

Теперь мы будем смотреть на предупреждения и ошибки. Оба формируют одностороннюю систему связи между программой (в данном случае Sass) и разработчиком (вами). Если вас интересует проблема ошибок в мире CSS, помните, что вы уже знаете ответ. Всякий раз, когда вы забываете точку с запятой или неправильно используете функцию, Sass выдает ошибку, объясняя, что вы сделали неправильно, и как вы можете это исправить, к счастью! Было бы очень больно копаться в коде, чтобы выяснить, что пошло не так.

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

Как предупреждения, так и ошибки выводятся в текущем выходном канале. При компиляции Sass вручную или с помощью инструмента через интерфейс командной строки (CLI), такого как Grunt или Gulp , поток вывода является консолью. Для инструментов с пользовательским интерфейсом, таких как Codekit или Prepros , вполне вероятно, что они перехватывают и отображают предупреждения и ошибки как часть своего интерфейса. Онлайновым игровым площадкам, таким как CodePen и SassMeister, удается ловить ошибки, но не предупреждения, поэтому не пугайтесь, если вы не можете их там проверить.

Предупреждения

Как уже было сказано, способность генерировать предупреждения в Sass не нова. Можно отобразить сообщения или значение любого выражения SassScript в стандартный поток вывода с @warn директивы @warn .

Предупреждение не влияет на процесс компиляции; это не мешает компиляции преследовать или изменять его любым способом. Его единственная цель — отображать сообщение в консоли.

Есть много причин использовать предупреждения в Sass. Вот пара, но вы, вероятно, найдете свой собственный:

  • информирование пользователя о предположении относительно кода, чтобы избежать неожиданных и трудно отслеживаемых ошибок
  • консультирование по поводу устаревшей функции или миксина как части библиотеки или фреймворка

Отправить предупреждение очень просто: начните с директивы @warn , затем укажите, что это такое. Предупреждения обычно делаются для предоставления некоторой информации и контекста, поэтому они часто содержат предложение, объясняющее ситуацию. При этом вам не нужно использовать строку; Вы можете предупредить с помощью номера, списка, карты — что угодно. Здесь мы печатаем строку:

 @warn 'Uh-oh, something looks weird.'; 

При использовании обычного клиента CLI это предупреждение выдаст следующий вывод:

 WARNING: Uh-oh, something looks weird. on line 1 of /Users/hgiraudel/jump-start-sass/warning.scss 

Эй, это мило, не правда ли? Хотя это предупреждение далеко не полезно. Это говорит о том, что что-то выглядит странно, но не говорит, что, почему или что можно сделать, чтобы это не выглядело странно. Мы обсудим, как мы можем улучшить предупреждения дальше.

Давайте теперь перейдем к более серьезному примеру, когда мы знаем, как использовать эту функцию. Представьте, что у нас есть пользовательская функция Sass, которая пытается преобразовать значение пикселя в единицу em :

 @function px-to-em($value, $base-font-size: 16px) { @return ($value / $base-font-size) * 1em; } // Usage .foo { font-size: px-to-em(42px); // 2.625em } 

Все хорошо. Теперь, что происходит, когда передается функция без единиц — например, 42 — в функцию? Возможно, вы уже догадались, но так как это не совсем очевидно, я дам вам ответ:

 2.625em/px isn't a valid CSS value. 

Это происходит потому, что вы пытаетесь выполнить расчет между несовместимыми единицами ( px и em ). Чтобы обойти эту проблему, мы можем предположить, что значение без единиц измерения выражается в пикселях, и сначала преобразовать его:

 @function px-to-em($value, $base-font-size: 16px) { @if unitless($value) { @warn 'Assuming value `#{$value}` to be in pixels; attempting to convert it.'; $value: $value * 1px; } @return ($value / $base-font-size) * 1em; } 

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

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

Другим практическим примером было бы предостеречь от использования устаревшей функции или миксина. Возможно, вы уже слышали или использовали Bourbon , легковесную библиотеку миксинов для Sass. Бурбон активно поддерживается, и иногда требуется удаление помощников из библиотеки. Чтобы избежать внезапного нарушения оды человека, Бурбон предупреждает о будущей амортизации еще до того, как он фактически удалит миксины:

 @mixin inline-block { display: inline-block; @warn 'The `inline-block` mixin is deprecated and will be removed in the next major version release.'; } 

Умная! Люди, которые все еще используют inline-block миксин из Бурбона, знают, что библиотека полностью удалит его в следующей версии, поэтому они знают, что нужно начинать обновлять свою кодовую базу для удаления миксина.

Разница между @warn и @debug

Вы можете или не можете быть знакомы с директивой @debug , которая печатает значение выражения SassScript в стандартный поток вывода таким же образом, как @warn . Вы можете быть удивлены, почему есть две функции, выполняющие одну и ту же задачу, и в чем может быть разница между ними.

Ну, есть два основных различия между предупреждением о значении и отладкой значения. Во-первых, предупреждения можно отключить с помощью quiet опции. Отладки, с другой стороны, всегда будут напечатаны, так что вы не забудете их удалить, когда закончите с ними.

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

Директива @debug может действительно пригодиться, когда вы хотите знать, что находится внутри переменной, например:

 @debug $base-font-size; 

ошибки

Предупреждения и ошибки в Sass ведут себя примерно одинаково, поэтому изучение ошибок станет легким делом теперь, когда вы отлично знакомы с предупреждениями! Единственная разница между ошибкой и предупреждением состоит в том, что, как вы уже догадались, ошибка останавливает процесс компиляции.

Использование ошибок может быть полезно, например, при проверке параметров из миксинов и функций. В предыдущем разделе это работало, даже если данный аргумент был не совсем таким, как ожидалось, но мы не можем (и не должны) делать это всегда. В большинстве случаев, если аргументы недопустимы, лучше выдать ошибку, чтобы автор таблицы стилей мог решить проблему.

Вы можете @error ошибку, используя директиву @error . Что касается предупреждений, вы можете передать что угодно этой директиве — не обязательно строку, хотя обычно имеет смысл предоставить четкий контекст. Аргумент (то, что вы даете директиве @error ) будет напечатан в стандартном потоке вывода, а также трассировку стека, чтобы дать более полное представление о проблеме. Процесс компиляции немедленно остановится.

Давайте начнем с ошибки, допущенной Гэндальфом:

 @error 'YOUUUUU! SHALL NOT. PASS.'; 

Вывод может зависеть от того, как вы компилируете свои таблицы стилей, поскольку некоторые инструменты определенным образом распознают и улучшают ошибки. Используя стандартный sass Ruby (gem), вот как это выглядит:

 Error: YOUUUUU! SHALL NOT. PASS. on line 1 of /Users/hgiraudel/jump-start-sass/error.scss Use --trace for backtrace. 

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

Время взглянуть на реальный практический пример. Давайте начнем с написания небольшой функции, помогающей получить доступ к глубоко уложенным значениям в картах, map-deep-get(..) :

 @function map-deep-get($map, $keys...) { @each $key in $keys { $map: map-get($map, $key); @if (type-of($map) == 'null') { @return $map; } } @return $map; } 

Давайте сделаем это с помощью пользовательских ошибок. Но сначала рассмотрим следующую карту и вызов map-deep-get(..) :

 $map: ( 'foo': ( 'bar': ( 'baz': 42 ) ) ); $value: map-deep-get($map, 'foo', 'bar', 'baz', 'qux'); 

Как вы могли заметить, на карте отсутствует ключ qux вложенный в baz . Действительно, baz даже не связана с картой; вместо этого он отображается на число ( 42 ). Если мы попытаемся выполнить этот код, он даст:

 Error: 42 is not a map for `map-get` on line 1 of /Users/hgiraudel/jump-start-sass/error.scss 

Sass пытается выполнить map-get(..) на 42 и выдает ошибку, потому что это не может быть сделано. Хотя сообщение об ошибке правильное, оно не очень полезно. Было бы полезно узнать название ключа, вызвавшего проблему. Мы можем это сделать!

Мы уже проверяем, является ли $map null чтобы выполнить ранний возврат, чтобы избежать ошибки компиляции, если ключ не существует. Мы можем выполнить вторую проверку, чтобы убедиться, что карта действительно является картой, или мы выдаем значимую ошибку:

 @function map-deep-get($map, $keys...) { @each $key in $keys { $map: map-get($map, $key); // If `$map` does not contain the next key, return `null` @if type-of($map) == 'null' { @return $map; } // If `$map` is not a map, throw an error @if type-of($map) != 'map' { @error 'Key `#{$key}` is not associated with a map but a #{type-of($map)} (`#{$map}`).'; } } @return $map; } 

Если мы снова запустим наш предыдущий фрагмент, вот результат:

 Error: Key `baz` is not associated with a map but a number (`42`). on line 1 of /Users/hgiraudel/jump-start-sass/error.scss 

Это гораздо лучше! Теперь легко исправить нашу карту и / или вызов нашей функции благодаря полезному сообщению об ошибке.

Завершение дела

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

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

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