<?xml version="1.0" encoding="utf-8" ?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:tt="http://teletype.in/" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"><title>Будни фронта</title><author><name>Будни фронта</name></author><id>https://teletype.in/atom/budnifronta</id><link rel="self" type="application/atom+xml" href="https://teletype.in/atom/budnifronta?offset=0"></link><link rel="alternate" type="text/html" href="https://teletype.in/@budnifronta?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=budnifronta"></link><link rel="next" type="application/rss+xml" href="https://teletype.in/atom/budnifronta?offset=10"></link><link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></link><updated>2026-04-17T23:49:52.603Z</updated><entry><id>budnifronta:Y2iGFkk9jxl</id><link rel="alternate" type="text/html" href="https://teletype.in/@budnifronta/Y2iGFkk9jxl?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=budnifronta"></link><title>Как сделать эффект печатной машинки с помощью CSS</title><published>2022-01-27T18:27:18.457Z</published><updated>2022-01-30T18:26:07.989Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img2.teletype.in/files/9e/e8/9ee865db-e8c1-408c-bc5f-ea6d9395bbc2.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://img4.teletype.in/files/bf/fb/bffbee5c-d33f-43ff-ad1f-ed69552727e3.jpeg&quot;&gt;В этой статье вы узнаете, как сделать текст вашего сайта динамичным и более привлекательным, используя эффекты печатной машинки в чистом CSS.</summary><content type="html">
  &lt;figure id=&quot;P4O9&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/bf/fb/bffbee5c-d33f-43ff-ad1f-ed69552727e3.jpeg&quot; width=&quot;1280&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;uXtz&quot;&gt;В этой статье вы узнаете, как сделать текст вашего сайта динамичным и более привлекательным, используя эффекты печатной машинки в чистом CSS.&lt;/p&gt;
  &lt;p id=&quot;NePw&quot;&gt;Эффект печатной машинки предполагает постепенное появление текста, как будто он печатается на ваших глазах.&lt;/p&gt;
  &lt;figure id=&quot;P7EJ&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/8c/7e/8c7e0a24-4b76-4f7a-8ff4-f8e5260998c2.gif&quot; width=&quot;538&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;9PID&quot;&gt;Добавление эффекта печатной машинки к фрагментам текста поможет привлечь посетителей вашего сайта и заинтересовать их в дальнейшем чтении. Эффект печатной машинки можно использовать для многих целей, например, для создания привлекательных посадочных страниц, элементов призыва к действию, персональных веб-сайтов и демонстрации кода.&lt;/p&gt;
  &lt;h2 id=&quot;Rbpg&quot;&gt;Эффект печатной машинки легко создать&lt;/h2&gt;
  &lt;p id=&quot;EVNE&quot;&gt;Все, что вам понадобится для того, чтобы разобраться в этом уроке - это базовые знания CSS и CSS-анимации.&lt;/p&gt;
  &lt;p id=&quot;OC2E&quot;&gt;Вот как будет работать эффект пишущей машинки:&lt;/p&gt;
  &lt;ul id=&quot;rf86&quot;&gt;
    &lt;li id=&quot;g6ir&quot;&gt;Анимация печатной машинки будет показывать наш текстовый элемент, изменяя его ширину от 0 до 100%, шаг за шагом, используя функцию CSS steps().&lt;/li&gt;
    &lt;li id=&quot;JbN1&quot;&gt;Анимация мигания будет анимировать курсор, который &amp;quot;набирает&amp;quot; текст.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h2 id=&quot;Jca0&quot;&gt;Создание веб-страницы для нашего эффекта набора текста&lt;/h2&gt;
  &lt;p id=&quot;vmDf&quot;&gt;Сначала создадим веб-страницу для демонстрации печатной машинки. Он будет включать контейнер &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; для нашего печатного текста с классом &lt;code&gt;typed-out&lt;/code&gt;:&lt;/p&gt;
  &lt;pre id=&quot;YWbV&quot; data-lang=&quot;html&quot;&gt;&amp;lt;!doctype html&amp;gt;
&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;Typewriter effect&amp;lt;/title&amp;gt;
    &amp;lt;style&amp;gt;
      body{
        background: navajowhite;
        background-size: cover;
        font-family: &amp;#x27;Trebuchet MS&amp;#x27;, sans-serif; 
      }
  &amp;lt;/style&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;
      &amp;lt;div class=&amp;quot;typed-out&amp;quot;&amp;gt;Web Developer&amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/pre&gt;
  &lt;h2 id=&quot;bqlb&quot;&gt;Стилизация контейнера для текста печатной машинки&lt;/h2&gt;
  &lt;p id=&quot;wsCA&quot;&gt;Теперь, когда у нас есть макет веб-страницы, давайте стилизуем &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; с помощью класса &amp;quot;typed-out&amp;quot;.&lt;/p&gt;
  &lt;pre id=&quot;Yx08&quot; data-lang=&quot;css&quot;&gt;.typed-out {
  overflow: hidden;
  border-right: .15em solid orange;
  font-size: 1.6rem;
  width: 0;
}&lt;/pre&gt;
  &lt;p id=&quot;nXRe&quot;&gt;Обратите внимание, что для того, чтобы эффект печатной машинки работал, мы добавили следующее:&lt;/p&gt;
  &lt;ul id=&quot;qXGK&quot;&gt;
    &lt;li id=&quot;Q7qh&quot;&gt;&lt;code&gt;&amp;quot;overflow: hidden;&amp;quot;&lt;/code&gt; и &lt;code&gt;&amp;quot;width: 0;&amp;quot;&lt;/code&gt;, чтобы содержимое текста не было видно до тех пор, пока не начнется эффект набора текста.&lt;/li&gt;
    &lt;li id=&quot;I2nN&quot;&gt;&lt;code&gt;&amp;quot;border-right: .15em solid orange;&amp;quot;&lt;/code&gt;, чтобы создать курсор печатной машинки.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;vkz5&quot;&gt;Перед созданием эффекта набора текста, чтобы остановить курсор на последней букве &lt;code&gt;typed-out&lt;/code&gt; элемента после того, как он будет полностью набран, как это сделала бы печатная машинка (или текстовый процессор), мы создадим контейнер для &lt;code&gt;typed-out&lt;/code&gt; элемента и добавим &lt;code&gt;display: inline-block;&lt;/code&gt;:&lt;/p&gt;
  &lt;pre id=&quot;GpnD&quot; data-lang=&quot;css&quot;&gt;.container {
  display: inline-block;
}&lt;/pre&gt;
  &lt;h2 id=&quot;eZUq&quot;&gt;Создание анимации раскрытия текста&lt;/h2&gt;
  &lt;p id=&quot;MaSo&quot;&gt;Анимация печатной машинки создаст эффект того, что текст внутри &lt;code&gt;typed-out&lt;/code&gt; элемента печатается буква за буквой. Мы будем использовать правило анимации &lt;code&gt;@keyframes&lt;/code&gt; CSS:&lt;/p&gt;
  &lt;pre id=&quot;9Nhg&quot; data-lang=&quot;css&quot;&gt;@keyframes typing {
  from { width: 0 }
  to { width: 100% }
}&lt;/pre&gt;
  &lt;p id=&quot;heI6&quot;&gt;Как вы можете видеть, все, что делает эта анимация, это изменяет ширину элемента от 0 до 100%.&lt;/p&gt;
  &lt;p id=&quot;UfBb&quot;&gt;Теперь мы включим эту анимацию в наш класс &lt;code&gt;typed-out&lt;/code&gt; и установим направление анимации на &lt;code&gt;forward&lt;/code&gt;, чтобы убедиться, что текстовый элемент не вернется к &lt;code&gt;width: 0&lt;/code&gt; после завершения анимации:&lt;/p&gt;
  &lt;pre id=&quot;SCjO&quot; data-lang=&quot;css&quot;&gt;.typed-out{
    overflow: hidden;
    border-right: .15em solid orange;
    white-space: nowrap;
    font-size: 1.6rem;
    width: 0;
    animation: typing 1s forwards;
}&lt;/pre&gt;
  &lt;p id=&quot;ucto&quot;&gt;Наш текстовый элемент будет просто раскрываться одним плавным движением слева направо:&lt;/p&gt;
  &lt;figure id=&quot;y8ZS&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/f6/1a/f61a47cd-8442-49a0-b119-7f972396fafb.png&quot; width=&quot;729&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;KZac&quot;&gt;&lt;a href=&quot;https://codepen.io/SitePoint/pen/OJjLXqE&quot; target=&quot;_blank&quot;&gt;Ссылка на Codepen&lt;/a&gt;&lt;/p&gt;
  &lt;h2 id=&quot;0fTW&quot;&gt;Добавление шагов для достижения эффекта печатной машинки&lt;/h2&gt;
  &lt;p id=&quot;vz4U&quot;&gt;Пока что наш текст раскрывается, но плавно, не раскрывая текст буква за буквой. Это начало, но, очевидно, это не то, как выглядит эффект печатной машинки.&lt;/p&gt;
  &lt;p id=&quot;9mJq&quot;&gt;Чтобы эта анимация раскрывала наш текстовый элемент буква за буквой (или по шагам), как это делает печатная машинка, нам нужно разделить анимацию &lt;code&gt;typing&lt;/code&gt;, включенную классом &lt;code&gt;typed-out&lt;/code&gt;, на шаги, чтобы она выглядела так, как будто текст набирается. В этом нам поможет функция CSS &lt;code&gt;steps()&lt;/code&gt;:&lt;/p&gt;
  &lt;pre id=&quot;xE5E&quot; data-lang=&quot;css&quot;&gt;.typed-out{
  overflow: hidden;
  border-right: .15em solid orange;
  white-space: nowrap;
  font-size: 1.6rem;
  width: 0;
  animation: 
    typing 1s steps(20, end) forwards;
}&lt;/pre&gt;
  &lt;p id=&quot;LtGM&quot;&gt;Как вы видите, мы разделили анимацию &lt;code&gt;typing&lt;/code&gt; на 20 шагов с помощью функции CSS &lt;code&gt;steps()&lt;/code&gt;. Вот что мы видим сейчас.&lt;/p&gt;
  &lt;p id=&quot;Tja5&quot;&gt;&lt;a href=&quot;https://codepen.io/SitePoint/pen/XWarjrX&quot; target=&quot;_blank&quot;&gt;Ссылка на Codepen&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;8mFR&quot;&gt;Вот наш полный код на данный момент:&lt;/p&gt;
  &lt;pre id=&quot;Bz5B&quot; data-lang=&quot;html&quot;&gt;&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;Typewriter effect&amp;lt;/title&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;style&amp;gt;
    body{
      background: navajowhite;
      background-size: cover;
      font-family: &amp;#x27;Trebuchet MS&amp;#x27;, sans-serif; 
    }
    .container{
      display: inline-block;
    }
    .typed-out{
      overflow: hidden;
      border-right: .15em solid orange;
      white-space: nowrap;
      animation: 
      typing 1s steps(20, end) forwards;
      font-size: 1.6rem;
      width: 0;
    }
    @keyframes typing {
      from { width: 0 }
      to { width: 100% }
    }
  &amp;lt;/style&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;h1&amp;gt;I&amp;#x27;m Matt, I&amp;#x27;m a&amp;lt;/h1&amp;gt;
&amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;
  &amp;lt;div class=&amp;quot;typed-out&amp;quot;&amp;gt;Web Developer&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/pre&gt;
  &lt;h3 id=&quot;Yf2S&quot;&gt;Настройка шагов для более длительного эффекта &lt;/h3&gt;
  &lt;p id=&quot;tiEV&quot;&gt;Чтобы приспособиться к длинным фрагментам текста, необходимо увеличить шаги и продолжительность анимации набора текста.&lt;/p&gt;
  &lt;p id=&quot;A508&quot;&gt;&lt;a href=&quot;https://codepen.io/SitePoint/pen/vYJBXEp&quot; target=&quot;_blank&quot;&gt;Ссылка на Codepen&lt;/a&gt;&lt;/p&gt;
  &lt;h3 id=&quot;9e7k&quot;&gt;Настройка шагов для более короткого эффекта&lt;/h3&gt;
  &lt;p id=&quot;NBBt&quot;&gt;А чтобы приспособиться к более коротким фрагментам текста, нужно уменьшить шаги и продолжительность анимации набора текста:&lt;br /&gt;&lt;a href=&quot;https://codepen.io/SitePoint/pen/YzxKGXY&quot; target=&quot;_blank&quot;&gt;Ссылка на Codepen&lt;/a&gt;&lt;/p&gt;
  &lt;h3 id=&quot;vY3D&quot;&gt;Настройка кода для эффекта мигающего набора текста&lt;/h3&gt;
  &lt;p id=&quot;xajS&quot;&gt;Мы можем сделать курсор тоньше или толще, изменив его свойство &lt;code&gt;border-right: .15em solid orange;&lt;/code&gt;, или сделать курсор другого цвета, задать ему &lt;code&gt;border-radius&lt;/code&gt;, настроить частоту его мигания и многое другое.&lt;/p&gt;
  &lt;p id=&quot;nncX&quot;&gt;&lt;a href=&quot;https://codepen.io/SitePoint/pen/YzxKGWe&quot; target=&quot;_blank&quot;&gt;Ссылка на Codepen&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;EsCc&quot;&gt;Вы можете поэкспериментировать с этими свойствами в демо-версии на CodePen и посмотреть, что еще вы можете придумать!&lt;/p&gt;
  &lt;h2 id=&quot;Lzm7&quot;&gt;Комбинирование элементов анимации&lt;/h2&gt;
  &lt;p id=&quot;bydS&quot;&gt;Теперь, когда вы знаете, как сделать эффект печатной машинки в CSS, пришло время продемонстрировать несколько практических и актуальных случаев использования этого эффекта.&lt;/p&gt;
  &lt;h3 id=&quot;UTwX&quot;&gt;Эффект печатания портфолио&lt;/h3&gt;
  &lt;p id=&quot;h96k&quot;&gt;Можно использовать такой пример для личного портфолио. Эффекты печатной машинки могут выделить ваше веб-резюме/личный сайт и сделать его более привлекательным.&lt;/p&gt;
  &lt;figure id=&quot;18DY&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/83/73/8373d472-57f5-45a3-95fb-004a865ce4a4.gif&quot; width=&quot;694&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;ycDL&quot;&gt;Демо-версия &lt;a href=&quot;https://codepen.io/SitePoint/pen/YzxKGpa&quot; target=&quot;_blank&quot;&gt;CodePen&lt;/a&gt;.&lt;/p&gt;
  &lt;h3 id=&quot;q3Cs&quot;&gt;Эффект типизации API&lt;/h3&gt;
  &lt;p id=&quot;iUIv&quot;&gt;Вот пример посадочной страницы API.&lt;/p&gt;
  &lt;figure id=&quot;jBQs&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/05/d3/05d36a04-1255-44c6-8df9-9b6aedcdc64e.gif&quot; width=&quot;542&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;BAXc&quot;&gt;Вы можете потренироваться с демонстрацией этого API на &lt;a href=&quot;https://codepen.io/SitePoint/pen/wvqwgRx&quot; target=&quot;_blank&quot;&gt;CodePen&lt;/a&gt;.&lt;/p&gt;
  &lt;p id=&quot;9Nxm&quot;&gt;Вполне вероятно, что на каком-то этапе своего пути разработчика вы сталкивались с посадочной страницей поставщика API и видели подобный блок кода, демонстрирующий реализацию их API. Я лично считаю, что это действительно практичная и уместная реализация эффекта печатной машинки, и считаю, что это выглядит более привлекательно и заманчиво, чем статичный кусок кода.&lt;/p&gt;
  &lt;p id=&quot;8U6R&quot;&gt;Эффекты печатной машинки на целевых страницах продуктов более привлекательны и заинтересовывают посетителей, желающих воспользоваться продуктами или услугами. Проведя много времени за разработкой веб-сервисов и веб-приложений, я могу сказать по своему опыту, что эффекты печатной машинки создают дополнительный интерес к вашим целевым страницам. Набранный текст типа &amp;quot;Начните сегодня&amp;quot; придает дополнительный импульс тексту призыва к действию.&lt;/p&gt;
  &lt;h2 id=&quot;2teB&quot;&gt;&lt;strong&gt;Заключение&lt;/strong&gt;&lt;/h2&gt;
  &lt;p id=&quot;iN1S&quot;&gt;Мы видели в этой статье, как легко с помощью CSS создать анимированный текст &amp;quot;печатной машинки&amp;quot;. Этот эффект печатания определенно может придать интерес и восхищение вашим веб-страницам.&lt;/p&gt;
  &lt;p id=&quot;QiMN&quot;&gt;Однако в конце стоит сделать небольшое предупреждение. Этот прием лучше всего использовать на небольших участках некритичного текста, просто чтобы создать немного дополнительной привлекательности. Но будьте осторожны и не полагайтесь на него слишком сильно, так как использование подобной CSS-анимации имеет некоторые ограничения. Обязательно протестируйте текст, напечатанный на пишущей машинке, на различных устройствах и при разных размерах экрана просмотра, так как результаты могут отличаться на разных платформах. Также подумайте о конечных пользователях, использующих вспомогательные технологии, и в идеале проведите несколько тестов на удобство использования, чтобы убедиться, что вы не усложняете жизнь своим пользователям. Если вы можете сделать что-то с помощью чистого CSS, это еще не значит, что вы должны это делать. Если эффект печатной машинки важен для вас и вы хотите использовать его для более важного контента, возможно стоит рассмотреть также решения на JavaScript.&lt;/p&gt;
  &lt;p id=&quot;drLM&quot;&gt;В любом случае, я надеюсь, что вам понравилась эта статья, и что она заставила вас задуматься о других интересных вещах, которые можно сделать с помощью CSS-анимации, чтобы добавить интересный и забавный характер вашим веб-страницам.&lt;/p&gt;
  &lt;p id=&quot;C3X7&quot;&gt;Источник: &lt;a href=&quot;https://www.sitepoint.com/css-typewriter-effect/&quot; target=&quot;_blank&quot;&gt;https://www.sitepoint.com/css-typewriter-effect/&lt;/a&gt;&lt;/p&gt;

</content></entry><entry><id>budnifronta:u4ONfLrU_Me</id><link rel="alternate" type="text/html" href="https://teletype.in/@budnifronta/u4ONfLrU_Me?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=budnifronta"></link><title>Yarn vs npm: все, что вам нужно знать</title><published>2022-01-26T10:28:15.106Z</published><updated>2022-01-27T19:07:26.814Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img1.teletype.in/files/80/a7/80a7295c-fc0c-4895-afe7-4de8a60289e4.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://img1.teletype.in/files/44/44/4444b5fe-01b5-4a07-aa4f-57de0077cfca.jpeg&quot;&gt;В этом руководстве мы сравним Yarn и npm - два самых популярных менеджера пакетов. Мы рассмотрим их все преимущества и недостатки, чтобы помочь вам выбрать, какой из них использовать для своих проектов.</summary><content type="html">
  &lt;figure id=&quot;r4eq&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/44/44/4444b5fe-01b5-4a07-aa4f-57de0077cfca.jpeg&quot; width=&quot;1280&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;5xlo&quot;&gt;В этом руководстве мы сравним Yarn и npm - два самых популярных менеджера пакетов. Мы рассмотрим их все преимущества и недостатки, чтобы помочь вам выбрать, какой из них использовать для своих проектов.&lt;/p&gt;
  &lt;h2 id=&quot;f55z&quot;&gt;Изложение основ&lt;/h2&gt;
  &lt;p id=&quot;ub4y&quot;&gt;В старые добрые времена разработчикам было достаточно простого текстового редактора для создания и управления значительной частью своих проектов. Но с тех пор веб сильно изменился. Сегодня даже в довольно простом проекте часто встречаются сотни или тысячи скриптов со сложными вложенными зависимостями, которыми просто невозможно управлять без какого-либо автоматизированного инструмента. И именно здесь на помощь приходят менеджеры пакетов.&lt;/p&gt;
  &lt;p id=&quot;7WYT&quot;&gt;Менеджер пакетов - это инструмент, который автоматически обрабатывает зависимости проекта различными способами. Например, с помощью него мы можем устанавливать, удалять, обновлять и модернизировать пакеты, настраивать параметры проекта, запускать скрипты и так далее. Всю тяжелую и утомительную работу делает менеджер пакетов, оставляя нам только самое интересное - само программирование.&lt;/p&gt;
  &lt;p id=&quot;84r4&quot;&gt;&lt;a href=&quot;https://docs.npmjs.com/cli/v7/commands/npm&quot; target=&quot;_blank&quot;&gt;npm&lt;/a&gt; означает Node Package Manager. Он был представлен в 2010 году, положив начало новой эре в веб-разработке. До этого момента зависимости проекта загружались и управлялись вручную. npm стал волшебной палочкой, которая вывела веб-разработку на новый уровень.&lt;/p&gt;
  &lt;p id=&quot;aw8i&quot;&gt;На самом деле npm включает в себя три составляющих:&lt;/p&gt;
  &lt;ul id=&quot;eTIZ&quot;&gt;
    &lt;li id=&quot;czhz&quot;&gt;веб-сайт для управления различными аспектами вашей работы с npm&lt;/li&gt;
    &lt;li id=&quot;X4MP&quot;&gt;реестр для доступа к обширной публичной базе данных пакетов JavaScript&lt;/li&gt;
    &lt;li id=&quot;WLe3&quot;&gt;интерфейс командной строки (CLI) для взаимодействия с npm через терминал&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;ozfk&quot;&gt;Однако, когда большинство людей говорят о npm, они обычно имеют в виду последний - инструмент CLI. Он поставляется в качестве менеджера пакетов по умолчанию с каждой новой установкой Node. Это означает, что вы можете начать использовать его сразу же.&lt;/p&gt;
  &lt;p id=&quot;dOvd&quot;&gt;Yarn расшифровывается как Yet Another Resource Negotiator. Менеджер пакетов Yarn - это альтернатива npm, выпущенная компанией Facebook в октябре 2016 года. Первоначальной целью создания Yarn было устранение недостатков npm, таких как производительность и проблемы безопасности. Yarn был быстро позиционирован как безопасный, быстрый и надежный инструмент управления зависимостями JavaScript.&lt;/p&gt;
  &lt;p id=&quot;KcUM&quot;&gt;Но команда npm извлекла для себя урок и быстро заполнила пробелы в npm, реализовав недостающие функции.&lt;/p&gt;
  &lt;p id=&quot;N3RM&quot;&gt;Давайте быстро перенесемся во времени, чтобы увидеть общую картину:&lt;/p&gt;
  &lt;ul id=&quot;IX6F&quot;&gt;
    &lt;li id=&quot;uEzB&quot;&gt;2010: выпущен npm с поддержкой Node.&lt;/li&gt;
    &lt;li id=&quot;lVQ2&quot;&gt;2016: Выпущен Yarn. Он показывает гораздо большую производительность, чем npm. Он также генерирует файл &lt;code&gt;yarn.lock&lt;/code&gt;, который делает совместное использование и точную репликацию репозиториев намного проще и предсказуемее.&lt;/li&gt;
    &lt;li id=&quot;5JEM&quot;&gt;2017: Выпущен npm 5. Он предлагает автоматическую генерацию файла &lt;code&gt;package-lock.json&lt;/code&gt; в ответ на &lt;code&gt;yarn.lock&lt;/code&gt;.&lt;/li&gt;
    &lt;li id=&quot;oN6m&quot;&gt;2018: Выпущен npm 6 с улучшенной безопасностью. Теперь npm проверяет уязвимости безопасности перед установкой зависимостей.&lt;/li&gt;
    &lt;li id=&quot;IU4A&quot;&gt;2020: Выпущены Yarn 2 и npm 7. Оба пакета имеют новые возможности, которые мы увидим позже в этом руководстве.&lt;/li&gt;
    &lt;li id=&quot;h3zA&quot;&gt;2021: Выходит Yarn 3 с различными улучшениями.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;r16c&quot;&gt;Сегодня оба пакетных менеджера идут бок о бок в гонке за управление пакетами, предлагая схожие функции и возможности. Но все же есть несколько различий, которые помогают определить, какой из них выбрать.&lt;/p&gt;
  &lt;p id=&quot;JZnK&quot;&gt;В оставшейся части этого руководства мы рассмотрим основные сходства и различия между npm и Yarn.&lt;/p&gt;
  &lt;h2 id=&quot;GOL5&quot;&gt;Yarn и npm: сравнение установки&lt;/h2&gt;
  &lt;p id=&quot;snvl&quot;&gt;Мы начнем наше сравнительное исследование с процесса установки как npm, так и Yarn.&lt;/p&gt;
  &lt;h3 id=&quot;fpAQ&quot;&gt;Установка самих менеджеров пакетов&lt;/h3&gt;
  &lt;p id=&quot;mNNQ&quot;&gt;Как я отметил выше, npm поставляется с предустановленным Node, поэтому нет необходимости устанавливать npm вручную.&lt;/p&gt;
  &lt;p id=&quot;d3s1&quot;&gt;В отличие от этого, Yarn нужно устанавливать отдельно. Во-первых, нам нужно установить Yarn глобально:&lt;/p&gt;
  &lt;pre id=&quot;C2F4&quot; data-lang=&quot;npmignore&quot;&gt;npm install -g yarn&lt;/pre&gt;
  &lt;p id=&quot;eqO0&quot;&gt;Затем мы можем использовать его для каждого проекта, установив нужную версию внутри нашего проекта. Для этого нужно выполнить команду yarn set version в корневом каталоге проекта:&lt;/p&gt;
  &lt;pre id=&quot;YZhw&quot; data-lang=&quot;npmignore&quot;&gt;yarn set version berry&lt;/pre&gt;
  &lt;p id=&quot;fJly&quot;&gt;В данном случае &lt;code&gt;berry&lt;/code&gt; - это версия, которую мы хотим установить.&lt;/p&gt;
  &lt;p id=&quot;U5Ip&quot;&gt;Если мы хотим обновить версию до последней, мы выполним следующее:&lt;/p&gt;
  &lt;pre id=&quot;TLg4&quot; data-lang=&quot;npmignore&quot;&gt;yarn set version latest&lt;/pre&gt;
  &lt;p id=&quot;gWqn&quot;&gt;С Yarn мы можем использовать разные версии для каждого проекта.&lt;/p&gt;
  &lt;p id=&quot;r6Qx&quot;&gt;Чтобы сделать то же самое с npm, вам потребуется установить &lt;a href=&quot;https://github.com/nvm-sh/nvm&quot; target=&quot;_blank&quot;&gt;nvm (Node Version Manager)&lt;/a&gt;. &lt;/p&gt;
  &lt;h3 id=&quot;6D0V&quot;&gt;Установка зависимостей проекта&lt;/h3&gt;
  &lt;p id=&quot;FXDg&quot;&gt;Теперь давайте посмотрим, как устанавливаются зависимости проекта.&lt;/p&gt;
  &lt;p id=&quot;iH38&quot;&gt;Когда мы запускаем &lt;code&gt;npm install&lt;/code&gt;, зависимости устанавливаются последовательно, одна за другой. Логи вывода в терминале информативны, но немного трудночитаемы.&lt;/p&gt;
  &lt;p id=&quot;sGx3&quot;&gt;Чтобы установить пакеты с помощью Yarn, мы выполняем команду &lt;code&gt;yarn&lt;/code&gt;. Yarn устанавливает пакеты параллельно, что является одной из причин, почему он быстрее, чем npm. Если вы используете Yarn 1, вы увидите, что журналы вывода yarn чистые, визуально различимые и краткие. Они также упорядочены в виде дерева для удобства восприятия. Но это меняется в версиях 2 и 3, где журналы не такие интуитивно понятные и человекочитаемые.&lt;/p&gt;
  &lt;p id=&quot;f9CS&quot;&gt;До этого мы видели, что npm и Yarn имеют разные команды для установки пакетов. В следующем разделе мы рассмотрим больше команд.&lt;/p&gt;
  &lt;h2 id=&quot;Zsln&quot;&gt;Сравнение команд npm и Yarn&lt;/h2&gt;
  &lt;p id=&quot;kC7E&quot;&gt;npm и Yarn имеют много общих команд, но есть и много неидентичных команд. Давайте сначала рассмотрим некоторые из похожих команд:&lt;/p&gt;
  &lt;ul id=&quot;Zgu6&quot;&gt;
    &lt;li id=&quot;GLAz&quot;&gt;&lt;code&gt;npm init&lt;/code&gt; | &lt;code&gt;yarn init&lt;/code&gt;: создание нового пакета&lt;/li&gt;
    &lt;li id=&quot;tVFN&quot;&gt;&lt;code&gt;npm run&lt;/code&gt; | &lt;code&gt;yarn run&lt;/code&gt;: запуск скрипта, определенного в package.json&lt;/li&gt;
    &lt;li id=&quot;Qoeq&quot;&gt;&lt;code&gt;npm test&lt;/code&gt; | &lt;code&gt;yarn test&lt;/code&gt;: тестирование пакета&lt;/li&gt;
    &lt;li id=&quot;UJZL&quot;&gt;&lt;code&gt;npm publish&lt;/code&gt; | &lt;code&gt;yarn publish&lt;/code&gt;: опубликовать пакет&lt;/li&gt;
    &lt;li id=&quot;OyNt&quot;&gt;&lt;code&gt;npm cache clean&lt;/code&gt; | &lt;code&gt;yarn cache clean&lt;/code&gt;: удалить все данные из папки cache&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;IJfI&quot;&gt;Эти команды упрощают переключение между двумя менеджерами, но есть некоторые неидентичные команды, которые могут вызвать путаницу. Давайте посмотрим, что это за команды в следующем списке:&lt;/p&gt;
  &lt;ul id=&quot;8Gdp&quot;&gt;
    &lt;li id=&quot;i66w&quot;&gt;&lt;code&gt;npm install&lt;/code&gt; | &lt;code&gt;yarn&lt;/code&gt;: установка зависимостей&lt;/li&gt;
    &lt;li id=&quot;wEzl&quot;&gt;&lt;code&gt;npm install [package]&lt;/code&gt; | &lt;code&gt;yarn add [package]&lt;/code&gt;: установка пакета&lt;/li&gt;
    &lt;li id=&quot;uKIW&quot;&gt;&lt;code&gt;npm install --save-dev [package]&lt;/code&gt; | &lt;code&gt;yarn add - -dev [package]&lt;/code&gt;: установка пакета в качестве зависимости для разработки&lt;/li&gt;
    &lt;li id=&quot;zwKc&quot;&gt;&lt;code&gt;npm uninstall [package]&lt;/code&gt; | &lt;code&gt;yarn remove [package]&lt;/code&gt;: удаление пакета&lt;/li&gt;
    &lt;li id=&quot;Y7Bw&quot;&gt;&lt;code&gt;npm uninstall --save-dev [package]&lt;/code&gt; | &lt;code&gt;yarn remove [package]&lt;/code&gt;: удаление пакета, зависящего от разработки&lt;/li&gt;
    &lt;li id=&quot;uoOo&quot;&gt;&lt;code&gt;npm update&lt;/code&gt; | &lt;code&gt;yarn upgrade&lt;/code&gt;: обновление зависимостей&lt;/li&gt;
    &lt;li id=&quot;Tb9n&quot;&gt;&lt;code&gt;npm update [package]&lt;/code&gt; | &lt;code&gt;yarn upgrade [package]&lt;/code&gt;: обновление пакета&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;nu5l&quot;&gt;В Yarn также есть несколько уникальных команд, которые не имеют аналогов в npm. Например, команда &lt;code&gt;why&lt;/code&gt; отображает причину необходимости пакета: это может быть зависимость, нативный модуль или зависимость от проекта.&lt;/p&gt;
  &lt;h2 id=&quot;aQqw&quot;&gt;Yarn против npm: скорость и производительность&lt;/h2&gt;
  &lt;p id=&quot;kg3W&quot;&gt;Когда Yarn или npm нужно установить пакет, они выполняют ряд задач. В npm эти задачи выполняются для каждого пакета и последовательно, то есть он будет ждать, пока пакет будет полностью установлен, прежде чем переходить к следующему. В отличие от него, Yarn выполняет эти задачи параллельно, что повышает производительность.&lt;/p&gt;
  &lt;p id=&quot;aHgf&quot;&gt;Несмотря на то, что оба менеджера предлагают механизмы кэширования, Yarn, кажется, делает это немного лучше. Реализуя парадигму нулевой установки, как мы увидим в разделе сравнения возможностей, он способен устанавливать пакеты практически мгновенно. Он кэширует каждый пакет и сохраняет его на диске, поэтому при следующей установке этого пакета вам даже не потребуется подключение к интернету, так как пакет будет установлен с диска в автономном режиме.&lt;/p&gt;
  &lt;p id=&quot;Q55X&quot;&gt;Несмотря на то, что Yarn имеет некоторые преимущества, скорости Yarn и npm в их последних версиях вполне сопоставимы. Поэтому мы не можем определить победителя.&lt;/p&gt;
  &lt;h2 id=&quot;nSom&quot;&gt;Yarn vs npm: сравнение безопасности&lt;/h2&gt;
  &lt;p id=&quot;qIyz&quot;&gt;Одно из главных критических замечаний в адрес npm касается безопасности. Предыдущие версии npm имеют несколько серьезных уязвимостей в безопасности.&lt;/p&gt;
  &lt;p id=&quot;ScVm&quot;&gt;Начиная с версии 6, npm проверяет пакеты во время установки и сообщает вам, если обнаружены какие-либо уязвимости. Мы можем выполнить эту проверку вручную, запустив &lt;code&gt;npm audit&lt;/code&gt; для установленных пакетов. Если будут найдены уязвимости, npm даст нам рекомендации по безопасности.&lt;/p&gt;
  &lt;figure id=&quot;RbyX&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://uploads.sitepoint.com/wp-content/uploads/2021/08/1630415886npm-audit.jpg&quot; width=&quot;830&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;6Yul&quot;&gt;Как видно на скриншоте выше, мы можем запустить &lt;code&gt;npm audit fix&lt;/code&gt; для устранения уязвимостей пакетов, и деревья зависимостей будут исправлены, если это возможно.&lt;/p&gt;
  &lt;p id=&quot;LoRU&quot;&gt;И Yarn, и npm используют криптографические хэш-алгоритмы для обеспечения целостности пакетов.&lt;/p&gt;
  &lt;h2 id=&quot;hWBA&quot;&gt;Yarn vs npm: сравнение возможностей&lt;/h2&gt;
  &lt;p id=&quot;xFtN&quot;&gt;Как и в случае с командами, некоторые функции npm и Yarn являются общими, но есть и некоторые различия. Давайте сначала рассмотрим общие возможности этих двух менеджеров пакетов.&lt;/p&gt;
  &lt;h3 id=&quot;8UNx&quot;&gt;Создание файла блокировки&lt;/h3&gt;
  &lt;p id=&quot;6gRH&quot;&gt;В &lt;code&gt;package.json&lt;/code&gt;, файле, в котором npm и Yarn ведут учет зависимостей проекта, номера версий не всегда точны. Вместо этого вы можете задать диапазон версий. Таким образом, вы можете выбрать конкретную мажорную и минорную версию пакета, но позволить npm установить последний патч, который может исправить некоторые ошибки.&lt;/p&gt;
  &lt;p id=&quot;Phad&quot;&gt;В идеальном мире семантического версионирования исправленные релизы не будут содержать никаких ломающих изменений. Но, к сожалению, это не всегда так. Стратегия, используемая npm, может привести к тому, что на двух компьютерах окажется один и тот же файл &lt;code&gt;package.json&lt;/code&gt;, но будут установлены разные версии пакета, что, возможно, приведет к появлению ошибок.&lt;/p&gt;
  &lt;p id=&quot;WyJL&quot;&gt;Чтобы избежать несоответствия версий пакетов, точная установленная версия фиксируется в файле блокировки пакетов. При каждом добавлении модуля npm и Yarn создают (или обновляют) файл &lt;code&gt;package-lock.json&lt;/code&gt; и &lt;code&gt;yarn.lock&lt;/code&gt; соответственно. Таким образом, вы можете быть уверены, что на другой машине установлен точно такой же пакет, но при этом в файле &lt;code&gt;package.json&lt;/code&gt; определен диапазон допустимых версий.&lt;/p&gt;
  &lt;h3 id=&quot;0cZp&quot;&gt;Использование рабочих областей&lt;/h3&gt;
  &lt;p id=&quot;qRCp&quot;&gt;Рабочие пространства позволяют вам иметь один монорепо для управления зависимостями в нескольких проектах. Это означает, что у вас есть один корневой пакет верхнего уровня, который имеет несколько дочерних пакетов, называемых рабочими пространствами.&lt;/p&gt;
  &lt;h3 id=&quot;HHsc&quot;&gt;Удаленный запуск скриптов&lt;/h3&gt;
  &lt;p id=&quot;AwK1&quot;&gt;Команда &lt;code&gt;npx&lt;/code&gt; используется для запуска скриптов из &lt;code&gt;./node_modules/.bin&lt;/code&gt;. Она также позволяет выполнять пакеты из реестра npm, не устанавливая их в зависимости вашего проекта. Например, вы можете создать новое приложение React, выполнив следующее:&lt;/p&gt;
  &lt;pre id=&quot;MgjQ&quot; data-lang=&quot;npmignore&quot;&gt;npx create-react-app my-app&lt;/pre&gt;
  &lt;p id=&quot;sFEP&quot;&gt;В Yarn вы можете достичь того же результата, используя эквивалентную команду &lt;code&gt;dlx&lt;/code&gt;:&lt;/p&gt;
  &lt;pre id=&quot;mx80&quot; data-lang=&quot;npmignore&quot;&gt;yarn dlx create-react-app my-app&lt;/pre&gt;
  &lt;p id=&quot;iUyd&quot;&gt;Остальные функции, которые мы будем изучать, уникальны для Yarn.&lt;/p&gt;
  &lt;h3 id=&quot;adsb&quot;&gt;Нулевые установки&lt;/h3&gt;
  &lt;p id=&quot;Bk9m&quot;&gt;При нулевой установке кэш хранится в каталоге вашего проекта в папке &lt;code&gt;.yarn&lt;/code&gt;. Когда вы используете такие команды, как &lt;code&gt;yarn&lt;/code&gt; или &lt;code&gt;yarn add &amp;lt;package&amp;gt;&lt;/code&gt;, Yarn создаст файл &lt;code&gt;.pnp.cjs&lt;/code&gt;. Этот файл содержит иерархию зависимостей, используемую Node для загрузки пакетов вашего проекта. Таким образом, вы можете получить к ним доступ практически в нулевое время.&lt;/p&gt;
  &lt;h3 id=&quot;h3fB&quot;&gt;Plug&amp;#x27;n&amp;#x27;Play (Подключи и работай)&lt;/h3&gt;
  &lt;p id=&quot;5ydK&quot;&gt;Plug&amp;#x27;n&amp;#x27;Play - это альтернативная стратегия установки. Вместо того чтобы генерировать каталог &lt;code&gt;node_modules&lt;/code&gt; и оставлять решение проблемы на усмотрение Node, Yarn генерирует единственный файл &lt;code&gt;.pnp.cjs&lt;/code&gt;, который сопоставляет пакеты с их расположением на диске и списком зависимостей. Эта возможность может привести к более быстрому запуску проекта, лучшей оптимизации дерева зависимостей, более быстрому времени установки и, конечно, устраняет необходимость в папке &lt;code&gt;node_modules&lt;/code&gt;.&lt;/p&gt;
  &lt;h3 id=&quot;gUYx&quot;&gt;Лицензия&lt;/h3&gt;
  &lt;p id=&quot;Opn5&quot;&gt;В Yarn встроена функция проверки лицензий, которая может быть полезна в различных случаях при разработке приложений.&lt;/p&gt;
  &lt;h2 id=&quot;aRha&quot;&gt;Yarn vs npm: какой менеджер пакетов выбрать&lt;/h2&gt;
  &lt;p id=&quot;ItM4&quot;&gt;Мы рассмотрели различные сходства и различия npm и Yarn, но так и не определили, что лучше и какой из них выбрать. Как всегда, ответ зависит от наших желаний и требований.&lt;/p&gt;
  &lt;p id=&quot;l2fp&quot;&gt;В качестве общего руководства позвольте мне в заключение дать следующий совет:&lt;/p&gt;
  &lt;ul id=&quot;jZaS&quot;&gt;
    &lt;li id=&quot;uPAD&quot;&gt;Выбирайте npm, если вас устраивает ваш текущий рабочий процесс, вы не хотите устанавливать дополнительный инструмент и у вас мало места на диске.&lt;/li&gt;
    &lt;li id=&quot;8f63&quot;&gt;Выбирайте Yarn, если вам нужны такие замечательные возможности, как Plug&amp;#x27;n&amp;#x27;Play, вам нужна функциональность, которой не хватает в npm, и у вас достаточно места на диске.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;B5TQ&quot;&gt;Если вам все еще трудно принять четкое решение между npm и Yarn, вы можете попробовать &lt;a href=&quot;https://pnpm.io/&quot; target=&quot;_blank&quot;&gt;pnpm&lt;/a&gt;, который пытается объединить лучшее от обоих пакетных менеджеров и является третьим крупным игроком в среде пакетных менеджеров.&lt;/p&gt;
  &lt;h2 id=&quot;wnPk&quot;&gt;Заключение&lt;/h2&gt;
  &lt;p id=&quot;dlh2&quot;&gt;Мы увидели, насколько важны менеджеры пакетов для современной веб-разработки, и сравнили два самых популярных конкурента на рынке. Они оба имеют свои преимущества и недостатки, и для того, чтобы выбрать лучший для вас, необходимо иметь четкое представление о ваших требованиях. Лучший способ решить, какой из них вам больше подходит, - попробовать оба и посмотреть, какой из них работает лучше.&lt;/p&gt;
  &lt;p id=&quot;VOJk&quot;&gt;И, наконец, не раздумывайте. Просто выберите один из них и переходите к самому интересному: созданию отличных приложений!&lt;/p&gt;
  &lt;p id=&quot;lJqA&quot;&gt;Источник: https://www.sitepoint.com/yarn-vs-npm/&lt;/p&gt;

</content></entry><entry><id>budnifronta:wMy_tawdyjk</id><link rel="alternate" type="text/html" href="https://teletype.in/@budnifronta/wMy_tawdyjk?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=budnifronta"></link><title>Изучение Vite через исходный код</title><published>2022-01-21T19:56:22.324Z</published><updated>2022-01-23T18:00:35.500Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img2.teletype.in/files/dc/11/dc113bab-9c65-42cc-9dbf-2de03cf7fcc0.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://img1.teletype.in/files/08/5e/085ead36-972a-4cf3-9f30-7fb717e600da.jpeg&quot;&gt;Как вы, вероятно, слышали, в экосистеме front-end есть новый крутой инструмент для сборки под названием Vite. Хотя он был создан Эваном Ю (который также создал Vue.js), он не зависит от фреймворка, поэтому вы можете использовать Vite с Vue.js, React.js, Svelte.js или даже с обычным JavaScript.</summary><content type="html">
  &lt;figure id=&quot;6ZiZ&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/08/5e/085ead36-972a-4cf3-9f30-7fb717e600da.jpeg&quot; width=&quot;1280&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;ttov&quot;&gt;Как вы, вероятно, слышали, в экосистеме front-end есть новый крутой инструмент для сборки под названием Vite. Хотя он был создан Эваном Ю (который также создал Vue.js), он не зависит от фреймворка, поэтому вы можете использовать Vite с Vue.js, React.js, Svelte.js или даже с обычным JavaScript.&lt;/p&gt;
  &lt;p id=&quot;u3fV&quot;&gt;В этой статье мы изучим Vite, чтобы получить некоторые сведения о его внутренней архитектуре. В частности, мы изучим системы шаблонов и плагинов Vite. В конце вы будете лучше понимать разницу между шаблонами и плагинами, а также то, как основная система Vite связана с плагином.&lt;/p&gt;
  &lt;p id=&quot;Rmbs&quot;&gt;Теперь, без лишних слов, давайте создадим приложение с помощью Vite.&lt;/p&gt;
  &lt;h2 id=&quot;dtF1&quot;&gt;Создание приложения с Vite&lt;/h2&gt;
  &lt;p id=&quot;hfnP&quot;&gt;Для данной демонстрации мы создадим проект Vue, используя эту команду:&lt;/p&gt;
  &lt;pre id=&quot;JuP8&quot; data-lang=&quot;javascript&quot;&gt;npm init vite@latest&lt;/pre&gt;
  &lt;p id=&quot;FEVw&quot;&gt;(Наличие &lt;code&gt;@latest&lt;/code&gt; гарантирует, что вы всегда получите последнюю версию, когда будете выполнять &lt;code&gt;npm install&lt;/code&gt; внутри этого нового проекта).&lt;/p&gt;
  &lt;p id=&quot;nj7o&quot;&gt;В качестве примечания, вы могли видеть устаревшую версию команды &lt;code&gt;init&lt;/code&gt;.&lt;/p&gt;
  &lt;figure id=&quot;FaWX&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://uploads.sitepoint.com/wp-content/uploads/2021/09/1632214539img-1-deprecation.png&quot; width=&quot;1500&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;LFB1&quot;&gt;Как вы можете видеть, предупреждение об устарелости говорит нам использовать &lt;code&gt;npm init vite&lt;/code&gt; вместо этого.&lt;/p&gt;
  &lt;p id=&quot;XvTB&quot;&gt;Эта новая команда, по сути, является сокращением для:&lt;/p&gt;
  &lt;pre id=&quot;7BI5&quot; data-lang=&quot;javascript&quot;&gt;npx create-vite&lt;/pre&gt;
  &lt;p id=&quot;NPr2&quot;&gt;Это позволит установить и запустить инструмент под названием create-vite, который подскажет вам, какой проект вы создаете. Вы выберете имя и шаблон.&lt;/p&gt;
  &lt;p id=&quot;OSDp&quot;&gt;Выберите имя для вашего проекта.&lt;/p&gt;
  &lt;figure id=&quot;ZDDS&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://uploads.sitepoint.com/wp-content/uploads/2021/09/1632214543img-2-select-name.png&quot; width=&quot;1558&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;iEQo&quot;&gt;И выберите шаблон для использования.&lt;/p&gt;
  &lt;figure id=&quot;QGtT&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://uploads.sitepoint.com/wp-content/uploads/2021/09/1632214549img-3-select-template.png&quot; width=&quot;1562&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;a2oI&quot;&gt;Для изучения вы можете использовать либо &lt;code&gt;vanilla&lt;/code&gt;, либо &lt;code&gt;vue&lt;/code&gt;.&lt;/p&gt;
  &lt;p id=&quot;kVEN&quot;&gt;Далее мы изучим инструмент &lt;code&gt;create-vite&lt;/code&gt; через его исходный код на GitHub.&lt;/p&gt;
  &lt;h2 id=&quot;qcDX&quot;&gt;Изучение исходного кода Vite&lt;/h2&gt;
  &lt;p id=&quot;RZ3i&quot;&gt;Сначала зайдите на страницу Vite в GitHub по адресу &lt;a href=&quot;http://github.com/vitejs/vite&quot; target=&quot;_blank&quot;&gt;github.com/vitejs/vite&lt;/a&gt;.&lt;/p&gt;
  &lt;figure id=&quot;7H4B&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://uploads.sitepoint.com/wp-content/uploads/2021/09/1632214555img-4-packages.png&quot; width=&quot;1922&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;8AYp&quot;&gt;Затем перейдите в папку &lt;code&gt;packages&lt;/code&gt;.&lt;/p&gt;
  &lt;figure id=&quot;Oass&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://uploads.sitepoint.com/wp-content/uploads/2021/09/1632214563img-6-create-vite.png&quot; width=&quot;2566&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;xQpE&quot;&gt;Здесь вы можете увидеть &lt;code&gt;create-app&lt;/code&gt; и &lt;code&gt;create-vite&lt;/code&gt;.&lt;/p&gt;
  &lt;p id=&quot;yiB8&quot;&gt;&lt;code&gt;create-app&lt;/code&gt; отвечает за первоначальную команду, которая говорит &amp;quot;deprecated (устаревший)&amp;quot;. Здесь нас интересует папка &lt;code&gt;create-vite&lt;/code&gt;. В ней находятся все встроенные шаблоны для создания проектов.&lt;/p&gt;
  &lt;p id=&quot;MQp3&quot;&gt;Внутри папки &lt;code&gt;packages&lt;/code&gt; мы также можем увидеть несколько папок plugin для нескольких встроенных плагинов.&lt;/p&gt;
  &lt;p id=&quot;bJM0&quot;&gt;Теперь самое время изучить различия между шаблонами и плагинами, а также то, как они работают вместе в рабочем процессе инструмента сборки.&lt;/p&gt;
  &lt;h2 id=&quot;V1NG&quot;&gt;Шаблоны&lt;/h2&gt;
  &lt;p id=&quot;i0ZO&quot;&gt;Понятие шаблона можно легко понять: это стартовый код для нового проекта.&lt;/p&gt;
  &lt;p id=&quot;E0hX&quot;&gt;Внутри папки &lt;code&gt;packages/create-vite&lt;/code&gt; вы должны увидеть дюжину папок &lt;code&gt;template-*&lt;/code&gt;.&lt;/p&gt;
  &lt;p id=&quot;3DMh&quot;&gt;📁 &lt;strong&gt;/packages/create-vite&lt;/strong&gt;&lt;/p&gt;
  &lt;figure id=&quot;g2fC&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://uploads.sitepoint.com/wp-content/uploads/2021/09/1632214559img-5-packages-folder.png&quot; width=&quot;2500&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;2e9Q&quot;&gt;Как вы видите, Vite поддерживает шаблоны для различных фреймворков (и их TypeScript-аналогов).&lt;/p&gt;
  &lt;p id=&quot;LR1z&quot;&gt;Вы можете выбрать &lt;code&gt;vanilla&lt;/code&gt; в команде &lt;code&gt;create-vite&lt;/code&gt;.&lt;/p&gt;
  &lt;figure id=&quot;AF8E&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://uploads.sitepoint.com/wp-content/uploads/2021/09/1632214567img-7-vanilla.png&quot; width=&quot;1524&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;vKn7&quot;&gt;Если вы выберете vanilla, он возьмет файлы из папки &lt;code&gt;packages/template-vanilla&lt;/code&gt; и клонирует их как ваш новый проект.&lt;/p&gt;
  &lt;p id=&quot;VjZo&quot;&gt;📁 &lt;strong&gt;/packages/template-vanilla&lt;/strong&gt;&lt;/p&gt;
  &lt;figure id=&quot;yPna&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://uploads.sitepoint.com/wp-content/uploads/2021/09/1632214571img-8-template-vanilla.png&quot; width=&quot;2488&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;tVA5&quot;&gt;Вы также можете выбрать &lt;code&gt;vue&lt;/code&gt; из списка:&lt;/p&gt;
  &lt;figure id=&quot;WowV&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://uploads.sitepoint.com/wp-content/uploads/2021/09/1632214574img-9-vue.png&quot; width=&quot;1516&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;ryUg&quot;&gt;Если вы выбрали vue, он будет клонировать файлы в папке &lt;code&gt;packages/template-vue&lt;/code&gt; как ваш новый проект.&lt;/p&gt;
  &lt;p id=&quot;kMtS&quot;&gt;📁 &lt;strong&gt;/packages/template-vue&lt;/strong&gt;&lt;/p&gt;
  &lt;figure id=&quot;cYys&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://uploads.sitepoint.com/wp-content/uploads/2021/09/1632214579img-10-template-vue.png&quot; width=&quot;2478&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;ZXas&quot;&gt;Сгенерированный проект из шаблона vue будет иметь стандартную структуру папок, которую вы ожидаете от проекта Vue.&lt;/p&gt;
  &lt;p id=&quot;gSKB&quot;&gt;Итак, это шаблон. Теперь поговорим о плагине.&lt;/p&gt;
  &lt;h2 id=&quot;FfGw&quot;&gt;Плагины&lt;/h2&gt;
  &lt;p id=&quot;CzUW&quot;&gt;Как я уже говорил, Vite не привязан к конкретным фреймворкам. Он способен создавать проекты для различных фреймворков благодаря своей системе плагинов.&lt;/p&gt;
  &lt;p id=&quot;IQx9&quot;&gt;Из коробки Vite предоставляет плагины для Vue, Vue with JSX и React.&lt;/p&gt;
  &lt;p id=&quot;JUff&quot;&gt;Вы можете изучить код каждого встроенного плагина в папке &lt;code&gt;packages&lt;/code&gt;:&lt;/p&gt;
  &lt;p id=&quot;oLKt&quot;&gt;📁 &lt;strong&gt;/packages&lt;/strong&gt;&lt;/p&gt;
  &lt;figure id=&quot;Hm49&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://uploads.sitepoint.com/wp-content/uploads/2021/09/1632215014img-11-plugins.png&quot; width=&quot;2504&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;E7fw&quot;&gt;Примечание: &lt;code&gt;plugin-legacy&lt;/code&gt; предназначен для устаревших браузеров, которые не поддерживают встроенный ESM.&lt;/p&gt;
  &lt;p id=&quot;XU9Y&quot;&gt;Наиболее распространенный способ использования этих плагинов - через соответствующие шаблоны. Например, шаблон Vue требует использования плагина Vue, а шаблон React - плагина React.&lt;/p&gt;
  &lt;p id=&quot;jQij&quot;&gt;Проект, созданный с помощью шаблона vanilla, не имеет представления о том, как обслуживать однофайловые файлы компонентов Vue (SFC). Но проект Vue, созданный с помощью Vite, сможет обрабатывать файлы типа SFC. И он также знает, как упаковать весь проект Vue для продакшена.&lt;/p&gt;
  &lt;p id=&quot;SC0i&quot;&gt;Если мы сравним соответствующие файлы &lt;code&gt;package.json&lt;/code&gt; шаблона Vue и ванильного шаблона, мы легко поймем, почему это так.&lt;/p&gt;
  &lt;p id=&quot;oiIa&quot;&gt;📁 &lt;strong&gt;/packages/template-vanilla/package.json&lt;/strong&gt;&lt;/p&gt;
  &lt;figure id=&quot;0rmW&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://uploads.sitepoint.com/wp-content/uploads/2021/09/1632215017img-12-vanilla-package.png&quot; width=&quot;2460&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;5x7z&quot;&gt;📁 &lt;strong&gt;/packages/template-vue/package.json&lt;/strong&gt;&lt;/p&gt;
  &lt;figure id=&quot;XPZQ&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://uploads.sitepoint.com/wp-content/uploads/2021/09/1632215020img-13-vue-package.png&quot; width=&quot;2466&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;oFtS&quot;&gt;&lt;code&gt;template-vue&lt;/code&gt; содержит все то же, что и &lt;code&gt;template-vanilla&lt;/code&gt;, плюс три дополнительных пакета.&lt;/p&gt;
  &lt;p id=&quot;mf8A&quot;&gt;📁 &lt;strong&gt;/packages/template-vue/package.json&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;epUI&quot; data-lang=&quot;javascript&quot;&gt;&amp;quot;dependencies&amp;quot;: {
    &amp;quot;vue&amp;quot;: &amp;quot;^3.2.6&amp;quot; // 1
  },
  &amp;quot;devDependencies&amp;quot;: {
    &amp;quot;@vitejs/plugin-vue&amp;quot;: &amp;quot;^1.6.1&amp;quot;, // 2
    &amp;quot;@vue/compiler-sfc&amp;quot;: &amp;quot;^3.2.6&amp;quot;, // 3
    &amp;quot;vite&amp;quot;: &amp;quot;^2.5.4&amp;quot;
  }&lt;/pre&gt;
  &lt;ul id=&quot;btNx&quot;&gt;
    &lt;li id=&quot;CcW4&quot;&gt;&lt;code&gt;vue&lt;/code&gt; - это основная библиотека, которая работает во время выполнения проекта&lt;/li&gt;
    &lt;li id=&quot;HOCb&quot;&gt;&lt;code&gt;@vitejs/plugin-vue&lt;/code&gt; - плагин, отвечающий за обслуживание и компоновку проекта Vue&lt;/li&gt;
    &lt;li id=&quot;zMPh&quot;&gt;&lt;code&gt;@vue/compiler-sfc&lt;/code&gt; необходим для компиляции SFC-файла&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;0PhQ&quot;&gt;Поэтому можно с уверенностью сказать, что эти три пакета дают проекту Vite возможность понимать код Vue. Пакет&lt;code&gt; @vitejs/plugin-vue&lt;/code&gt; - это &amp;quot;мост&amp;quot;, соединяющий ядро системы Vite с фреймворком Vue.js.&lt;/p&gt;
  &lt;h2 id=&quot;fQK7&quot;&gt;Vue-плагин&lt;/h2&gt;
  &lt;p id=&quot;2fM7&quot;&gt;Как мы видели в &lt;code&gt;package.json&lt;/code&gt; плагина Vue, пакет &lt;code&gt;@vitejs/plugin-vue&lt;/code&gt; отвечает за сборку проекта Vue.&lt;/p&gt;
  &lt;p id=&quot;HSGY&quot;&gt;Vite делегирует работу по сборке Rollup, который является еще одним очень популярным инструментом сборки. Взаимосвязь между плагинами полагается на ядро &lt;code&gt;vite&lt;/code&gt; для вызова кода пакета &lt;code&gt;плагина&lt;/code&gt; в некоторые определенные моменты времени. Эти определенные моменты называются &lt;strong&gt;хуками&lt;/strong&gt;. Разработчик плагина должен решить, какой код будет выполняться в каждом хуке.&lt;/p&gt;
  &lt;p id=&quot;c0yA&quot;&gt;Например, в исходном коде плагина Vue можно увидеть некоторые из этих хуков.&lt;/p&gt;
  &lt;p id=&quot;34fd&quot;&gt;📁 &lt;strong&gt;/packages/plugin-vue/src/index.ts&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;NyZm&quot; data-lang=&quot;javascript&quot;&gt;async resolveId(id) {
  // component export helper
  if (id === EXPORT_HELPER_ID) {
    return id
  }
  
  if (parseVueRequest(id).query.vue) {
    return id
  }
},

load(id, ssr = !!options.ssr) {
  if (id === EXPORT_HELPER_ID) {
    return helperCode
  }

  const { filename, query } = parseVueRequest(id)
  // выбрать соответствующий блок для виртуальных модулей подчастей
  if (query.vue) {
    if (query.src) {
      return fs.readFileSync(filename, &amp;#x27;utf-8&amp;#x27;)
    }
    const descriptor = getDescriptor(filename, options)!
    let block: SFCBlock | null | undefined
    if (query.type === &amp;#x27;script&amp;#x27;) {
      // обработка слияния &amp;lt;script&amp;gt; + &amp;lt;script setup&amp;gt; через compileScript()
      block = getResolvedScript(descriptor, ssr)
    } else if (query.type === &amp;#x27;template&amp;#x27;) {
      block = descriptor.template!
    } else if (query.type === &amp;#x27;style&amp;#x27;) {
      block = descriptor.styles[query.index!]
    } else if (query.index != null) {
      block = descriptor.customBlocks[query.index]
    }
    if (block) {
      return {
        code: block.content,
        map: block.map as any
      }
    }
  }
},

transform(code, id, ssr = !!options.ssr) {
  const { filename, query } = parseVueRequest(id)
  if (query.raw) {
    return
  }
  if (!filter(filename) &amp;amp;&amp;amp; !query.vue) {
    if (!query.vue &amp;amp;&amp;amp; refTransformFilter(filename)) {
      if (!canUseRefTransform) {
        this.warn(&amp;#x27;refTransform requires @vue/compiler-sfc@^3.2.5.&amp;#x27;)
      } else if (shouldTransformRef(code)) {
        return transformRef(code, {
          filename,
          sourceMap: true
        })
      }
    }
    return
  }
    if (!query.vue) {
    // основной запрос
    return transformMain(
      code,
      filename,
      options,
      this,
      ssr,
      customElementFilter(filename)
    )
  } else {
    // запрос на подблок
    const descriptor = getDescriptor(filename, options)!
    if (query.type === &amp;#x27;template&amp;#x27;) {
      return transformTemplateAsModule(code, descriptor, options, this, ssr)
    } else if (query.type === &amp;#x27;style&amp;#x27;) {
      return transformStyle(
        code,
        descriptor,
        Number(query.index),
        options,
        this
      )
    }
  }
}&lt;/pre&gt;
  &lt;p id=&quot;MBol&quot;&gt;А в основном пакете &lt;code&gt;vite&lt;/code&gt;, Rollup будет использоваться для вызова вышеуказанных хуков плагина.&lt;/p&gt;
  &lt;p id=&quot;1Ms4&quot;&gt;📁 &lt;strong&gt;/packages/vite/src/node/build.ts&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;sLFT&quot; data-lang=&quot;javascript&quot;&gt;// сначала собирает все используемые плагины
const plugins = (
  ssr ? config.plugins.map((p) =&amp;gt; injectSsrFlagToHooks(p)) : config.plugins
) as Plugin[]

...

// затем поместите плагины и все остальное в объект options
const rollupOptions: RollupOptions = {
  input,
  preserveEntrySignatures: ssr
    ? &amp;#x27;allow-extension&amp;#x27;
    : libOptions
    ? &amp;#x27;strict&amp;#x27;
    : false,
  ...options.rollupOptions,
  plugins,
  external,
  onwarn(warning, warn) {
    onRollupWarning(warning, warn, config)
  }
}

...

// наконец, делегировать rollup
const bundle = await rollup.rollup(rollupOptions)&lt;/pre&gt;
  &lt;p id=&quot;Ojv9&quot;&gt;Плагин Rollup очень похож на плагин Vite. Но поскольку Rollup не предназначен для использования в качестве инструмента сборки из коробки, плагин Vite будет иметь дополнительные опции и хуки, которые недоступны в классическом плагине Rollup.&lt;/p&gt;
  &lt;p id=&quot;SAHe&quot;&gt;Другими словами, плагин Vite - это расширение плагина Rollup.&lt;/p&gt;
  &lt;h2 id=&quot;wJEK&quot;&gt;Команды Vite&lt;/h2&gt;
  &lt;p id=&quot;HtMh&quot;&gt;Возвращаясь к шаблону Vue, давайте уделим немного внимания опции &lt;code&gt;scripts&lt;/code&gt;.&lt;/p&gt;
  &lt;p id=&quot;CfDW&quot;&gt;📁 &lt;strong&gt;/packages/create-vite/template-vue/package.json&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;D7vq&quot; data-lang=&quot;javascript&quot;&gt;&amp;quot;scripts&amp;quot;: {
  &amp;quot;dev&amp;quot;: &amp;quot;vite&amp;quot;,
  &amp;quot;build&amp;quot;: &amp;quot;vite build&amp;quot;,
  &amp;quot;serve&amp;quot;: &amp;quot;vite preview&amp;quot;
},&lt;/pre&gt;
  &lt;p id=&quot;LODU&quot;&gt;Это конфигурации, которые позволяют нам выполнять следующие команды внутри проекта Vite:&lt;/p&gt;
  &lt;ul id=&quot;ggFx&quot;&gt;
    &lt;li id=&quot;2A5e&quot;&gt;&lt;code&gt;npm run dev&lt;/code&gt; для запуска сервера разработки&lt;/li&gt;
    &lt;li id=&quot;0V00&quot;&gt;&lt;code&gt;npm run build&lt;/code&gt; для создания production сборки&lt;/li&gt;
    &lt;li id=&quot;q55y&quot;&gt;&lt;code&gt;npm run serve&lt;/code&gt; для предварительного локального просмотра указанной production сборки&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;eIdq&quot;&gt;Приведенные выше команды сопоставлены со следующими командами:&lt;/p&gt;
  &lt;ul id=&quot;dkGR&quot;&gt;
    &lt;li id=&quot;k2Jz&quot;&gt;&lt;code&gt;vite&lt;/code&gt;&lt;/li&gt;
    &lt;li id=&quot;CSPW&quot;&gt;&lt;code&gt;vite build&lt;/code&gt;&lt;/li&gt;
    &lt;li id=&quot;dUJB&quot;&gt;&lt;code&gt;vite preview&lt;/code&gt;&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;PWjP&quot;&gt;Как видите, пакет &lt;code&gt;vite&lt;/code&gt; - это то, с чего все начинается.&lt;/p&gt;
  &lt;p id=&quot;USNq&quot;&gt;Вы можете получить представление о том, какие еще сторонние инструменты задействованы, заглянув в файл &lt;code&gt;package.json&lt;/code&gt; пакета &lt;code&gt;vite&lt;/code&gt;.&lt;/p&gt;
  &lt;p id=&quot;Q2EB&quot;&gt;📁 &lt;strong&gt;/packages/vite/package.json&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;g1au&quot; data-lang=&quot;javascript&quot;&gt;&amp;quot;dependencies&amp;quot;: {
  &amp;quot;esbuild&amp;quot;: &amp;quot;^0.12.17&amp;quot;,
  &amp;quot;postcss&amp;quot;: &amp;quot;^8.3.6&amp;quot;,
  &amp;quot;resolve&amp;quot;: &amp;quot;^1.20.0&amp;quot;,
  &amp;quot;rollup&amp;quot;: &amp;quot;^2.38.5&amp;quot;
},&lt;/pre&gt;
  &lt;p id=&quot;RfSL&quot;&gt;Как вы можете видеть, &lt;code&gt;vite&lt;/code&gt; на самом деле использует два разных пакетника за кадром: Rollup и esbuild.&lt;/p&gt;
  &lt;h2 id=&quot;rollupvsesbuild&quot;&gt;Rollup vs esbuild&lt;/h2&gt;
  &lt;p id=&quot;l39b&quot;&gt;Vite использует оба этих пакетника для различных видов деятельности.&lt;/p&gt;
  &lt;p id=&quot;CVvz&quot;&gt;Rollup используется Vite для основных нужд пакетирования. А esbuild используется для совместимости и оптимизации модулей. Эти шаги известны как процесс &amp;quot;Предварительного объединения зависимостей&amp;quot; (Dependency Pre-bundling). Этот процесс считается &amp;quot;тяжелым&amp;quot;, поскольку его необходимо выполнять на основе каждого модуля, а в проекте обычно используется много модулей.&lt;/p&gt;
  &lt;p id=&quot;q1XB&quot;&gt;Совместимость модулей означает преобразование различных форматов (модули UMD или CommonJS) в стандартный формат ESM.&lt;/p&gt;
  &lt;p id=&quot;yTLL&quot;&gt;Оптимизация предназначена для объединения всех различных файлов из одного зависимого пакета в одно &amp;quot;нечто&amp;quot;, которое затем нужно получить только один раз.&lt;/p&gt;
  &lt;p id=&quot;avL5&quot;&gt;Rollup был бы слишком медленным для обработки тяжелых вещей по сравнению с esbuild. Esbuild на самом деле является самым быстрым инструментом сборки. Он быстрый, потому что разработан на Go (язык программирования).&lt;/p&gt;
  &lt;p id=&quot;rNLJ&quot;&gt;Вот &lt;a href=&quot;https://esbuild.github.io/&quot; target=&quot;_blank&quot;&gt;сравнение, приведенное на сайте&lt;/a&gt; официальной документации.&lt;/p&gt;
  &lt;figure id=&quot;0jD5&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://uploads.sitepoint.com/wp-content/uploads/2021/09/1632215023img-14-benchmark.png&quot; width=&quot;1644&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;e01M&quot;&gt;Как видите, esbuild не просто быстрый, он находится на совершенно другом уровне. Вот почему Vite работает молниеносно.&lt;/p&gt;
  &lt;h2 id=&quot;kBtT&quot;&gt;Заключение&lt;/h2&gt;
  &lt;p id=&quot;NOzs&quot;&gt;В этой статье мы узнали, что:&lt;/p&gt;
  &lt;ul id=&quot;M0t4&quot;&gt;
    &lt;li id=&quot;m3HZ&quot;&gt;команда &lt;code&gt;npm init vite&lt;/code&gt; использует инструмент &lt;code&gt;create-vite&lt;/code&gt;&lt;/li&gt;
    &lt;li id=&quot;mztu&quot;&gt;пакет &lt;code&gt;create-vite&lt;/code&gt; содержит все встроенные шаблоны&lt;/li&gt;
    &lt;li id=&quot;4qY8&quot;&gt;специфичный для фреймворка шаблон зависит от соответствующего специфичного для фреймворка плагина&lt;/li&gt;
    &lt;li id=&quot;222r&quot;&gt;плагины реализованы в архитектуре, основанной на хуках&lt;/li&gt;
    &lt;li id=&quot;Xtxy&quot;&gt;Vite использует Rollup и esbuild за кадром.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;TgEJ&quot;&gt;Теперь у вас должно быть твердое понимание системы Vite. Но на практике вам понадобятся другие общие возможности, которые мы здесь не рассмотрели. Самыми распространенными из них являются поддержка TypeScript и препроцессора CSS.&lt;/p&gt;
  &lt;p id=&quot;hshv&quot;&gt;Источник: &lt;a href=&quot;https://www.sitepoint.com/exploring-vite-source-code/&quot; target=&quot;_blank&quot;&gt;https://www.sitepoint.com/exploring-vite-source-code/&lt;/a&gt;&lt;/p&gt;

</content></entry><entry><id>budnifronta:T5lkedL8RUF</id><link rel="alternate" type="text/html" href="https://teletype.in/@budnifronta/T5lkedL8RUF?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=budnifronta"></link><title>Фрагменты React: простой синтаксис для повышения производительности</title><published>2022-01-15T15:38:57.960Z</published><updated>2022-01-16T17:57:40.144Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img3.teletype.in/files/e1/14/e11495dc-ca24-4865-a3c6-e6abaf4b3856.jpeg"></media:thumbnail><summary type="html">&lt;img src=&quot;https://img2.teletype.in/files/96/75/96758973-f437-4eb9-9e1b-81a67b7ed01a.jpeg&quot;&gt;Фрагменты React были представлены в ноябре 2017 года в версии React 16.2.0. Хотя они существуют уже давно, многие разработчики React избегают их использования, или применяют их, не зная, что это такое. Фрагменты React - это начальная, но ключевая функция, и каждый разработчик React должен освоить ее, независимо от уровня квалификации. Кроме того, учитывая, как давно они стали частью React, их уже нельзя игнорировать.</summary><content type="html">
  &lt;figure id=&quot;OjCo&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/96/75/96758973-f437-4eb9-9e1b-81a67b7ed01a.jpeg&quot; width=&quot;1280&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;zRxU&quot;&gt;Фрагменты React были представлены в ноябре 2017 года в версии React 16.2.0. Хотя они существуют уже давно, многие разработчики React избегают их использования, или применяют их, не зная, что это такое. Фрагменты React - это начальная, но ключевая функция, и каждый разработчик React должен освоить ее, независимо от уровня квалификации. Кроме того, учитывая, как давно они стали частью React, их уже нельзя игнорировать.&lt;/p&gt;
  &lt;p id=&quot;LFEt&quot;&gt;Итак, давайте рассмотрим все, что вам нужно для освоения фрагментов React.&lt;/p&gt;
  &lt;h2 id=&quot;Qe2j&quot;&gt;Почему существуют фрагменты React&lt;/h2&gt;
  &lt;p id=&quot;euzs&quot;&gt;Как указано в официальной документации React, возврат более чем одного элемента HTML - это часто желаемое поведение для компонентов React. Чтобы добиться этого, вы должны обернуть все эти элементы тегом HTML. Это связано с тем, что React требует, чтобы компоненты возвращали только один элемент HTML. Самым простым решением было бы использовать тег &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;. С логической точки зрения этот дополнительный &amp;lt;div&amp;gt; обычно можно считать неуместным, но он имеет последствия.&lt;/p&gt;
  &lt;p id=&quot;kGQd&quot;&gt; Во-первых, постоянно используя такой подход, вы делаете DOM более вложенным и, следовательно, более медленным для рендеринга. Во-вторых, такой подход может привести к некорректному HTML, как вы вскоре увидите.&lt;/p&gt;
  &lt;p id=&quot;RtGq&quot;&gt;Например, допустим, у вас есть компонент &lt;code&gt;Table&lt;/code&gt;, который отображает таблицу HTML, колонки которой отображаются с помощью другого компонента под названием &lt;code&gt;Columns&lt;/code&gt;. Вот код, который вы можете использовать для этого:&lt;/p&gt;
  &lt;pre id=&quot;xgQj&quot; data-lang=&quot;javascript&quot;&gt;function Table() {
  return (
    &amp;lt;table&amp;gt;
      &amp;lt;tr&amp;gt;
        &amp;lt;Columns /&amp;gt;
      &amp;lt;/tr&amp;gt;
    &amp;lt;/table&amp;gt;
  );
}

// обертка div, используемая для возврата двух тегов &amp;lt;td&amp;gt;
function Columns() {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;td&amp;gt;Hello&amp;lt;/td&amp;gt;
      &amp;lt;td&amp;gt;World&amp;lt;/td&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}&lt;/pre&gt;
  &lt;p id=&quot;KZ9b&quot;&gt;В результате будет выведен следующий HTML, который является недопустимым, поскольку &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; не может быть дочерним элементом &lt;code&gt;&amp;lt;tr&amp;gt;&lt;/code&gt;.&lt;/p&gt;
  &lt;pre id=&quot;pYIN&quot; data-lang=&quot;html&quot;&gt;&amp;lt;table&amp;gt;
  &amp;lt;tr&amp;gt;
    &amp;lt;div&amp;gt;
      &amp;lt;td&amp;gt;Hello&amp;lt;/td&amp;gt;
      &amp;lt;td&amp;gt;World&amp;lt;/td&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/tr&amp;gt;
&amp;lt;/table&amp;gt;
&lt;/pre&gt;
  &lt;p id=&quot;UUCy&quot;&gt;React-фрагменты были введены именно для решения этой проблемы.&lt;/p&gt;
  &lt;h2 id=&quot;xfPb&quot;&gt;Что такое React-фрагменты&lt;/h2&gt;
  &lt;p id=&quot;qLla&quot;&gt;Фрагменты React включают в себя специальный синтаксис, который позволяет группировать список HTML-элементов без добавления дополнительных узлов в DOM. Другими словами, Фрагменты React позволяют группировать несколько дочерних компонентов без внесения лишней разметки в отображаемый HTML, предлагая решение проблемы, рассмотренной ранее, и многих других.&lt;/p&gt;
  &lt;h2 id=&quot;SU2l&quot;&gt;Как их использовать&lt;/h2&gt;
  &lt;p id=&quot;Ji95&quot;&gt;Вы можете использовать фрагменты React, обернув дочерние элементы, которые будут возвращены вашим компонентом, тегом &lt;code&gt;&amp;lt;React.Fragments&amp;gt;&lt;/code&gt;. Возвращаясь к приведенному выше примеру, компонент &lt;code&gt;Columns&lt;/code&gt; будет написан следующим образом:&lt;/p&gt;
  &lt;pre id=&quot;Fnn7&quot; data-lang=&quot;javascript&quot;&gt;function Columns() {
  return (
    &amp;lt;React.Fragment&amp;gt;
      &amp;lt;td&amp;gt;Hello&amp;lt;/td&amp;gt;
      &amp;lt;td&amp;gt;World&amp;lt;/td&amp;gt;
    &amp;lt;/React.Fragment&amp;gt;
  );
}&lt;/pre&gt;
  &lt;p id=&quot;09M3&quot;&gt;Это приведет к тому, что компонент &lt;code&gt;Table&lt;/code&gt; будет переведен в следующий HTML:&lt;/p&gt;
  &lt;pre id=&quot;hpys&quot; data-lang=&quot;html&quot;&gt;&amp;lt;table&amp;gt;
  &amp;lt;tr&amp;gt;
    &amp;lt;td&amp;gt;Hello&amp;lt;/td&amp;gt;
    &amp;lt;td&amp;gt;World&amp;lt;/td&amp;gt;
  &amp;lt;/tr&amp;gt;
&amp;lt;/table&amp;gt;&lt;/pre&gt;
  &lt;p id=&quot;Qr57&quot;&gt;Как вы можете видеть, в отображаемом HTML нет тега обертки. В отличие от того, что было раньше, это не приведет к некорректному HTML.&lt;/p&gt;
  &lt;p id=&quot;ebIB&quot;&gt;В фрагментах React также можно использовать короткий синтаксис, который выглядит как пустой тег:&lt;/p&gt;
  &lt;pre id=&quot;0Kdo&quot; data-lang=&quot;javascript&quot;&gt;// использование &amp;lt;&amp;gt; - это то же самое, что использование &amp;lt;React.Fragment&amp;gt;
// использование &amp;lt;/&amp;gt; - это то же самое, что использование &amp;lt;/React.Fragment&amp;gt;
function Columns() {
  return (
    &amp;lt;&amp;gt;
      &amp;lt;td&amp;gt;Hello&amp;lt;/td&amp;gt;
      &amp;lt;td&amp;gt;World&amp;lt;/td&amp;gt;
    &amp;lt;/&amp;gt;
  );
}&lt;/pre&gt;
  &lt;p id=&quot;VdeI&quot;&gt;Это приводит к тому же результату, что и в примере выше. Поэтому помните, что пустой тег - это сокращение для &lt;code&gt;&amp;lt;React.Fragment&amp;gt;&lt;/code&gt;.&lt;/p&gt;
  &lt;h2 id=&quot;Eq2k&quot;&gt;Когда их использовать&lt;/h2&gt;
  &lt;p id=&quot;Or21&quot;&gt;В принципе, вы должны использовать &lt;code&gt;React Fragments&lt;/code&gt; в любом случае, чтобы не использовать лишнюю обертку &amp;lt;div&amp;gt;, чтобы заставить ваш компонент возвращать более одного элемента HTML. &lt;/p&gt;
  &lt;p id=&quot;dloc&quot;&gt;Поэтому не думайте о фрагментах Reаct как о замене &amp;lt;div&amp;gt; в вашем HTML. Напротив, рассматривайте их как способ избежать ненужных тегов и получить в результате лучшую структуру разметки.&lt;/p&gt;
  &lt;p id=&quot;fgkH&quot;&gt;Существует три варианта использования фрагментов React. Давайте рассмотрим их все.&lt;/p&gt;
  &lt;h3 id=&quot;IQjS&quot;&gt;1. Обертывание нескольких элементов HTML&lt;/h3&gt;
  &lt;p id=&quot;woWS&quot;&gt;Как вы уже догадались, обертывание нескольких элементов HTML является наиболее распространенным случаем использования фрагментов React. Всякий раз, когда вам нужно определить компонент React, который должен возвращать несколько элементов HTML, вы должны обернуть их тегом &lt;code&gt;&amp;lt;React.Fragment&amp;gt;&lt;/code&gt; или &lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;. Как мы уже видели, это рекомендуемый подход, поскольку использование любого другого оберточного тега может привести к некорректному HTML.&lt;/p&gt;
  &lt;p id=&quot;im6H&quot;&gt;Давайте посмотрим их в действии при определении компонента, возвращающего четыре HTML-элемента.&lt;/p&gt;
  &lt;pre id=&quot;U7Jq&quot; data-lang=&quot;javascript&quot;&gt;// возвращение 4 &amp;lt;div&amp;gt; без добавление дополнительной обертки &amp;lt;div&amp;gt;
function FragmentExample () {  
  return (
    &amp;lt;&amp;gt;
      &amp;lt;div&amp;gt;
        First div
      &amp;lt;/div&amp;gt;
      &amp;lt;div&amp;gt;
        Second div
      &amp;lt;/div&amp;gt;
      &amp;lt;div&amp;gt;
        Third div
      &amp;lt;/div&amp;gt;
      &amp;lt;div&amp;gt;
        Fourth div
      &amp;lt;/div&amp;gt;
    &amp;lt;/&amp;gt;
  );  
}
ReactDOM.render(
  &amp;lt;FragmentExample/&amp;gt;,
  document.getElementById(&amp;#x27;container&amp;#x27;)
);&lt;/pre&gt;
  &lt;figure id=&quot;CwDa&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/49/e5/49e54049-399b-450c-9525-f34266aadeb4.png&quot; width=&quot;726&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;IuYo&quot;&gt;&lt;a href=&quot;https://codepen.io/SitePoint/pen/VwbwQvJ&quot; target=&quot;_blank&quot;&gt;Ссылка на Codepen&lt;/a&gt;&lt;/p&gt;
  &lt;h3 id=&quot;yCFX&quot;&gt;2. Фрагменты с ключом&lt;/h3&gt;
  &lt;p id=&quot;Azde&quot;&gt;Как указано в &lt;a href=&quot;https://ru.reactjs.org/docs/fragments.html#keyed-fragments&quot; target=&quot;_blank&quot;&gt;документации React&lt;/a&gt;, фрагменты, объявленные с помощью явного синтаксиса &lt;code&gt;&amp;lt;React.Fragment&amp;gt;&lt;/code&gt;, могут иметь ключи, и это полезно при работе с любой коллекцией JavaScript. Обратите внимание, что при использовании краткого синтаксиса это не так.&lt;/p&gt;
  &lt;p id=&quot;mZSY&quot;&gt;Например, допустим, у вас есть массив объектов, где каждый элемент представляет автора. Ваша цель - отобразить всех авторов, используя данные из этого массива. Этого можно достичь путем отображения каждого элемента массива на соответствующий HTML-элемент, который, согласно требованиям React, &lt;a href=&quot;https://ru.reactjs.org/docs/lists-and-keys.html#gatsby-focus-wrapper&quot; target=&quot;_blank&quot;&gt;должен иметь уникальный ключ&lt;/a&gt;. Поскольку фрагменты React поддерживают ключевые реквизиты, вы можете использовать их для достижения этой цели без введения дополнительной разметки. Давайте посмотрим на это на живом примере:&lt;/p&gt;
  &lt;figure id=&quot;qkJr&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/a5/cb/a5cba776-f9ee-4689-9e9c-d740fcb1e047.png&quot; width=&quot;733&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;yRpz&quot;&gt;&lt;a href=&quot;https://codepen.io/SitePoint/pen/bGWGLpB&quot; target=&quot;_blank&quot;&gt;Ссылка на Codepen&lt;/a&gt;&lt;/p&gt;
  &lt;h3 id=&quot;4TfA&quot;&gt;3. Условный рендеринг&lt;/h3&gt;
  &lt;p id=&quot;EdpQ&quot;&gt;Когда дело доходит до условного рендеринга, React требует, чтобы вы возвращали один элемент в обеих ветвях. Именно здесь на помощь приходят фрагменты React, позволяющие более легко выводить группы элементов и избегать добавления ненужных дополнительных тегов, как в следующем примере:&lt;/p&gt;
  &lt;figure id=&quot;dvJQ&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/ac/7b/ac7bb39f-e49b-4478-9ed9-f6ee30b1478c.png&quot; width=&quot;724&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;1Pat&quot;&gt;&lt;a href=&quot;https://codepen.io/SitePoint/pen/rNmNJeK&quot; target=&quot;_blank&quot;&gt;Ссылка на Codepen&lt;/a&gt;&lt;/p&gt;
  &lt;h2 id=&quot;qjmA&quot;&gt;Заключение&lt;/h2&gt;
  &lt;p id=&quot;UQGb&quot;&gt;В этой статье мы рассмотрели фрагменты React и почему они являются неизбежной функцией, которую должен освоить каждый разработчик React. Фрагменты позволяют создавать лучшую структуру DOM, избегая вставки ненужных &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;. Кроме того, более чистая структура разметки означает более короткое время рендеринга, что является отличным решением. Фрагменты React позволяют вам писать более чистый, поддерживаемый и читаемый код.&lt;/p&gt;
  &lt;p id=&quot;tHgB&quot;&gt;Источник: &lt;a href=&quot;https://www.sitepoint.com/react-fragments-introduction/&quot; target=&quot;_blank&quot;&gt;https://www.sitepoint.com/react-fragments-introduction/&lt;/a&gt;&lt;/p&gt;

</content></entry><entry><id>budnifronta:HVR5XLVRkkK</id><link rel="alternate" type="text/html" href="https://teletype.in/@budnifronta/HVR5XLVRkkK?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=budnifronta"></link><title>5 лучших инструментов для передачи дизайна в 2022 году</title><published>2022-01-13T20:22:36.391Z</published><updated>2022-01-14T19:27:47.754Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img1.teletype.in/files/00/4b/004b8755-1004-4b80-8673-9f4cbe66a1ae.jpeg"></media:thumbnail><summary type="html">&lt;img src=&quot;https://img2.teletype.in/files/55/5d/555de15d-afba-4c62-93a5-84784496f1be.jpeg&quot;&gt;В этой статье мы рассмотрим текущее состояние инструментов передачи дизайна и процесса проектирования в целом, а также предложу мой выбор из пяти лучших инструментов дизайна, представленных на сегодняшнем рынке.</summary><content type="html">
  &lt;figure id=&quot;RuCS&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/55/5d/555de15d-afba-4c62-93a5-84784496f1be.jpeg&quot; width=&quot;1280&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;lERk&quot;&gt;В этой статье мы рассмотрим текущее состояние инструментов передачи дизайна и процесса проектирования в целом, а также предложу мой выбор из пяти лучших инструментов дизайна, представленных на сегодняшнем рынке.&lt;/p&gt;
  &lt;p id=&quot;pIIr&quot;&gt;&amp;quot;Передача дизайна&amp;quot; подразумевает под собой предоставление дизайна UI разработчику, который будет его программировать (верстать). До появления термина &amp;quot;передача дизайна&amp;quot; его передача была сложной, неприятной и часто катастрофической задачей. В те времена Adobe Photoshop был единственным доступным инструментом для проектирования пользовательских интерфейсов, а инструментов и/или функций для дизайна не существовало. Преобразование дизайна в код именовалось &amp;quot;нарезкой PSD&amp;quot;. &lt;/p&gt;
  &lt;p id=&quot;y8zJ&quot;&gt;За нарезку PSD (документа Photoshop) отвечал разработчик, что было очень неприятно, поскольку разработчики по понятным причинам не хотели работать с инструментами дизайна. Дизайнеры вручную документировали спецификации дизайна, чтобы сделать все более понятным, но это все равно приводило к визуальным/функциональным несоответствиям и бурным дискуссиям с разработчиками. &lt;/p&gt;
  &lt;h2 id=&quot;VCDm&quot;&gt;Передача дизайна сегодня&lt;/h2&gt;
  &lt;p id=&quot;D9u4&quot;&gt;В настоящее время существует множество инструментов UI с функциями передачи дизайна и даже инструментов, полностью предназначенных для передачи дизайна, которые помогают дизайнерам и разработчикам переводить дизайн в код, хранить файлы, поддерживать согласованность между элементами и облегчать хорошее сотрудничество дизайнера и разработчика.&lt;/p&gt;
  &lt;p id=&quot;guAf&quot;&gt;Современные дизайнеры и разработчики считают процесс передачи дизайна одним из ключевых процессов разработки, будь то создание системы дизайна или продукта с нуля. Более того, инструменты разработки UI, такие как Figma, предлагают функции передачи и системы разработки вместе.&lt;/p&gt;
  &lt;h2 id=&quot;yNDN&quot;&gt;Что на самом деле делают инструменты передачи дизайна?&lt;/h2&gt;
  &lt;p id=&quot;VJue&quot;&gt;Инструменты передачи помогают:&lt;/p&gt;
  &lt;ul id=&quot;dV6T&quot;&gt;
    &lt;li id=&quot;n1Ph&quot;&gt;дизайнерам подготовить свои проекты к проверке&lt;/li&gt;
    &lt;li id=&quot;4cD6&quot;&gt;разработчикам в проверке и переводе проектов в код&lt;/li&gt;
    &lt;li id=&quot;nTER&quot;&gt;дизайнерам и разработчикам сотрудничать и общаться&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;y7Pq&quot;&gt;Без передачи дизайна разработчикам остается только одна альтернатива: гадать. Угадывание часто приводит к визуальным и функциональным неточностям - например, использованию неправильных цветов или странному поведению элементов взаимодействия. &lt;/p&gt;
  &lt;p id=&quot;kxZ9&quot;&gt;Давайте рассмотрим пять лучших инструментов для передачи дизайна.&lt;/p&gt;
  &lt;h2 id=&quot;figmahttpsfigmacommostused&quot;&gt;&lt;a href=&quot;https://figma.com/&quot; target=&quot;_blank&quot;&gt;Figma&lt;/a&gt;&lt;/h2&gt;
  &lt;p id=&quot;jcer&quot;&gt;Платформы: Web, macOS, Linux, Windows&lt;br /&gt;Цена: 3 тарифа: Бесплатный, $12 в месяц, $45 в месяц&lt;/p&gt;
  &lt;figure id=&quot;c7g8&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/43/33/433318fc-cc99-41d3-b0ee-a7770e4f7c96.png&quot; width=&quot;1348&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;CFJU&quot;&gt;Хотя Figma не так совершенна, как Zeplin, в плане количества поддерживаемых языков кода, она переводит стили дизайна в CSS (для веб), Swift (для iOS/macOS/iPadOS) и XML (для Android). Однако это в любом случае должно покрывать большинство случаев передачи дизайна.&lt;/p&gt;
  &lt;p id=&quot;IXHk&quot;&gt;Альтернативные инструменты передачи дизайна могут быть установлены в качестве плагинов Figma для случаев, когда дизайн необходимо перевести в Sass, Less, Stylus, код React Native и т. д.&lt;/p&gt;
  &lt;p id=&quot;2Ze3&quot;&gt;Изображения можно экспортировать или копировать в буфер обмена в формате SVG или PNG, все сразу или по отдельности, в любом разрешении.&lt;/p&gt;
  &lt;p id=&quot;y0BO&quot;&gt;Если коллегам есть что сказать (или спросить) о дизайне, они могут четко и открыто сообщить об этом с помощью контекстных комментариев, что способствует сотрудничеству и гарантирует, что все согласны с тем, как дизайн должен выглядеть, ощущаться и функционировать.&lt;/p&gt;
  &lt;p id=&quot;iEOv&quot;&gt;Figma - это не только самый используемый инструмент для передачи дизайна, но и для пользовательских потоков, пользовательских интерфейсов, интерактивных прототипов, систем проектирования и контроля версий (согласно исследованию 2020 Design Tools Survey). Хотя Zeplin является самым популярным инструментом для передачи данных благодаря тому, что он поддерживает больше языков программирования, Figma не слишком отстает от него, поскольку он многофункционален и позволяет выполнять гораздо больше функций, чем просто передача данных.&lt;/p&gt;
  &lt;p id=&quot;ycLF&quot;&gt;Поэтому я бы выбрал Figma (как и большинство команд) до тех пор, пока мне не понадобится передавать проекты, использующие неподдерживаемый язык кода, и в этом случае Zeplin станет более чем идеальным вторичным вариантом.&lt;/p&gt;
  &lt;h2 id=&quot;zeplinhttpszepliniohighestrated&quot;&gt;&lt;a href=&quot;https://zeplin.io/&quot; target=&quot;_blank&quot;&gt;Zeplin&lt;/a&gt;&lt;/h2&gt;
  &lt;p id=&quot;oupp&quot;&gt;Платформы: Web, macOS, Windows&lt;br /&gt;Импорт из: Sketch, Figma, Adobe XD, Photoshop&lt;br /&gt;Стоимость: Имеет 3 тарифа. Бесплатный, $6/месяц, $12/месяц&lt;/p&gt;
  &lt;figure id=&quot;BBy2&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/ea/80/ea80765c-e18e-4ca8-9f36-284f4b2d2498.png&quot; width=&quot;1345&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;U3PY&quot;&gt;Zeplin поддерживает больше языков, чем Figma (React Native, Sass, Less, Stylus и т.д. в дополнение к стандартным Swift, XML и CSS). Он также дешевле, чем аналогичные инструменты Figma, хотя это объясняется тем, что аналогичные инструменты Figma многофункциональны и охватывают гораздо большую часть рабочего процесса проектирования пользовательского интерфейса. Zeplin является самым высоко оцененным инструментом для передачи дизайна, поэтому некоторые дизайнеры склонны не замечать этот недостаток.&lt;/p&gt;
  &lt;p id=&quot;byzd&quot;&gt;Чтобы использовать Zeplin, вам придется сначала создать дизайн с помощью Photoshop, Adobe XD, Sketch или Figma, поэтому совершенно понятно, что некоторые дизайнеры предпочитают, чтобы рабочий процесс по созданию пользовательского интерфейса ограничивался одним инструментом, и, вероятно, именно поэтому Figma используется чаще, чем Zeplin.&lt;/p&gt;
  &lt;p id=&quot;jdK3&quot;&gt;С функциональной точки зрения, Zeplin делает все, что вы ожидаете от инструмента передачи данных (и делает это довольно хорошо). Он экспортирует изображения в различные форматы и с различным разрешением, переводит стили дизайна в код и облегчает коммуникацию.&lt;/p&gt;
  &lt;h2 id=&quot;invisionhttpsinvisionappcom&quot;&gt;&lt;a href=&quot;https://invisionapp.com/&quot; target=&quot;_blank&quot;&gt;InVision&lt;/a&gt;&lt;/h2&gt;
  &lt;p id=&quot;93hD&quot;&gt;Платформы: Web, macOS, Windows&lt;br /&gt;Цена: $0/месяц, $7.95/месяц&lt;/p&gt;
  &lt;figure id=&quot;BBLf&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/50/45/5045ddf9-b6d7-40ab-84d7-6b9d315a025d.png&quot; width=&quot;1335&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;x4AB&quot;&gt;Инструмент передачи дизайна Inspect компании InVision, который работает в рамках Specs и Prototype, является лишь одним из инструментов в большом наборе средств совместной работы над дизайном компании InVision.&lt;/p&gt;
  &lt;p id=&quot;RNt6&quot;&gt;Однако InVision Studio (инструмент InVision для проектирования пользовательского интерфейса) - это то место, где вы, скорее всего, будете создавать свои проекты, прежде чем передавать их разработчикам. Studio доступна для пользователей macOS и Windows.&lt;/p&gt;
  &lt;p id=&quot;Ed3t&quot;&gt;Хотя стоимость пакета InVision составляет всего 7,95 долларов за пользователя в месяц, что звучит как выгодная сделка по сравнению с аналогичными инструментами, в последнее время компания InVision была вовлечена в негативные отзывы из-за чрезмерных затрат на маркетинг инструментов, которые не оправдали надежд. Основная критика заключается в том, что инструменты InVision иногда кажутся полуфабрикатами и не связанными друг с другом, даже после отложенного запуска. В отличие от этого, Figma работает как единое приложение безупречно.&lt;/p&gt;
  &lt;p id=&quot;ra3C&quot;&gt;Тем не менее, InVision является третьим наиболее используемым инструментом для передачи дизайна и по-прежнему широко используется в целом. Хотя кажется, что его популярность снижается, так как конкуренты отъедают свою долю рынка, в последнее время он ведет себя тихо.&lt;/p&gt;
  &lt;p id=&quot;Usdo&quot;&gt;Инструмент Inspect от InVision может переводить стили дизайна в CSS, Less, Sass, SCSS, Stylus, Swift/Objective-C (Apple) и XML (Android) - впечатляющий список. Если вы знакомы с экосистемой InVision, выбор Inspect для процесса передачи дизайна будет неплохим вариантом.&lt;/p&gt;
  &lt;h2 id=&quot;adobexd&quot;&gt;&lt;a href=&quot;https://www.adobe.com/products/xd.html&quot; target=&quot;_blank&quot;&gt;Adobe XD&lt;/a&gt;&lt;/h2&gt;
  &lt;p id=&quot;62A5&quot;&gt;Платформы: macOS, Windows&lt;br /&gt;Стоимость: $0/месяц, $9.99/месяц, $22.99/месяц&lt;/p&gt;
  &lt;figure id=&quot;3nyu&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/98/88/9888c270-79be-47fe-8f6a-9ed26f181705.png&quot; width=&quot;1351&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;CoIh&quot;&gt;До сих пор мы обсуждали инструменты для передачи дизайна (Zeplin), многофункциональные инструменты проектирования пользовательского интерфейса, включающие передачу дизайна (Figma), и дизайнерские комплексы с несколькими полуинтегрированными инструментами, включающими передачу дизайна (InVision). Из всех этих инструментов Adobe XD наиболее похож на Figma, поскольку тоже является многофункциональным инструментом проектирования пользовательского интерфейса.&lt;/p&gt;
  &lt;p id=&quot;tQRJ&quot;&gt;Adobe XD - солидный соперник в этом списке, не имеющий сильных недостатков. На самом деле, если вы уже знакомы с экосистемой Adobe, Adobe XD может быть лучшим выбором, особенно если у вас уже есть подписка на Adobe Creative Cloud (в этом случае у вас может быть доступ к Adobe XD).&lt;/p&gt;
  &lt;p id=&quot;BuNV&quot;&gt;Если нет, то $9,99/месяц - это все равно справедливая цена, поскольку она предлагает те же функции, что и Figma, за меньшие деньги. Однако, поскольку мы говорим о передаче дизайна, стоит отметить, что Adobe XD только переводит стили в CSS. Но он включает в себя обычные функции (переключение форматов, экспорт активов, извлечение контента).&lt;/p&gt;
  &lt;p id=&quot;Azu4&quot;&gt;В целом, если вам требуется только передача дизайна в CSS и/или вы уже знакомы с экосистемой Adobe, Adobe XD - достойный выбор. В этих двух случаях платить больше за подписку на Figma может оказаться излишним.&lt;/p&gt;
  &lt;h2 id=&quot;sketchhttpswwwsketchcom&quot;&gt;&lt;a href=&quot;https://www.sketch.com/&quot; target=&quot;_blank&quot;&gt;Sketch&lt;/a&gt;&lt;/h2&gt;
  &lt;p id=&quot;6ikF&quot;&gt;Платформы: macOS&lt;br /&gt;Цена: $9/месяц, $99/год&lt;/p&gt;
  &lt;figure id=&quot;x8Sr&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/32/74/32744bf9-3d82-4a7c-9977-3829dd704d09.png&quot; width=&quot;1342&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;BYaz&quot;&gt;Наряду с Figma и Adobe XD, Sketch - это еще один многофункциональный инструмент проектирования, который может облегчить большую часть рабочего процесса проектирования пользовательского интерфейса, включая передачу дизайна. Однако, к сожалению, Sketch поддерживает только перевод стилей дизайна в CSS (как Adobe XD).&lt;/p&gt;
  &lt;p id=&quot;LMGw&quot;&gt;Еще одним недостатком Sketch является то, что его основное приложение поддерживает только пользователей Mac, хотя, поскольку передача дизайна осуществляется через URL-адрес, которым можно поделиться, это не должно вызывать беспокойства у разработчиков (но это следует учитывать, если в вашей команде несколько дизайнеров).&lt;/p&gt;
  &lt;p id=&quot;KPEB&quot;&gt;В целом, Sketch не является лучшим, но и не плох. Он остается в пятерке лучших, потому что дизайнерам нравится его UX.&lt;/p&gt;
  &lt;p id=&quot;m6Af&quot;&gt;Еще пять инструментов передачи дизайна&lt;/p&gt;
  &lt;p id=&quot;MU9U&quot;&gt;Несмотря на то, что следующие инструменты передачи дизайна не так широко используются, как вышеупомянутые предложения, их стоит рассмотреть, если те, не подходят вам или вашей команде. Кроме того, несколько из перечисленных ниже инструментов (UXPin и Marvel) принадлежат к более крупной экосистеме инструментов, а рабочие процессы лучше держать в рамках одной экосистемы. (То есть, если вы уже используете UXPin или Marvel, будет хорошей идеей использовать их и для передачи).&lt;/p&gt;
  &lt;ul id=&quot;4A34&quot;&gt;
    &lt;li id=&quot;cQMt&quot;&gt;&lt;a href=&quot;https://abstract.com/&quot; target=&quot;_blank&quot;&gt;Abstract&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;IBpX&quot;&gt;&lt;a href=&quot;https://uxpin.com/studio/handoff/&quot; target=&quot;_blank&quot;&gt;UXPin Handoff&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;NQGQ&quot;&gt;&lt;a href=&quot;https://marvelapp.com/features/handoff/&quot; target=&quot;_blank&quot;&gt;Marvel Handoff&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;URN1&quot;&gt;&lt;a href=&quot;https://avocode.com/&quot; target=&quot;_blank&quot;&gt;Avocode&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;g7ao&quot;&gt;&lt;a href=&quot;https://sympli.io/&quot; target=&quot;_blank&quot;&gt;Sympli&lt;/a&gt;&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h2 id=&quot;oMNy&quot;&gt;Заключение &lt;/h2&gt;
  &lt;p id=&quot;5Z7K&quot;&gt;Судя по инструментам для передачи дизайна в этом списке (ранжированном по количеству пользователей), очевидно, что дизайнеры предпочли бы ограничить рабочий процесс проектирования пользовательского интерфейса одной экосистемой, а еще лучше - одним инструментом. Клиенты тоже не прочь заплатить больше.&lt;/p&gt;
  &lt;p id=&quot;conF&quot;&gt;Лично я с этим согласен. Платить больше за Figma, которая охватывает весь рабочий процесс проектирования пользовательского интерфейса (включая передачу дизайна) не только в рамках одной экосистемы, но и одного инструмента/интерфейса, безусловно, стоит. Тем не менее, я бы смирился с необходимостью синхронизировать дизайн с Zeplin, поскольку он обеспечивает высокий пользовательский опыт.&lt;/p&gt;
  &lt;p id=&quot;JjQw&quot;&gt;Однако и у других инструментов передачи есть свои преимущества. В конечном счете, команды дизайнеров и разработчиков должны искать что-то, что сгладит взаимодействие дизайнера и разработчика, поэтому стоит попробовать два или три варианта, чтобы понять, что лучше всего подходит вам и другим заинтересованным сторонам, участвующим в передаче данных от дизайнера к разработчику.&lt;/p&gt;
  &lt;p id=&quot;pvTL&quot;&gt;Источник: https://www.sitepoint.com/best-design-handoff-tools/&lt;/p&gt;

</content></entry><entry><id>budnifronta:IpfWHHH-PCK</id><link rel="alternate" type="text/html" href="https://teletype.in/@budnifronta/IpfWHHH-PCK?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=budnifronta"></link><title>13 фильмов для программистов, которые стоит посмотреть</title><published>2022-01-08T20:16:49.563Z</published><updated>2022-01-14T19:37:29.837Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img1.teletype.in/files/c1/6c/c16c2f7b-e530-4778-b37c-bf6c1a8ee87c.jpeg"></media:thumbnail><summary type="html">&lt;img src=&quot;https://img4.teletype.in/files/ff/ee/ffeeb7d8-7b77-4d5f-ac41-eb2dda7e3b31.jpeg&quot;&gt;Кроме &quot;Матрицы&quot;, &quot;Девушки с татуировкой дракона&quot; и &quot;Игры в имитацию&quot;, существует множество замечательных фильмов о программистах.</summary><content type="html">
  &lt;figure id=&quot;RTOi&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/ff/ee/ffeeb7d8-7b77-4d5f-ac41-eb2dda7e3b31.jpeg&quot; width=&quot;1280&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;g9jI&quot;&gt;Кроме &amp;quot;Матрицы&amp;quot;, &amp;quot;Девушки с татуировкой дракона&amp;quot; и &amp;quot;Игры в имитацию&amp;quot;, существует множество замечательных фильмов о программистах.&lt;/p&gt;
  &lt;p id=&quot;IjVb&quot;&gt;В этой статье Вы найдёте множество фильмов о программистах, о которых, возможно, не слышали. &lt;/p&gt;
  &lt;h2 id=&quot;mwDa&quot;&gt;1) Социальная сеть (2010)&lt;/h2&gt;
  &lt;p id=&quot;8l1Q&quot;&gt;Несмотря на то, что в фильме &amp;quot;Социальная сеть&amp;quot; один из самых известных миллиардеров Марк Цукерберг изображен не в самом хорошем образе, он по-прежнему является одним из самых вдохновляющих фильмов для программистов. Фильм рассказывает об основателе Facebook, который создает сайт, проводя большую часть своих дней за программированием.&lt;/p&gt;
  &lt;p id=&quot;aJ4B&quot;&gt;Фильм рассказывает о том, как Facebook прошел путь от крошечной идеи близнецов Уинклвосс до 500 миллионов пользователей. И, поскольку сейчас у сайта социальной сети почти три миллиарда пользователей, поклонники все еще ждут &amp;quot;Социальную сеть 2&amp;quot;.&lt;/p&gt;
  &lt;h2 id=&quot;Zcr8&quot;&gt;2) Девушка с татуировкой дракона (2011)&lt;/h2&gt;
  &lt;p id=&quot;Frc6&quot;&gt;Как и &amp;quot;Социальная сеть&amp;quot;, &amp;quot;Девушка с татуировкой дракона&amp;quot; снята Дэвидом Финчером. Но у них есть еще одно сходство, поскольку оба главных героя - программисты.&lt;/p&gt;
  &lt;p id=&quot;rsQT&quot;&gt;Более конкретно, Лисбет Саландер - компьютерный хакер, который помогает Микаэлю раскрыть убийство. &lt;/p&gt;
  &lt;h2 id=&quot;uCtX&quot;&gt;3) Стив Джобс (2015)&lt;/h2&gt;
  &lt;p id=&quot;1jjK&quot;&gt;Стив Джобс - первый из двух фильмов о программистах, написанных Аароном Соркиным, который также является автором &amp;quot;Социальной сети&amp;quot;. Но то, как Соркин пишет о двух самых знаменитых программистах, уникально, поскольку его больше интересуют в этих людях несовершенства, чем их инновационные изобретения.&lt;/p&gt;
  &lt;p id=&quot;kdx9&quot;&gt;Фильмы &amp;quot;Стив Джобс&amp;quot; и &amp;quot;Джобс&amp;quot; вышли в прокат одновременно, причем последний был еще одним кинобиографией об основателе компании Apple. Фильм 2015 года состоит из трех частей, каждая из которых посвящена запуску разных продуктов.&lt;/p&gt;
  &lt;h2 id=&quot;fHwV&quot;&gt;4) Матрица (1999)&lt;/h2&gt;
  &lt;p id=&quot;J4D4&quot;&gt;Фильм &amp;quot;Матрица&amp;quot; - прекрасный пример киберпанка. До того, как стать Нео, мистер Андерсон был простым компьютерным программистом по имени Томас, но то, что последовало за этим, является новаторской высокой концепцией о смоделированной реальности, которая полна взрывного действия.&lt;/p&gt;
  &lt;p id=&quot;AWxc&quot;&gt;Четвертый фильм серии, &amp;quot;Воскрешение Матрицы&amp;quot;, вышел на экраны в 2021 году. В трейлере Нео не помнит, что такое Матрица, так что он вполне может снова стать программистом.&lt;/p&gt;
  &lt;h2 id=&quot;BqvN&quot;&gt;5) Игра в имитацию (2014)&lt;/h2&gt;
  &lt;p id=&quot;2G7g&quot;&gt;Если бы не Алан Тьюринг, вполне возможно что развитие компьютеров пошло бы немного по-другому. Некоторые считают, что фильм &amp;quot;Игра в имитацию&amp;quot; не заслужил номинации на премию &amp;quot;Оскар&amp;quot; за лучшую картину, но экранное изображение роли реально существовавшего ученого во Второй мировой войне не может быть более убедительным.&lt;/p&gt;
  &lt;p id=&quot;3O8C&quot;&gt;В фильме &amp;quot;Игра в имитацию&amp;quot; также показана личная жизнь Тьюринга после событий Второй мировой войны: в 1950-х годах он подвергся химической кастрации за то, что был геем. Хотя он был великим гением и изобретателем, у него был душераздирающий конец, как и у фильма.&lt;/p&gt;
  &lt;h2 id=&quot;Xd7A&quot;&gt;6) Военные игры (1983)&lt;/h2&gt;
  &lt;p id=&quot;T502&quot;&gt;Несмотря на то, что на момент выхода фильм не получил наибольшего признания критиков, &amp;quot;Военные игры&amp;quot; опередил свое время. Фильм рассказывает о молодом хакере, который получает доступ к суперкомпьютеру, принадлежащему военным Соединенных Штатов.&lt;/p&gt;
  &lt;p id=&quot;syAc&quot;&gt;В последнее время хакеры стали серьезной угрозой, ведь они могут получить доступ к большому количеству личной информации. А поскольку дети получают компьютеры в подарок все в более раннем возрасте, &amp;quot;Военные игры&amp;quot; и его главный герой Дэвид (Мэтью Бродерик) предсказали будущее. &lt;/p&gt;
  &lt;h2 id=&quot;kMIm&quot;&gt;7) Трон (1982)&lt;/h2&gt;
  &lt;p id=&quot;QLnl&quot;&gt;&amp;quot;Трон&amp;quot; - это увлекательный фильм для программистов, который стоит посмотреть по многим причинам. Прежде всего, фильм рассказывает о Кевине Флинне, программисте и разработчике видеоигр, который в итоге переносится в программное обеспечение, которое он разрабатывал.&lt;/p&gt;
  &lt;p id=&quot;rwHn&quot;&gt;В основе программы лежит целый мир, полный захватывающих эффектов и действия. И прежде всего, &amp;quot;Трон&amp;quot; - один из самых первых фильмов в истории, в котором было использовано масштабное CGI, проложившее путь практически ко всем голливудским фильмам, выходящим сегодня.&lt;/p&gt;
  &lt;h2 id=&quot;nFvU&quot;&gt;8) Рыба-меч (2001)&lt;/h2&gt;
  &lt;p id=&quot;eVAF&quot;&gt;&amp;quot;Рыба-меч&amp;quot; - это, по сути, смесь &amp;quot;Матрицы&amp;quot; и &amp;quot;Одиннадцати друзей Оушена&amp;quot;. &lt;/p&gt;
  &lt;p id=&quot;YzAA&quot;&gt;Как и &amp;quot;Одиннадцати друзей Оушена&amp;quot;,  в фильме рассказывается о команде грабителей банков, но для того, чтобы украсть 9,5 миллиардов долларов, им нужен лучший компьютерный программист. &amp;quot;Рыба-меч&amp;quot; - это интересный и уникальный взгляд на фильм о грабежах, а эстетику конца 90-х годов приятно пересматривать.&lt;/p&gt;
  &lt;h2 id=&quot;5uVx&quot;&gt;9) Кадры (2013) &lt;/h2&gt;
  &lt;p id=&quot;Cw2n&quot;&gt;Фильмы о программистах, как правило, слишком серьезны, но &amp;quot;Кадры&amp;quot; - это комедия о двух идиотах, которые каким-то образом устраиваются на стажировку в Google. Это один из немногих фильмов с хорошим использованием product placement, поскольку весь фильм рассказывает о том, как прекрасен Google.&lt;/p&gt;
  &lt;p id=&quot;fCyV&quot;&gt;Хотя есть комедии гораздо лучшего качества, &amp;quot;Кадры&amp;quot; понравится любому программисту-энтузиасту только за то, как он демонстрирует кампусы Google. Между велосипедами Google и капсулами для сна, фильм представляет собой рекламу, которая хорошо работает.&lt;/p&gt;
  &lt;h2 id=&quot;m3Cv&quot;&gt;10) Пятая власть (2013)&lt;/h2&gt;
  &lt;p id=&quot;OYgn&quot;&gt;Фильм &amp;quot;Пятая власть&amp;quot; рассказывает о Джулиане Ассанже (Бенедикт Камбербэтч), реально существующем активисте и программисте, создавшем WikiLeaks. Когда он создает платформу, где любой анонимный пользователь может сливать правительственные секреты, а его жизнь превращается в триллер.&lt;/p&gt;
  &lt;p id=&quot;fwXw&quot;&gt;Возможно, это также является одной из причин того, что фильм не получил такого признания, как другие в этом списке, поскольку он больше полагается на мелодраму и меньше на достоверные факты. Камбербэтч явно любит играть программистов, ведь он не только играет главную роль в фильме &amp;quot;Пятая власть&amp;quot;, но и Алана Тьюринга в &amp;quot;Игре в имитацию&amp;quot;.&lt;/p&gt;
  &lt;h2 id=&quot;CVoY&quot;&gt;11) Пираты Кремниевой долины (1999)&lt;/h2&gt;
  &lt;p id=&quot;sr0A&quot;&gt;Во-первых, это фильм не о корпорациях «Apple» и «Microsoft». Фильм о людях, которые смогли «перевернуть мир». Фильм рассказывает о том, как 5 человек смогли не просто стать богатыми и знаменитыми, а затмить таких гигантов как «IBM». Конечно, все внимание фокусируется на 2-х личностях: Билле и Стиве. Это не просто программисты и разработчики, очкарики и ботаники. &lt;/p&gt;
  &lt;p id=&quot;0TJY&quot;&gt;В фильме отлична, передана суть, почему на данный момент монополистом является Microsoft, а не Apple. Билл, во-первых, бизнесмен. Он знал как себя вести, когда открывать рот, а когда молчать. Когда ждать, а когда делать шаг. И полная его противоположность — Стив. Импульсивный, горячий, эмоциональный. Он не боится своих идей и не боится воплощать их в жизнь. &lt;/p&gt;
  &lt;p id=&quot;EjCe&quot;&gt;Последний диалог между Биллом и Стивом актуален до сих пор. Apple делает действительно продукты, на порядок «выше», чем Microsoft, но это действительно уже не важно.&lt;/p&gt;
  &lt;h1 id=&quot;7LOO&quot;&gt;12) Джобс: Империя соблазна (2013)&lt;/h1&gt;
  &lt;p id=&quot;P6R0&quot;&gt;Стив Джобс... Что вам приходит на ум, когда вы слышите это имя? CEO Apple и Pixar, создатель одного из первых персональных компьютеров, новатор, требовательный и авторитарный перфекционист. Человек, бросивший колледж и ставший миллиардером. Таким мы знаем Джобса по биографиям и презентациям, но каким же он был на самом деле? Каким его знали друзья и коллеги? Именно на эти вопросы и попытались ответить создатели фильма &amp;#x27;Джобс: Империя соблазна&amp;#x27;.&lt;/p&gt;
  &lt;h2 id=&quot;Ql2X&quot;&gt;13) Социальная дилемма (2020) &lt;/h2&gt;
  &lt;p id=&quot;eOk2&quot;&gt;Данная картина показывает достаточно много серьезных проблем, связанных не только с социальными сетями, но и с IT гигантами в целом. Если рассуждать о пользе и вреде социальных сетей, то польза перевешивает. Благодаря социальным сетям у нас появилось множество профессий, возможность гибко лавировать в прослойках общества, контактировать с людьми на расстоянии и множество других благ. Они перманентно и крепко впились в нашу жизнь и будет сложно что-либо с этим поделать.&lt;/p&gt;

</content></entry><entry><id>budnifronta:1uLq-iIbs56</id><link rel="alternate" type="text/html" href="https://teletype.in/@budnifronta/1uLq-iIbs56?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=budnifronta"></link><title>Фронтенд-разработчик - что учить в 2022 году?</title><published>2022-01-06T21:43:06.072Z</published><updated>2022-01-08T07:38:51.676Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img4.teletype.in/files/bf/6b/bf6bc83a-0bea-497b-b253-5d22856ec1b6.jpeg"></media:thumbnail><summary type="html">&lt;img src=&quot;https://img3.teletype.in/files/63/f9/63f9e07d-9704-49ab-9ec8-dcec41886cc6.jpeg&quot;&gt;Технологии для фронтенд-разработчика: от начинающего до продвинутого уровня, которые необходимо изучить, чтобы стать одним из лучших фронтенд-разработчиков.</summary><content type="html">
  &lt;figure id=&quot;fu9S&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/63/f9/63f9e07d-9704-49ab-9ec8-dcec41886cc6.jpeg&quot; width=&quot;1280&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;CoEU&quot;&gt;Технологии для фронтенд-разработчика: от начинающего до продвинутого уровня, которые необходимо изучить, чтобы стать одним из лучших фронтенд-разработчиков.&lt;/p&gt;
  &lt;h2 id=&quot;OX9u&quot;&gt;1. Что такое фронтенд-разработка?&lt;/h2&gt;
  &lt;p id=&quot;ly0q&quot;&gt;Фронтенд веб-разработка, также известная как разработка на стороне клиента - это практика создания HTML, CSS и JavaScript для веб-сайта или веб-приложения таким образом, чтобы пользователь мог видеть их и взаимодействовать с ними напрямую. Проблема, связанная с разработкой внешнего интерфейса, заключается в том, что инструменты используемые для создания внешнего интерфейса, постоянно меняются. Следовательно, разработчику необходимо быть в курсе того, как постоянно развивается эта область.&lt;/p&gt;
  &lt;p id=&quot;2fGn&quot;&gt;Цель разработки сайта заключается в том, чтобы при открытии сайта пользователи видели информацию в удобном для чтения и актуальном формате. Это еще более усложняется тем, что пользователи сегодня используют большое количество устройств с различными размерами и разрешением экрана, что заставляет разработчика учитывать эти аспекты при создании сайта. Они должны обеспечить корректное отображение сайта в различных браузерах (кросс-браузерность), различных операционных системах (кросс-платформенность) и различных устройствах (кросс-девайсность), что требует тщательного планирования со стороны разработчика.&lt;/p&gt;
  &lt;h2 id=&quot;IyeM&quot;&gt;2. Сфера деятельности Frontend разработчика&lt;/h2&gt;
  &lt;p id=&quot;kgj5&quot;&gt;Frontend разработка - это проектирование, анализ и отладка кода приложений. Другими словами, frontend-разработка отвечает за управление дизайном, внешним видом и функциональностью веб-сайта. &lt;/p&gt;
  &lt;p id=&quot;45o8&quot;&gt;В целом, будущее выглядит светлым для тех, кто хочет стать frontend разработчиком. Недавние исследования предсказывали, что к 2021 году только в США будет не хватать около 1 миллиона разработчиков. По данным аналогичных исследований, в остальном мире ситуация будет еще хуже.&lt;/p&gt;
  &lt;p id=&quot;C1nE&quot;&gt;По данным Бюро трудовой статистики США, с 2016 по 2026 год занятость веб-разработчиков в США вырастет на 15%. Этот показатель намного выше, чем в среднем по всем другим профессиям.&lt;/p&gt;
  &lt;h2 id=&quot;YmCg&quot;&gt;3. С чего начать?&lt;/h2&gt;
  &lt;p id=&quot;I2KJ&quot;&gt;Чтобы стать успешным Frontend разработчиком. Вам необходимо обладать некоторыми важными навыками.&lt;/p&gt;
  &lt;p id=&quot;J91P&quot;&gt;Frontend-разработчику необходим хорошо укомплектованный личный набор инструментов. Поэтому навыки frontend разработчика включают в себя необходимость:&lt;/p&gt;
  &lt;ul id=&quot;QRxt&quot;&gt;
    &lt;li id=&quot;5ChL&quot;&gt;Знать HTML, CSS, JavaScript.&lt;/li&gt;
    &lt;li id=&quot;INj7&quot;&gt;Владеть опытом работы с веб-фреймворками (React.js, Angular.js, Vue.js).&lt;/li&gt;
    &lt;li id=&quot;Jc7v&quot;&gt;Иметь опыт работы с приложениями для графического дизайна (Adobe Illustrator или Photoshop, Figma).&lt;/li&gt;
    &lt;li id=&quot;BedE&quot;&gt;Понимание принципов SEO&lt;/li&gt;
    &lt;li id=&quot;l87f&quot;&gt;Обладать навыками &amp;quot;решения проблем&amp;quot;&lt;/li&gt;
    &lt;li id=&quot;tr0C&quot;&gt;Уметь общаться с членами команды, руководителями и клиентами&lt;/li&gt;
    &lt;li id=&quot;WdZZ&quot;&gt;Обладать навыками межличностного общения&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h2 id=&quot;aW1Y&quot;&gt;4. Чему нужно научиться?&lt;/h2&gt;
  &lt;p id=&quot;uXkJ&quot;&gt;Необходимые навыки варьируются в зависимости от должности и проекта, над которым предстоит работать. Некоторым компаниям нужны только основы, но с солидным опытом; другие ищут настоящих профессионалов, разработчиков, которые также неплохо разбираются и в UI и UX дизайне.&lt;/p&gt;
  &lt;h3 id=&quot;nz7p&quot;&gt;4.1 Технологии для изучения:&lt;/h3&gt;
  &lt;h3 id=&quot;EU9Y&quot;&gt;&lt;strong&gt;4.1.1. HTML5 и CSS&lt;/strong&gt;&lt;/h3&gt;
  &lt;p id=&quot;PPVb&quot;&gt;Язык разметки гипертекста (HTML) и каскадные таблицы стилей (CSS) - это гайки и болты веб-сайта. В то время как HTML придает веб-страницам структуру, CSS помогает стилизовать элементы HTML с помощью цвета, шрифтов, шрифта и многого другого.&lt;/p&gt;
  &lt;p id=&quot;RlHl&quot;&gt;Освоение HTML и CSS является ОБЯЗАТЕЛЬНЫМ. Честно говоря, не иметь их под рукой - неприемлемо для фронтенд разработчика. HTML, ключевой структурный компонент любого веб-сайта, вместе с CSS, уже позволяет создавать некоторые базовые веб-сайты и приложения. Однако, чтобы сделать его интерактивным, вам нужен JavaScript! Но без знания HTML и CSS его невозможно внедрить в сайт или приложение.&lt;/p&gt;
  &lt;h3 id=&quot;n0xs&quot;&gt;&lt;strong&gt;4.1.2. JavaScript&lt;/strong&gt;&lt;/h3&gt;
  &lt;p id=&quot;Aa6V&quot;&gt;Этот язык программирования на стороне клиента позволяет добавлять на сайт интерактивные функции, включая опросы, слайд-шоу и формы. Он также поддерживает динамические элементы, включая анимацию страницы, прокрутку, аудио и видео.&lt;/p&gt;
  &lt;h3 id=&quot;Up0U&quot;&gt;&lt;strong&gt;4.2. Фреймворки &lt;/strong&gt;&lt;/h3&gt;
  &lt;p id=&quot;vLDk&quot;&gt;Фреймворки - это заранее написанные модули кода для таких распространенных элементов сайта, как интерфейсы входа в систему и поиска. Их легко внедрять и использовать многократно.&lt;/p&gt;
  &lt;h3 id=&quot;ukcf&quot;&gt;&lt;strong&gt;4.2.1. Фреймворки JavaScript &lt;/strong&gt;&lt;/h3&gt;
  &lt;p id=&quot;YDKY&quot;&gt;В зависимости от команды, с которой вы собираетесь работать, или от проекта, скорее всего, будет задан фреймворк, с которым вы должны быть знакомы. Знание самого языка - это одно, но умение работать в рамках фреймворка - это дополнительный навык, без которого мало что получится, особенно если вы хотите создать какой-то реальный проект для клиента. Наиболее популярными являются Angular, React и Vue.js - знакомство с одним из них будет большим плюсом.&lt;/p&gt;
  &lt;h3 id=&quot;lrlO&quot;&gt;&lt;strong&gt;React.js&lt;/strong&gt; &lt;/h3&gt;
  &lt;p id=&quot;oLQK&quot;&gt;React - это фронтенд библиотека JavaScript с открытым исходным кодом, используемая для создания интерактивных пользовательских интерфейсов (UI), что помогает повысить скорость работы приложений. Это один из самых простых для изучения фреймворков, который был разработан Facebook для решения проблем с поддержкой кода из-за постоянных дополнений и улучшений. Он до сих пор поддерживается Facebook и другими отдельными frontend разработчиками.&lt;/p&gt;
  &lt;h3 id=&quot;9chy&quot;&gt;&lt;strong&gt;Angular.js&lt;/strong&gt;&lt;/h3&gt;
  &lt;p id=&quot;ntGu&quot;&gt;Angular - это современный фреймворк с открытым исходным кодом на основе TypeScript и один из самых рейтинговых инструментов разработки программного обеспечения. Особенности Angular Directives позволяют разработчикам программировать специальное поведение DOM, что делает возможным создание полного и динамического HTML-контента. Angular имеет функцию иерархической вставки зависимостей, которая делает компоненты кода удобными для тестирования, многократного использования и более легкого управления: она помогает определить зависимости кода как внешние элементы, отделяя компоненты от их зависимостей.&lt;/p&gt;
  &lt;h3 id=&quot;52ky&quot;&gt;&lt;strong&gt;Vue.js&lt;/strong&gt; &lt;/h3&gt;
  &lt;p id=&quot;Ah8F&quot;&gt;Vue - один из самых дружелюбных к новичкам фреймворков, с хорошо проработанной документацией и поддерживающим сообществом. Vue имеет широкий выбор инструментов, таких как инструменты end-to-end тестирования, системы установки плагинов, инструменты отладки в браузере, серверный рендерер, менеджер состояний и другие.&lt;/p&gt;
  &lt;h3 id=&quot;0D35&quot;&gt;&lt;strong&gt;4.2.2 CSS фреймворки&lt;/strong&gt;&lt;/h3&gt;
  &lt;p id=&quot;wJil&quot;&gt;Фреймворки CSS это оптимизация рабочего процесса. Разработчику лучше знать их, потому что он сможет получить те же результаты за меньшее время и с меньшим количеством набора текста. Еще одним важным аспектом является отзывчивый дизайн - сайты и приложения, которые отлично работают на любом устройстве и размере. Знание того, как преобразовать сайт из статичного в гибкий, необходимо, но еще лучше сэкономить время, используя фреймворки, в которых это уже встроено.&lt;/p&gt;
  &lt;h3 id=&quot;6rbp&quot;&gt;4.2.2.1. Bootstrap&lt;/h3&gt;
  &lt;p id=&quot;08Iu&quot;&gt;Bootstrap - это бесплатный CSS-фреймворк с открытым исходным кодом, направленный на адаптивную, мобильно-ориентированную веб-разработку. Bootstrap считается одним из лучших CSS-фреймворков благодаря своему гибкому дизайну. Он содержит основанные на CSS и JavaScript шаблоны дизайна для типографики, форм, кнопок, навигации и других компонентов интерфейса. Они имеют обширную документацию, примеры и демо-версии, которые помогут вам быстро начать разработку адаптивного веб-сайта.&lt;/p&gt;
  &lt;h3 id=&quot;JjKV&quot;&gt;4.2.2.2. Tailwind CSS&lt;/h3&gt;
  &lt;p id=&quot;VUrR&quot;&gt;Tailwind - это CSS-фреймворк для быстрого создания интерфейсов пользователя. Он включает в себя классы, позволяющие создавать UI пользовательского интерфейса прямо в пользовательской разметке. В отличие от Bootstrap, где вы получаете заранее разработанные компоненты, которые можно использовать в качестве основы для дальнейшей разработки, Tailwind не имеет готового шаблона, но позволяет быстро внедрить свой стиль.&lt;/p&gt;
  &lt;h3 id=&quot;NDCM&quot;&gt;4.2.2.3. Bulma&lt;/h3&gt;
  &lt;p id=&quot;VUFz&quot;&gt;Bulma - это современный CSS-фреймворк, основанный на flexbox. Он предоставляет гибкий дизайн и компоненты пользовательского интерфейса, ориентированные на мобильные устройства, и имеет модульную структуру, позволяющую внедрять только то, что вы хотите включить в свой веб-дизайн. Bulma предлагает современную систему сетки на основе flexbox. &lt;/p&gt;
  &lt;h3 id=&quot;LWkh&quot;&gt;4.3 Инструменты&lt;/h3&gt;
  &lt;h3 id=&quot;s6QO&quot;&gt;4.3.1 Веб-браузер &lt;/h3&gt;
  &lt;p id=&quot;WBLi&quot;&gt;Веб-браузер - это ПО, как мы знаем, используемое для получения, отображения и просмотра информации в сети. Как правило, браузеры работают на компьютере, планшете или телефоне, но в последнее время браузер можно найти практически на чем угодно (например, на холодильнике, в автомобиле и т.д.).&lt;/p&gt;
  &lt;p id=&quot;iQOj&quot;&gt;Наиболее распространенными веб-браузерами являются следующие:&lt;/p&gt;
  &lt;ul id=&quot;OojW&quot;&gt;
    &lt;li id=&quot;3v4d&quot;&gt;Chrome&lt;/li&gt;
    &lt;li id=&quot;5Gdt&quot;&gt;Safari&lt;/li&gt;
    &lt;li id=&quot;oXpE&quot;&gt;Internet Explorer (Примечание: не Edge, а IE 9 - IE 11)&lt;/li&gt;
    &lt;li id=&quot;Z9xl&quot;&gt;Firefox&lt;/li&gt;
    &lt;li id=&quot;7lgx&quot;&gt;Edge&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;FCl4&quot;&gt;С помощью инструментов разработчика (которые вы открываете в браузере) вы можете экспериментировать с каждым элементом сайта. Почему это важно? Потому что, не меняя ничего в коде, вы можете проверить, как эти изменения повлияют на сайт или приложение, пока оно открыто в браузере. Это также помогает при поиске ошибок и недостатков. &lt;/p&gt;
  &lt;h3 id=&quot;tVqA&quot;&gt;4.3.2 Инструменты проектирования&lt;/h3&gt;
  &lt;p id=&quot;96YX&quot;&gt;Возможность иметь базовое представление о работе с изображениями, создавать графические компоненты, ретушировать изображения, разрабатывать пользовательские интерфейсы или просто настраивать определенную информацию с помощью графики, иллюстраций и/или изображений для вашего сайта - это огромный плюс. Это ускоряет вашу производительность и повышает вашу ценность, независимо от того, работаете ли вы профессионально в компании или стартапе, активно фрилансите.&lt;/p&gt;
  &lt;p id=&quot;7cxa&quot;&gt;Ниже приведены некоторые полезные инструменты для дизайна:&lt;/p&gt;
  &lt;ul id=&quot;XhO3&quot;&gt;
    &lt;li id=&quot;VqmD&quot;&gt;Adobe Photoshop&lt;/li&gt;
    &lt;li id=&quot;Diwf&quot;&gt;Adobe Illustrator&lt;/li&gt;
    &lt;li id=&quot;BsRU&quot;&gt;Adobe XD&lt;/li&gt;
    &lt;li id=&quot;se4z&quot;&gt;Adobe InDesign&lt;/li&gt;
    &lt;li id=&quot;C1jB&quot;&gt;Figma &lt;/li&gt;
  &lt;/ul&gt;
  &lt;h3 id=&quot;dT9l&quot;&gt;4.4 Оптимизация производительности веб-сайта (WPO)&lt;/h3&gt;
  &lt;p id=&quot;GSBA&quot;&gt;Медленно загружающийся сайт может резко снизить вовлеченность пользователей. Методы оптимизации производительности сайта помогают обеспечить более быстрое время загрузки с помощью средств автоматизации.&lt;/p&gt;
  &lt;p id=&quot;ua70&quot;&gt;Например, можно оптимизировать изображения и сделать компоненты страницы более легкими в зависимости от устройства без ущерба для функциональности сайта, этим обычно занимаются сборщики сайтов, такие как webpack, vite, parcell и другие, которые тоже необходимо знать разработчику.&lt;/p&gt;
  &lt;h3 id=&quot;msA1&quot;&gt;4.5 Поисковая оптимизация (SEO) &lt;/h3&gt;
  &lt;p id=&quot;T3Ns&quot;&gt;Поисковая оптимизация - это практика увеличения посещаемости сайта посредством результатов поиска.&lt;/p&gt;
  &lt;p id=&quot;87u4&quot;&gt;Как правило, для надзора за практикой SEO существует отдельная команда. Однако знание основ может помочь вам определить, где разместить заголовки, метаописания и текст на сайте, чтобы поисковые системы могли легко их найти.&lt;/p&gt;
  &lt;h3 id=&quot;evjz&quot;&gt;4.6. Контроль версий с помощью Git: &lt;/h3&gt;
  &lt;p id=&quot;hOtY&quot;&gt;В программной инженерии контроль версий - это класс систем, отвечающих за управление изменениями в компьютерных программах, документах, больших веб-сайтах или других коллекциях информации. Контроль версий является компонентом управления настройками ПО. &lt;/p&gt;
  &lt;h3 id=&quot;M45b&quot;&gt;4.6.1. Git&lt;/h3&gt;
  &lt;p id=&quot;pPiy&quot;&gt;Git это система контроля версий. Она активно поддерживается и имеет открытый исходный код, созданный тем же основателем операционной системы Linux. Каждый разработчик, имеющий рабочую копию кода, может легко получить доступ к полной истории изменений, что упрощает редактирование и восстановление кода. &lt;/p&gt;
  &lt;h2 id=&quot;pDbl&quot;&gt;5. Софт скилы&lt;/h2&gt;
  &lt;h3 id=&quot;JQZN&quot;&gt;5.1. Решение проблем&lt;/h3&gt;
  &lt;p id=&quot;GsbA&quot;&gt;Работа над проектом и каждой мелкой задачей - это ежедневная забота frontend разработчика, но проблемы решаются шаг за шагом, вместе с командой. Однако если что-то не работает на сайте, фронтенд-разработчик должен это исправить! Решать проблемы и делать так, чтобы все работало, должно быть мышлением каждого профессионального разработчика. &lt;/p&gt;
  &lt;h3 id=&quot;2jtl&quot;&gt;5.2. Командная работа&lt;/h3&gt;
  &lt;p id=&quot;4gU2&quot;&gt;Как было сказано выше, хорошая коммуникация является ключевым фактором! Работа в команде обычно является частью повседневной жизни frontend разработчика. Даже если вы работаете как фрилансер, вам придется хорошо общаться с клиентами и в какой-то степени работать с ними над проектом. Умение работать в команде, поддерживать других разработчиков и спрашивать совета, когда это необходимо, делает рабочий процесс более гладким, и в итоге вы быстрее получаете конечный продукт. &lt;/p&gt;
  &lt;h3 id=&quot;VF5z&quot;&gt;5.3. Хорошая коммуникация&lt;/h3&gt;
  &lt;p id=&quot;2wYW&quot;&gt;Разрушая стереотип из ситкома о разработчиках, вы должны уметь хорошо общаться. Прежде всего, работа между дизайнерами UI/UX, front и backend должна проходить гладко, чтобы завершить проект. Конечно, в agile-компаниях, занимающихся разработкой ПО, вы также получаете менеджера проекта, который помогает с потоком информации, и SCRUM-мастера, который помогает с процессом. Тем не менее, без некоторых базовых навыков межличностного общения работать с другими людьми будет не так просто. Эффективная коммуникация необходима, когда вы работаете с другими людьми. Также важно уметь излагать и доносить то, что вы задумали - написание документации, которую другие могут прочитать и понять, высоко ценится.&lt;/p&gt;
  &lt;h2 id=&quot;NCIh&quot;&gt;Заключение&lt;/h2&gt;
  &lt;p id=&quot;qLMr&quot;&gt;Независимо от того, как научиться программировать, наиболее важной частью является постоянное совершенствование. Существуют базовые технические навыки. Некоторые из нас имеют лучшую предрасположенность к их изучению, чем другие, но давайте не будем забывать, что упорная работа и практика обычно приносят свои плоды. Что касается софт скилов, то даже если вы не любите общаться с людьми, общение играет ключевую роль, когда вам нужно работать над проектом клиента, поэтому стоит поработать над некоторыми из них.&lt;/p&gt;
  &lt;p id=&quot;Tvkm&quot;&gt;Напишите в комментариях, какие навыки Вам нужно изучить из нашего списка и какие мы не указали? &lt;/p&gt;
  &lt;p id=&quot;nmOC&quot;&gt;Источник: &lt;a href=&quot;https://www.raftlabs.co/development/frontend-developer-complete-roadmap&quot; target=&quot;_blank&quot;&gt;https://www.raftlabs.co/development/frontend-developer-complete-roadmap&lt;/a&gt;&lt;/p&gt;

</content></entry><entry><id>budnifronta:S9toCiHnJpv</id><link rel="alternate" type="text/html" href="https://teletype.in/@budnifronta/S9toCiHnJpv?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=budnifronta"></link><title>Имитируемые методы массивов: как писать безупречно чистый код JavaScript</title><published>2021-12-25T21:01:29.091Z</published><updated>2021-12-26T17:36:40.041Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img4.teletype.in/files/bf/d9/bfd905c0-8a25-4147-947c-8af260e9ed2d.jpeg"></media:thumbnail><summary type="html">&lt;img src=&quot;https://img1.teletype.in/files/46/f6/46f6ad1d-3de9-4c2d-bda2-8b18b58124ba.jpeg&quot;&gt;В этой статье мы увидим, как методы массивов, которые изменяют исходный массив, усложняют нам жизнь. Но не все так плохо и печально. Мы перепишем код так, чтобы нас эта проблема больше не тревожила.</summary><content type="html">
  &lt;figure id=&quot;G74g&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/46/f6/46f6ad1d-3de9-4c2d-bda2-8b18b58124ba.jpeg&quot; width=&quot;1280&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;YBgd&quot;&gt;В этой статье мы увидим, как методы массивов, которые изменяют исходный массив, усложняют нам жизнь. Но не все так плохо и печально. Мы перепишем код так, чтобы нас эта проблема больше не тревожила.&lt;/p&gt;
  &lt;h2 id=&quot;WyYW&quot;&gt;Мутация массивов в JavaScript&lt;/h2&gt;
  &lt;p id=&quot;u5aO&quot;&gt;Массивы в JavaScript - это просто объекты, что означает, что их можно изменять. Фактически, многие встроенные методы массивов изменяют сам массив. Это может означать, что золотое правило, описанное выше, будет нарушено просто при использовании одного из встроенных методов.&lt;/p&gt;
  &lt;p id=&quot;F2o5&quot;&gt;Вот пример, показывающий, как это потенциально может вызвать некоторые проблемы:&lt;/p&gt;
  &lt;pre id=&quot;aEPX&quot; data-lang=&quot;javascript&quot;&gt;const numbers = [1,2,3];
const countdown = numbers.reverse();&lt;/pre&gt;
  &lt;p id=&quot;A0pf&quot;&gt;Этот код выглядит нормально. У нас есть массив с именем &lt;code&gt;numbers&lt;/code&gt;, и мы хотим, чтобы другой массив с именем &lt;code&gt;countdown&lt;/code&gt; перечислял числа в обратном порядке. И, кажется, это работает. Если проверить значение переменной &lt;code&gt;countdown&lt;/code&gt;, то это то, что мы ожидаем:&lt;/p&gt;
  &lt;pre id=&quot;jJS4&quot; data-lang=&quot;javascript&quot;&gt;countdown
&amp;lt;&amp;lt; [3,2,1]&lt;/pre&gt;
  &lt;p id=&quot;Y4WG&quot;&gt;Неприятным сопутствующим результатом этой операции является то, что метод &lt;code&gt;reverse()&lt;/code&gt; изменил и массив &lt;code&gt;numbers&lt;/code&gt;. Это совсем не то, чего мы хотели:&lt;/p&gt;
  &lt;p id=&quot;f9tr&quot;&gt;Что еще хуже, обе переменные ссылаются на один и тот же массив, поэтому любые изменения, которые мы впоследствии внесем в одну из них, повлияют на другую. Предположим, мы используем метод &lt;code&gt;Array.prototype.push()&lt;/code&gt;, чтобы добавить значение &lt;code&gt;0&lt;/code&gt; в конец массива &lt;code&gt;countdown&lt;/code&gt;. То же самое будет сделано и с массивом &lt;code&gt;numbers&lt;/code&gt; (поскольку они оба ссылаются на один и тот же массив):&lt;/p&gt;
  &lt;pre id=&quot;q6f6&quot; data-lang=&quot;javascript&quot;&gt;countdown.push(0)
&amp;lt;&amp;lt; 4
countdown
&amp;lt;&amp;lt; [3,2,1,0]
numbers
&amp;lt;&amp;lt; [3,2,1,0]&lt;/pre&gt;
  &lt;p id=&quot;S8OT&quot;&gt;Именно этот результат может остаться незамеченным - особенно в большом приложении - и привести к очень трудно отслеживаемым ошибкам.&lt;/p&gt;
  &lt;h2 id=&quot;XH3E&quot;&gt;Методы изменяющегося массива в JavaScript&lt;/h2&gt;
  &lt;p id=&quot;kuq7&quot;&gt;И &lt;code&gt;reverse&lt;/code&gt; - не единственный метод массива, который вызывает подобные мутации. Вот список методов массива, которые изменяют массив, к которому они обращаются:&lt;/p&gt;
  &lt;ul id=&quot;mhlg&quot;&gt;
    &lt;li id=&quot;nSjP&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Array/pop&quot; target=&quot;_blank&quot;&gt;Array.prototype.pop()&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;n67H&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Array/push&quot; target=&quot;_blank&quot;&gt;Array.prototype.push()&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;DLzO&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Array/shift&quot; target=&quot;_blank&quot;&gt;Array.prototype.shift()&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;q4kn&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift&quot; target=&quot;_blank&quot;&gt;Array.prototype.unshift()&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;0r9u&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse&quot; target=&quot;_blank&quot;&gt;Array.prototype.reverse()&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;S005&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Array/sort&quot; target=&quot;_blank&quot;&gt;Array.prototype.sort()&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;JAgm&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Array/splice&quot; target=&quot;_blank&quot;&gt;Array.prototype.splice()&lt;/a&gt;&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;JWU2&quot;&gt;Немного смущает то, что у массивов также есть некоторые методы, которые не изменяют исходный массив, а возвращают новый массив:&lt;/p&gt;
  &lt;ul id=&quot;3YkF&quot;&gt;
    &lt;li id=&quot;9wv7&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Array/slice&quot; target=&quot;_blank&quot;&gt;Array.prototype.slice()&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;tXQO&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Array/concat&quot; target=&quot;_blank&quot;&gt;Array.prototype.concat()&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;D9Ql&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Array/map&quot; target=&quot;_blank&quot;&gt;Array.prototype.map()&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;vFZ3&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Array/filter&quot; target=&quot;_blank&quot;&gt;Array.prototype.filter()&lt;/a&gt;&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;pn7g&quot;&gt;Эти методы возвращают новый массив в зависимости от операции, которую они выполнили. Например, метод &lt;code&gt;map()&lt;/code&gt; можно использовать для удвоения всех чисел в массиве:&lt;/p&gt;
  &lt;pre id=&quot;qfI2&quot; data-lang=&quot;javascript&quot;&gt;const numbers = [1,2,3];
const evens = numbers.map(number =&amp;gt; number * 2);
&amp;lt;&amp;lt; [2,4,6]&lt;/pre&gt;
  &lt;p id=&quot;3Hwd&quot;&gt;Теперь, если мы проверим массив numbers, то увидим, что вызов метода не повлиял на него:&lt;/p&gt;
  &lt;pre id=&quot;jway&quot; data-lang=&quot;javascript&quot;&gt;numbers
&amp;lt;&amp;lt; [1,2,3]&lt;/pre&gt;
  &lt;p id=&quot;8vjo&quot;&gt;Кажется, нет никакой причины, почему одни методы мутируют массив, а другие нет. Может быть трудно запомнить, какие из них что делают.&lt;/p&gt;
  &lt;p id=&quot;Qoy2&quot;&gt;В Ruby есть хорошее решение этой проблемы в том, как он использует нотацию &amp;quot;bang&amp;quot;. Любой метод, вызывающий постоянное изменение вызывающего его объекта, заканчивается символом &lt;code&gt;!&lt;/code&gt;. &lt;code&gt;[1,2,3].reverse!&lt;/code&gt; перевернет массив, а &lt;code&gt;[1,2,3].reverse&lt;/code&gt; вернет новый массив с перевернутыми элементами.&lt;/p&gt;
  &lt;p id=&quot;jNyt&quot;&gt;Имитируемые методы массивов: Давайте исправим этот мутирующий беспорядок!&lt;/p&gt;
  &lt;p id=&quot;p8G1&quot;&gt;Мы выяснили, что мутации могут быть потенциально вредными и что многие методы массивов вызывают их. Давайте посмотрим, как можно избежать их использования.&lt;/p&gt;
  &lt;p id=&quot;YGbS&quot;&gt;Не так уж сложно написать несколько функций, которые возвращают новый объект массива вместо того, чтобы мутировать исходный массив. Эти функции и будут нашими иммутабельными методами массива.&lt;/p&gt;
  &lt;p id=&quot;3CG9&quot;&gt;Поскольку мы не собираемся исправлять &lt;code&gt;Array.prototype&lt;/code&gt;, эти функции всегда будут принимать сам массив в качестве первого параметра.&lt;/p&gt;
  &lt;h2 id=&quot;toc_2&quot;&gt;Pop&lt;/h2&gt;
  &lt;p id=&quot;kyoB&quot;&gt;Давайте начнем с написания новой функции &lt;code&gt;pop&lt;/code&gt;, которая возвращает копию исходного массива, но без последнего элемента. Обратите внимание, что &lt;code&gt;Array.prototype.pop()&lt;/code&gt; возвращает значение, которое было извлечено из конца массива:&lt;/p&gt;
  &lt;pre id=&quot;eXIW&quot; data-lang=&quot;javascript&quot;&gt;const pop = array =&amp;gt; array.slice(0,-1);&lt;/pre&gt;
  &lt;p id=&quot;wndI&quot;&gt;Эта функция использует &lt;code&gt;Array.prototype.slice()&lt;/code&gt; для возврата копии массива, но с удаленным последним элементом. Второй аргумент -1 означает прекращение резки за 1 место до конца. Мы можем увидеть, как это работает, на примере ниже:&lt;/p&gt;
  &lt;pre id=&quot;wWFj&quot; data-lang=&quot;javascript&quot;&gt;const food = [&amp;#x27;🍏&amp;#x27;,&amp;#x27;🍌&amp;#x27;,&amp;#x27;🥕&amp;#x27;,&amp;#x27;🍩&amp;#x27;];
pop(food)
&amp;lt;&amp;lt; [&amp;#x27;🍏&amp;#x27;,&amp;#x27;🍌&amp;#x27;,&amp;#x27;🥕&amp;#x27;]&lt;/pre&gt;
  &lt;h2 id=&quot;toc_3&quot;&gt;Push&lt;/h2&gt;
  &lt;p id=&quot;ZRUi&quot;&gt;Далее создадим функцию &lt;code&gt;push()&lt;/code&gt;, которая будет возвращать новый массив, но с добавленным в конец новым элементом:&lt;/p&gt;
  &lt;pre id=&quot;XsZf&quot; data-lang=&quot;javascript&quot;&gt;const push = (array, value) =&amp;gt; [...array,value];&lt;/pre&gt;
  &lt;p id=&quot;R9Oo&quot;&gt;Здесь используется оператор &lt;code&gt;spread&lt;/code&gt; для создания копии массива. Затем он добавляет значение, указанное в качестве второго аргумента, в конец нового массива. Вот пример:&lt;/p&gt;
  &lt;pre id=&quot;PomC&quot; data-lang=&quot;javascript&quot;&gt;const food = [&amp;#x27;🍏&amp;#x27;,&amp;#x27;🍌&amp;#x27;,&amp;#x27;🥕&amp;#x27;,&amp;#x27;🍩&amp;#x27;];
push(food,&amp;#x27;🍆&amp;#x27;)
&amp;lt;&amp;lt; [&amp;#x27;🍏&amp;#x27;,&amp;#x27;🍌&amp;#x27;,&amp;#x27;🥕&amp;#x27;,&amp;#x27;🍩&amp;#x27;,&amp;#x27;🍆&amp;#x27;]&lt;/pre&gt;
  &lt;h2 id=&quot;toc_4&quot;&gt;Shift и Unshift&lt;/h2&gt;
  &lt;p id=&quot;Jt5l&quot;&gt;Аналогично мы можем написать замены для &lt;code&gt;Array.prototype.shift()&lt;/code&gt; и &lt;code&gt;Array.prototype.unshift()&lt;/code&gt;:&lt;/p&gt;
  &lt;pre id=&quot;u5gz&quot; data-lang=&quot;javascript&quot;&gt;const shift = array =&amp;gt; array.slice(1);&lt;/pre&gt;
  &lt;p id=&quot;CUFG&quot;&gt;Для нашей функции &lt;code&gt;shift()&lt;/code&gt; мы просто отрезаем первый элемент из массива вместо последнего. Это можно увидеть на примере ниже:&lt;/p&gt;
  &lt;pre id=&quot;mV4G&quot; data-lang=&quot;javascript&quot;&gt;const food = [&amp;#x27;🍏&amp;#x27;,&amp;#x27;🍌&amp;#x27;,&amp;#x27;🥕&amp;#x27;,&amp;#x27;🍩&amp;#x27;];
shift(food)
&amp;lt;&amp;lt; [&amp;#x27;🍌&amp;#x27;,&amp;#x27;🥕&amp;#x27;,&amp;#x27;🍩&amp;#x27;]&lt;/pre&gt;
  &lt;p id=&quot;ha3g&quot;&gt;Наш метод unshift() вернет новый массив с новым значением, добавленным в начало массива:&lt;/p&gt;
  &lt;pre id=&quot;FM75&quot; data-lang=&quot;javascript&quot;&gt;const unshift = (array,value) =&amp;gt; [value,...array];&lt;/pre&gt;
  &lt;p id=&quot;91rg&quot;&gt;Оператор spread позволяет нам размещать значения внутри массива в любом порядке. Мы просто помещаем новое значение перед копией исходного массива. Как это работает, можно увидеть на примере ниже:&lt;/p&gt;
  &lt;pre id=&quot;QJWz&quot; data-lang=&quot;javascript&quot;&gt;const food = [&amp;#x27;🍏&amp;#x27;,&amp;#x27;🍌&amp;#x27;,&amp;#x27;🥕&amp;#x27;,&amp;#x27;🍩&amp;#x27;];
unshift(food,&amp;#x27;🍆&amp;#x27;)
&amp;lt;&amp;lt; [&amp;#x27;🍆&amp;#x27;,&amp;#x27;🍏&amp;#x27;,&amp;#x27;🍌&amp;#x27;,&amp;#x27;🥕&amp;#x27;,&amp;#x27;🍩&amp;#x27;]&lt;/pre&gt;
  &lt;h2 id=&quot;toc_5&quot;&gt;Reverse&lt;/h2&gt;
  &lt;p id=&quot;2gNJ&quot;&gt;Теперь давайте попробуем написать замену для метода &lt;code&gt;Array.prototype.reverse()&lt;/code&gt;. Он будет возвращать копию массива в обратном порядке, вместо того чтобы изменять исходный массив:&lt;/p&gt;
  &lt;pre id=&quot;zEke&quot; data-lang=&quot;javascript&quot;&gt;const reverse = array =&amp;gt; [...array].reverse();&lt;/pre&gt;
  &lt;p id=&quot;6EXb&quot;&gt;Этот метод по-прежнему использует метод &lt;code&gt;Array.prototype.reverse()&lt;/code&gt;, но применяется к копии исходного массива, которую мы создаем с помощью оператора spread. Нет ничего плохого в том, чтобы мутировать объект сразу после его создания, что мы здесь и делаем. Мы можем видеть, как это работает в примере ниже:&lt;/p&gt;
  &lt;pre id=&quot;UZho&quot; data-lang=&quot;javascript&quot;&gt;const food = [&amp;#x27;🍏&amp;#x27;,&amp;#x27;🍌&amp;#x27;,&amp;#x27;🥕&amp;#x27;,&amp;#x27;🍩&amp;#x27;];
reverse(food)
&amp;lt;&amp;lt; [&amp;#x27;🍩&amp;#x27;,&amp;#x27;🥕&amp;#x27;,&amp;#x27;🍌&amp;#x27;,&amp;#x27;🍏&amp;#x27;]&lt;/pre&gt;
  &lt;h2 id=&quot;toc_6&quot;&gt;Splice&lt;/h2&gt;
  &lt;p id=&quot;7mcX&quot;&gt;Наконец, давайте разберемся с &lt;code&gt;Array.prototype.splice()&lt;/code&gt;. Это очень универсальная функция, поэтому мы не будем полностью переписывать то, что она делает. Вместо этого мы сосредоточимся на двух основных вариантах использования функции slice: удаление элементов из массива и вставка элементов в массив.&lt;/p&gt;
  &lt;h3 id=&quot;tnVl&quot;&gt;Удаление элемента массива&lt;/h3&gt;
  &lt;p id=&quot;THEQ&quot;&gt;Начнем с функции, которая вернет новый массив, но с удаленным элементом с заданным индексом:&lt;/p&gt;
  &lt;pre id=&quot;OdaH&quot; data-lang=&quot;javascript&quot;&gt;const remove = (array, index) =&amp;gt; [...array.slice(0, index),...array.slice(index + 1)];&lt;/pre&gt;
  &lt;p id=&quot;ay9I&quot;&gt;Для этого используется &lt;code&gt;Array.prototype.slice()&lt;/code&gt;, чтобы разделить массив на две половины - по обе стороны от элемента, который мы хотим удалить. Первый срез возвращает новый массив, копируя элементы исходного массива до индекса перед элементом, указанным в качестве аргумента. Второй фрагмент возвращает массив с элементами после удаляемого элемента, вплоть до конца исходного массива. Затем мы помещаем их оба вместе в новый массив с помощью оператора spread.&lt;/p&gt;
  &lt;p id=&quot;Afga&quot;&gt;Мы можем проверить, что это работает, попытавшись удалить элемент с индексом 2 в приведенном ниже массиве &lt;code&gt;food&lt;/code&gt;:&lt;/p&gt;
  &lt;pre id=&quot;6U86&quot; data-lang=&quot;javascript&quot;&gt;const food = [&amp;#x27;🍏&amp;#x27;,&amp;#x27;🍌&amp;#x27;,&amp;#x27;🥕&amp;#x27;,&amp;#x27;🍩&amp;#x27;];
remove(food,2)
&amp;lt;&amp;lt; [&amp;#x27;🍏&amp;#x27;,&amp;#x27;🍌&amp;#x27;,&amp;#x27;🍩&amp;#x27;]&lt;/pre&gt;
  &lt;h3 id=&quot;EHgI&quot;&gt;Добавление элемента массива&lt;/h3&gt;
  &lt;p id=&quot;T2qy&quot;&gt;Наконец, давайте напишем функцию, которая будет возвращать новый массив с новым значением, вставленным в определенный индекс:&lt;/p&gt;
  &lt;pre id=&quot;kSHV&quot; data-lang=&quot;javascript&quot;&gt;const insert = (array,index,value) =&amp;gt; [...array.slice(0, index), value, ...array.slice(index)];&lt;/pre&gt;
  &lt;p id=&quot;yzed&quot;&gt;Эта функция работает аналогично функции &lt;code&gt;remove()&lt;/code&gt;. Она создает два фрагмента массива, но на этот раз включает элемент с указанным индексом. Когда мы снова соединяем эти два фрагмента вместе, мы вставляем между ними значение, указанное в качестве аргумента.&lt;/p&gt;
  &lt;p id=&quot;O3nG&quot;&gt;Мы можем проверить, как это работает, попробовав вставить эмодзи в виде кекса в середину нашего массива продуктов:&lt;/p&gt;
  &lt;pre id=&quot;Eokx&quot; data-lang=&quot;javascript&quot;&gt;const food = [&amp;#x27;🍏&amp;#x27;,&amp;#x27;🍌&amp;#x27;,&amp;#x27;🥕&amp;#x27;,&amp;#x27;🍩&amp;#x27;]
insert(food,2,&amp;#x27;🧁&amp;#x27;)
&amp;lt;&amp;lt; [&amp;#x27;🍏&amp;#x27;,&amp;#x27;🍌&amp;#x27;,&amp;#x27;🧁&amp;#x27;,&amp;#x27;🥕&amp;#x27;,&amp;#x27;🍩&amp;#x27;]&lt;/pre&gt;
  &lt;p id=&quot;ENIp&quot;&gt;Теперь у нас есть набор методов неизменяемого массива, которые оставляют наши исходные массивы в покое. Я сохранил их все в одном месте на &lt;a href=&quot;https://codepen.io/SitePoint/pen/bGqwaBZ?editors=0010&quot; target=&quot;_blank&quot;&gt;CodePen&lt;/a&gt;, поэтому смело копируйте их и используйте в своих проектах. Вы можете разделить их по пространствам имен, сделав их методами одного объекта, или просто использовать их как есть, когда это необходимо.&lt;/p&gt;
  &lt;p id=&quot;UbN9&quot;&gt;Этих методов достаточно для большинства операций с массивами. Если вам нужно выполнить другую операцию, помните золотое правило: сначала создайте копию исходного массива с помощью оператора &lt;code&gt;spread&lt;/code&gt;. Затем сразу же примените к этой копии все мутирующие методы.&lt;/p&gt;
  &lt;p id=&quot;CBUg&quot;&gt;Источник: https://www.sitepoint.com/immutable-array-methods-javascript/&lt;/p&gt;

</content></entry><entry><id>budnifronta:d9nNe-zDStP</id><link rel="alternate" type="text/html" href="https://teletype.in/@budnifronta/d9nNe-zDStP?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=budnifronta"></link><title>5 способов исправить ошибки с помощью Git</title><published>2021-12-23T16:57:21.454Z</published><updated>2021-12-24T17:07:07.506Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img2.teletype.in/files/1b/a6/1ba6582d-43fd-431a-a78a-ddf87ce5622d.jpeg"></media:thumbnail><summary type="html">&lt;img src=&quot;https://img1.teletype.in/files/8e/85/8e85e091-e0f2-4603-8765-b6e79ecad1e9.jpeg&quot;&gt;Независимо от того, насколько вы опытны, практика разработки невозможна без ошибок. Но что отличает программистов от лучших программистов, так это то, что они умеют исправлять свои ошибки!</summary><content type="html">
  &lt;figure id=&quot;W12n&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/8e/85/8e85e091-e0f2-4603-8765-b6e79ecad1e9.jpeg&quot; width=&quot;1280&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;69W2&quot;&gt;Независимо от того, насколько вы опытны, практика разработки невозможна без ошибок. Но что отличает программистов от лучших программистов, так это то, что они умеют исправлять свои ошибки!&lt;/p&gt;
  &lt;p id=&quot;O3lm&quot;&gt;Если вы используете Git в качестве системы контроля версий, у вас под рукой уже есть множество &amp;quot;инструментов исправления&amp;quot;. В этом посте я расскажу вам о пяти мощных способах устранения ошибок в Git!&lt;/p&gt;
  &lt;h2 id=&quot;VdZS&quot;&gt;Отмена некоторых локальных изменений&lt;/h2&gt;
  &lt;p id=&quot;qVJY&quot;&gt;Программирование - это часто беспорядочный процесс. Временами кажется, что вы делаете два шага вперед и один назад. Другими словами: часть кода, который вы написали, прекрасна... а часть - не очень. Вот где Git может помочь вам: он позволяет сохранить то, что хорошо, и отбросить те изменения, которые вам больше не нужны.&lt;/p&gt;
  &lt;p id=&quot;N7Aj&quot;&gt;Давайте рассмотрим пример сценария с некоторыми &amp;quot;локальными&amp;quot; изменениями (они же изменения, которые мы еще не коммитили).&lt;/p&gt;
  &lt;p id=&quot;f7Us&quot;&gt;У нас есть проблемный файл &lt;code&gt;general.css&lt;/code&gt;. Давайте сначала разберемся с ним. Изменения, которые мы внесли, пошли в совершенно неправильном направлении. Давайте отменим все эти действия и воссоздадим последнее закоммиченное состояние этого файла:&lt;/p&gt;
  &lt;pre id=&quot;Wmk8&quot; data-lang=&quot;git&quot;&gt;$ git restore css/general.css&lt;/pre&gt;
  &lt;p id=&quot;6Hmf&quot;&gt;Обратите внимание, что в качестве альтернативы я мог бы использовать команду &lt;code&gt;git checkout&lt;/code&gt; для достижения того же результата. Но поскольку у &lt;code&gt;git checkout&lt;/code&gt; так много разных задач и значений, я предпочитаю более новую команду &lt;code&gt;git restore&lt;/code&gt; (которая ориентирована исключительно на такие задачи).&lt;/p&gt;
  &lt;p id=&quot;yaOX&quot;&gt;Наша вторая проблема в файле &lt;code&gt;index.html&lt;/code&gt; немного сложнее. Некоторые из изменений, которые мы внесли в этот файл, на самом деле замечательные, и только некоторые из них нужно отменить.&lt;/p&gt;
  &lt;p id=&quot;fa28&quot;&gt;И снова на помощь приходит &lt;code&gt;git restore&lt;/code&gt; - но на этот раз с помощью &lt;code&gt;-p&lt;/code&gt;, потому что мы хотим спуститься на уровень &amp;quot;patch&amp;quot;:&lt;/p&gt;
  &lt;pre id=&quot;RsAY&quot; data-lang=&quot;git&quot;&gt;$ git restore -p index.html&lt;/pre&gt;
  &lt;p id=&quot;Hj3P&quot;&gt;Затем Git для каждого фрагмента изменений в этом файле будет опрос - хотите ли вы отбросить данное изменение или нет.&lt;/p&gt;
  &lt;figure id=&quot;wpAt&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/c6/48/c6489c2c-5b6d-4737-bddd-6b44c7cd1dea.gif&quot; width=&quot;1046&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;McMC&quot;&gt;Вы заметите, что я ввел &amp;quot;n&amp;quot; для первого фрагмента (чтобы сохранить его) и &amp;quot;y&amp;quot; для второго фрагмента (чтобы отбросить его). После завершения процесса видно, что сохранился только первый, необходимый фрагмент изменений - как мы и хотели!&lt;/p&gt;
  &lt;h2 id=&quot;aU4N&quot;&gt;Возврат определенного файла в предыдущее состояние&lt;/h2&gt;
  &lt;p id=&quot;mKDI&quot;&gt;Иногда требуется восстановить определенный файл до определенной версии. Например, вы знаете, что &lt;code&gt;index.html&lt;/code&gt; работал нормально в какой-то более ранний момент времени, но теперь это не так. Тогда вы хотите вернуть время назад, но только для этого конкретного файла, а не для всего проекта!&lt;/p&gt;
  &lt;p id=&quot;drNA&quot;&gt;Прежде всего, необходимо выяснить, какую именно часть проекта мы хотим восстановить. При правильном наборе параметров вы можете заставить команду &lt;code&gt;git log&lt;/code&gt; показать вам историю только нашего единственного файла:&lt;/p&gt;
  &lt;pre id=&quot;iq0F&quot; data-lang=&quot;git&quot;&gt;$ git log -- index.html&lt;/pre&gt;
  &lt;figure id=&quot;wQEJ&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://uploads.sitepoint.com/wp-content/uploads/2021/08/1628079412git-log-filename@2x.png&quot; width=&quot;1614&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;2fHU&quot;&gt;Оно показывает нам только те коммиты, в которых был изменен &lt;code&gt;index.html&lt;/code&gt;, что довольно полезно для поиска ошибки.&lt;/p&gt;
  &lt;p id=&quot;7ImV&quot;&gt;Если вам нужно больше информации и вы хотите посмотреть на содержимое этих коммитов, вы можете попросить Git показать вам фактические изменения в этих коммитах с помощью флага &lt;code&gt;-p&lt;/code&gt;:&lt;/p&gt;
  &lt;pre id=&quot;sXuW&quot;&gt;$ git log -p -- index.html&lt;/pre&gt;
  &lt;p id=&quot;ZtRP&quot;&gt;После того как мы нашли неправильный коммит, в котором мы испортили наш чудесный маленький файл, мы можем исправить ошибку. Мы сделаем это, восстановив файл на версии, предшествующей неверному коммиту! Это важно: мы хотим восстанавливать файл не в том коммите, в котором была допущена ошибка, а в последнем хорошем состоянии - то есть за один коммит до этого!&lt;/p&gt;
  &lt;pre id=&quot;bwJ5&quot;&gt;$ git checkout &amp;lt;bad-commit-hash&amp;gt;~1 -- index.html&lt;/pre&gt;
  &lt;p id=&quot;HXst&quot;&gt;Добавление &lt;code&gt;~1&lt;/code&gt; к хэшу плохого коммита даст указание Git&amp;#x27;у сделать именно это: перейти на одну версию раньше ссылающегося коммита.&lt;/p&gt;
  &lt;p id=&quot;lTYX&quot;&gt;Выполнив эту команду, вы увидите, что &lt;code&gt;index.html&lt;/code&gt; в вашей локальной рабочей версии изменен: Git восстановил для нас последнюю правильную версию файла!&lt;/p&gt;
  &lt;h2 id=&quot;NRDD&quot;&gt;Восстановление потерянной версии с помощью Reflog&lt;/h2&gt;
  &lt;p id=&quot;pUdq&quot;&gt;Еще одним замечательным инструментом исправления в арсенале Git&amp;#x27;а является &amp;quot;Reflog&amp;quot;. Его можно рассматривать как журнал, в котором Git протоколирует все движения указателя HEAD, происходящие в вашем локальном репозитории - такие вещи, как коммиты, чек-ауты, слияния и ребейзы, cherry-pick&amp;#x27;и и сбросы. Все наиболее интересные действия прекрасно отображаются в этом журнале!&lt;/p&gt;
  &lt;p id=&quot;vkRy&quot;&gt;Такой журнал идеально подходит для тех случаев, когда дела идут неважно. Итак, давайте для начала устроим небольшую поломку, которую потом можно будет устранить с помощью &lt;code&gt;Reflog&lt;/code&gt;.&lt;/p&gt;
  &lt;p id=&quot;vRut&quot;&gt;Допустим, вы были уверены, что ваши последние коммиты никуда не годятся: вы хотели от них избавиться и поэтому использовали &lt;code&gt;git reset&lt;/code&gt; для возврата к предыдущей версии. В результате &amp;quot;плохие&amp;quot; коммиты исчезли из вашей истории коммитов - как вы и хотели.&lt;/p&gt;
  &lt;p id=&quot;7guE&quot;&gt;Дальше вы замечаете, что это была плохая идея: на самом деле коммиты были не так уж плохи! Но плохая новость, конечно, в том, что вы только что стёрли их из истории коммитов вашего репозитория! &lt;/p&gt;
  &lt;p id=&quot;Xvc1&quot;&gt;Это классический случай для инструмента Git&amp;#x27;а Reflog! Давайте посмотрим, как он может спасти вас:&lt;/p&gt;
  &lt;pre id=&quot;lDE9&quot; data-lang=&quot;git&quot;&gt;$ git reflog&lt;/pre&gt;
  &lt;ul id=&quot;8OlU&quot;&gt;
    &lt;li id=&quot;i4zk&quot;&gt;Во-первых, Reflog очень легко открыть: для этого достаточно выполнить простой &lt;code&gt;git reflog&lt;/code&gt;.&lt;/li&gt;
    &lt;li id=&quot;ciW8&quot;&gt;Во-вторых, вы заметите, что записанные состояния отсортированы в хронологическом порядке, причем самое новое находится вверху.&lt;/li&gt;
    &lt;li id=&quot;qhWh&quot;&gt;Если вы присмотритесь, то увидите, что самый верхний (то есть самый новый) элемент - это действие &amp;quot;сброс&amp;quot;. Что мы и сделали 20 секунд назад. Очевидно, журнал работает.&lt;/li&gt;
    &lt;li id=&quot;RMfi&quot;&gt;Если теперь мы захотим отменить наш непроизвольный &amp;quot;сброс&amp;quot;, мы можем просто вернуться к прежнему состоянию - что также аккуратно показано здесь! Мы можем просто скопировать хэш коммита этого предыдущего состояния в буфер обмена и продолжить работу оттуда.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;rQUc&quot;&gt;Чтобы восстановить прежнее состояние, мы можем либо снова использовать &lt;code&gt;git reset&lt;/code&gt;, либо просто создать новую ветку:&lt;/p&gt;
  &lt;pre id=&quot;Jn7i&quot; data-lang=&quot;git&quot;&gt;$ git branch happy-ending e5b19e4&lt;/pre&gt;
  &lt;p id=&quot;nhus&quot;&gt;Как мы можем с радостью убедиться, наша новая ветка содержит коммиты, которые, как мы думали, потеряли из-за случайной ошибки при &lt;code&gt;git reset&lt;/code&gt;!&lt;/p&gt;
  &lt;h2 id=&quot;naiN&quot;&gt;Восстановление удаленной ветки&lt;/h2&gt;
  &lt;p id=&quot;lzXZ&quot;&gt;Рефлог может быть полезен и в других ситуациях. Например, когда вы по неосторожности удалили ветку, которую действительно (!) не следовало удалять. Давайте посмотрим на наш пример:&lt;/p&gt;
  &lt;pre id=&quot;kNWA&quot; data-lang=&quot;git&quot;&gt;$ git branch
  * feature/analytics
    master&lt;/pre&gt;
  &lt;p id=&quot;vWOq&quot;&gt;Представим, что наш заказчик проекта говорит нам, что прекрасная функция &lt;code&gt;analytics&lt;/code&gt;, над которой мы работали, больше не нужна. Конечно же, мы удалим соответствующую ветку &lt;code&gt;feature/analytics&lt;/code&gt;!&lt;/p&gt;
  &lt;p id=&quot;TOlE&quot;&gt;&lt;code&gt;feature/analytics&lt;/code&gt; - это наша текущая ветка HEAD. Чтобы иметь возможность удалить ее, мы должны сначала переключиться на другую ветку:&lt;/p&gt;
  &lt;pre id=&quot;bhTO&quot; data-lang=&quot;git&quot;&gt;$ git checkout master
$ git branch -d feature/analytics
error: The branch &amp;#x27;feature/analytics&amp;#x27; is not fully merged.
If you are sure you want to delete it, run &amp;#x27;git branch -D feature/analytics&amp;#x27;.&lt;/pre&gt;
  &lt;p id=&quot;b7jk&quot;&gt;Git говорит нам, что мы собираемся сделать что-то действительно значимое: поскольку &lt;strong&gt;&lt;code&gt;feature/analytics&lt;/code&gt;&lt;/strong&gt; содержит уникальные коммиты, которые больше нигде не присутствуют, удаление этой функции уничтожит некоторые (потенциально ценные) данные. Что ж... поскольку функция больше не нужна, мы можем продолжать:&lt;/p&gt;
  &lt;pre id=&quot;QZQu&quot; data-lang=&quot;git&quot;&gt;$ git branch -D feature/analytics
Deleted branch feature/analytics (was b1c249b).&lt;/pre&gt;
  &lt;p id=&quot;VBM5&quot;&gt;Вы, наверное, уже догадались, что сейчас произойдет: наш заказчик проекта радостно сообщает нам, что функцию нужно вернуть в проект!  Они все-таки хотят ее реализовать! &lt;/p&gt;
  &lt;p id=&quot;wX3X&quot;&gt;И снова мы сталкиваемся с неприятной ситуацией, когда мы могли потерять ценные данные! Так что давайте посмотрим, сможет ли Reflog спасти нас еще раз:&lt;/p&gt;
  &lt;pre id=&quot;nq9a&quot; data-lang=&quot;git&quot;&gt;$ git reflog&lt;/pre&gt;
  &lt;p id=&quot;BpwS&quot;&gt;Прежде чем мы решили удалить нашу ветку, нам пришлось выполнить git checkout, чтобы от нее переключиться (поскольку Git не позволяет удалять текущую ветку). Конечно, эта процедура также была зарегистрирована в Reflog. Чтобы восстановить удалённую ветку, мы можем теперь просто взять предыдущее состояние в качестве отправной точки для новой ветки:&lt;/p&gt;
  &lt;pre id=&quot;jgi5&quot;&gt;$ git branch feature/analytics b1c249b&lt;/pre&gt;
  &lt;p id=&quot;zXGB&quot;&gt;И вуаля: наша ветка восстановилась!&lt;/p&gt;
  &lt;h2 id=&quot;FCD4&quot;&gt;Перенос коммита в другую ветку&lt;/h2&gt;
  &lt;p id=&quot;QTxx&quot;&gt;В заключение приведем еще одну классику из серии &amp;quot;О нет!&amp;quot;: коммит в не той ветке.&lt;/p&gt;
  &lt;p id=&quot;AlJR&quot;&gt;Сегодня во многих командах действует правило, запрещающее коммиты непосредственно в давно работающие ветки, такие как &amp;quot;main&amp;quot;, &amp;quot;master&amp;quot; или &amp;quot;develop&amp;quot;. Как правило, новые коммиты должны попадать в эти ветки только через слияния/ребейзы. И все же мы иногда забываем и делаем коммит напрямую...&lt;/p&gt;
  &lt;p id=&quot;XUwe&quot;&gt;Давайте рассмотрим следующий сценарий в качестве примера.&lt;/p&gt;
  &lt;p id=&quot;Z4dv&quot;&gt;Мы должны были сделать коммит на &lt;code&gt;feature/newsletter&lt;/code&gt;, но по неосторожности нажали на master. Давайте рассмотрим решение проблемы шаг за шагом.&lt;/p&gt;
  &lt;p id=&quot;HJvj&quot;&gt;Во-первых, мы должны убедиться, что на этот раз мы находимся в правильной ветке, поэтому мы проверяем &lt;code&gt;feature/newsletter&lt;/code&gt;:&lt;/p&gt;
  &lt;pre id=&quot;nQ10&quot;&gt;$ git checkout feature/newsletter&lt;/pre&gt;
  &lt;p id=&quot;Pr6Y&quot;&gt;Теперь мы можем безопасно перенести этот коммит с помощью команды &lt;code&gt;cherry-pick&lt;/code&gt;:&lt;/p&gt;
  &lt;pre id=&quot;To4T&quot;&gt;$ git cherry-pick 26bf1b48&lt;/pre&gt;
  &lt;p id=&quot;au4H&quot;&gt;Мы можем взглянуть на &lt;code&gt;feature/newsletter&lt;/code&gt; и увидим, что теперь коммит существует и здесь.&lt;/p&gt;
  &lt;p id=&quot;p6gK&quot;&gt;Пока всё хорошо. Но &lt;code&gt;cherry-pick&lt;/code&gt; не удалил коммит из &lt;code&gt;master&lt;/code&gt; ветки, где его никогда не должно было быть. Поэтому нам придётся навести порядок и там:&lt;/p&gt;
  &lt;pre id=&quot;13JO&quot; data-lang=&quot;git&quot;&gt;$ git checkout master
$ git reset --hard HEAD~1&lt;/pre&gt;
  &lt;p id=&quot;mSZX&quot;&gt;Мы переключаемся обратно на &lt;code&gt;master&lt;/code&gt; и затем используем &lt;code&gt;git reset&lt;/code&gt;, чтобы удалить ненужный коммит из истории. Наконец, все вновь исправлено.&lt;/p&gt;
  &lt;p id=&quot;de7F&quot;&gt;Мы не можем избежать ошибок! Каким бы лучшим программистом мы ни были, время от времени мы будем ошибаться. Поэтому вопрос не в том, совершаем ли мы ошибки, а в том, насколько хорошо мы умеем с ними справляться и устранять проблемы. &lt;/p&gt;
  &lt;p id=&quot;A5W5&quot;&gt;Источник: &lt;a href=&quot;https://www.sitepoint.com/5-ways-to-undo-mistakes-with-git/&quot; target=&quot;_blank&quot;&gt;https://www.sitepoint.com/5-ways-to-undo-mistakes-with-git/&lt;/a&gt;&lt;/p&gt;

</content></entry><entry><id>budnifronta:ZYpNqR9Z1sl</id><link rel="alternate" type="text/html" href="https://teletype.in/@budnifronta/ZYpNqR9Z1sl?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=budnifronta"></link><title>Введение в PostCSS</title><published>2021-12-14T05:19:48.841Z</published><updated>2021-12-16T17:30:55.425Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img1.teletype.in/files/82/b0/82b01224-aa41-417d-a7d2-25499fc1e9ef.jpeg"></media:thumbnail><summary type="html">&lt;img src=&quot;https://img4.teletype.in/files/f3/de/f3de2cf4-6f42-4966-889f-b6c91e828779.jpeg&quot;&gt;Препроцессоры CSS популярны, но у них есть некоторые недостатки. В этой статье мы рассмотрим преимущества PostCSS, как он работает и чего можно добиться с помощью обширного набора плагинов.</summary><content type="html">
  &lt;figure id=&quot;kTM7&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/f3/de/f3de2cf4-6f42-4966-889f-b6c91e828779.jpeg&quot; width=&quot;1280&quot; /&gt;
  &lt;/figure&gt;
  &lt;blockquote id=&quot;ypmB&quot;&gt;Препроцессоры CSS популярны, но у них есть некоторые недостатки. В этой статье мы рассмотрим преимущества PostCSS, как он работает и чего можно добиться с помощью обширного набора плагинов.&lt;/blockquote&gt;
  &lt;h2 id=&quot;tLux&quot;&gt;Значение и ограничения препроцессоров&lt;/h2&gt;
  &lt;p id=&quot;EHWM&quot;&gt;Большинство разработчиков CSS знакомы с препроцессорами. Такие инструменты, как Sass, Less и Stylus, ввели такие понятия, как партиции файлов, вложенность, переменные и миксины. Некоторые функции постепенно появляются в родном CSS, но препроцессор по-прежнему полезен для управления большими кодовыми базами и поддержания единства стиля в коде.&lt;/p&gt;
  &lt;p id=&quot;0FvA&quot;&gt;Трудно представить себе работу без препроцессора CSS, но есть и минусы:&lt;/p&gt;
  &lt;ul id=&quot;Yx7T&quot;&gt;
    &lt;li id=&quot;6JBl&quot;&gt;&lt;strong&gt;Препроцессоры не являются расширяемыми или ограничиваемыми&lt;/strong&gt;. Большинство препроцессоров - это &amp;quot;черный ящик&amp;quot;, который предоставляет вам определенный набор поддерживаемых функций. Можно написать пользовательские функции, но функциональность, выходящая за рамки данного инструмента, остается невозможной - например, вставка SVG в качестве фонового изображения. Аналогично, вы не можете остановить разработчиков, использующих опции, которых вы предпочли бы избежать, такие как &lt;code&gt;@extend&lt;/code&gt; или глубокая вложенность. Линтинг может помочь, но он не остановит препроцессор от компиляции корректного файла.&lt;/li&gt;
    &lt;li id=&quot;M1Ry&quot;&gt;&lt;strong&gt;Препроцессоры предоставляют свой собственный синтаксис.&lt;/strong&gt; Код препроцессора может напоминать CSS, но ни один браузер не сможет разобрать этот файл. Синтаксис отличается, и если ваш инструмент изменится или станет недоступным, ваш код потребует обновлений, чтобы сделать его пригодным для использования.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;5dgy&quot;&gt;Преимущества более чем превосходят эти риски, но существует альтернатива ...&lt;/p&gt;
  &lt;h2 id=&quot;vmqR&quot;&gt;Что такое PostCSS?&lt;/h2&gt;
  &lt;p id=&quot;ADtc&quot;&gt;PostCSS - это &lt;a href=&quot;https://github.com/postcss/postcss&quot; target=&quot;_blank&quot;&gt;не препроцессор&lt;/a&gt; (хотя он может работать как таковой). Это инструмент Node.js, который берет валидный CSS и улучшает его. Даже те, кто использует Sass, Less или Stylus, часто выполняют шаг PostCSS после первоначальной компиляции CSS. Вероятно, вы сталкивались с плагином PostCSS &lt;a href=&quot;https://github.com/postcss/autoprefixer&quot; target=&quot;_blank&quot;&gt;Autoprefixer&lt;/a&gt;, который автоматически добавляет префиксы &lt;code&gt;-webkit&lt;/code&gt;, &lt;code&gt;-moz&lt;/code&gt; и &lt;code&gt;-ms&lt;/code&gt; к свойствам CSS, которые их требуют.&lt;/p&gt;
  &lt;p id=&quot;CwBN&quot;&gt;Сам по себе PostCSS ничего не делает. Это синтаксический разборщик, который токенизирует код CSS для создания абстрактного синтаксического дерева. Плагин может обработать это дерево и соответствующим образом обновить свойства. После того, как все плагины завершат свою работу, PostCSS переформатирует все обратно в строку и выводит в файл CSS.&lt;/p&gt;
  &lt;p id=&quot;IY9u&quot;&gt;Доступно около &lt;a href=&quot;https://github.com/postcss/postcss/blob/main/docs/plugins.md&quot; target=&quot;_blank&quot;&gt;350 плагинов&lt;/a&gt;, и большинство из них выполняют одну задачу, например, &lt;a href=&quot;https://github.com/postcss/postcss-import&quot; target=&quot;_blank&quot;&gt;инлайнинг @import деклараций&lt;/a&gt;, &lt;a href=&quot;https://github.com/postcss/postcss-calc&quot; target=&quot;_blank&quot;&gt;упрощение функций calc()&lt;/a&gt;, &lt;a href=&quot;https://github.com/borodean/postcss-assets&quot; target=&quot;_blank&quot;&gt;работа с изображениями&lt;/a&gt;, &lt;a href=&quot;https://github.com/stylelint/stylelint&quot; target=&quot;_blank&quot;&gt;линтинг синтаксиса&lt;/a&gt;,&lt;a href=&quot;https://cssnano.co/&quot; target=&quot;_blank&quot;&gt; минификация&lt;/a&gt; и многое другое. Более удобный поиск плагинов доступен в каталоге &lt;a href=&quot;https://www.postcss.parts/&quot; target=&quot;_blank&quot;&gt;плагинов PostCSS&lt;/a&gt;.&lt;/p&gt;
  &lt;h3 id=&quot;JQj6&quot;&gt;Преимущества PostCSS&lt;/h3&gt;
  &lt;ul id=&quot;TmzA&quot;&gt;
    &lt;li id=&quot;Zq3t&quot;&gt;PostCSS является для CSS тем же, чем &lt;a href=&quot;https://babeljs.io/&quot; target=&quot;_blank&quot;&gt;Babel&lt;/a&gt; является для JavaScript. Он может взять стандартную таблицу стилей, которая работает в последних браузерах, и вывести CSS, который работает везде - например, преобразовать новое &lt;a href=&quot;https://developer.mozilla.org/ru/docs/Web/CSS/inset&quot; target=&quot;_blank&quot;&gt;свойство &lt;code&gt;inset&lt;/code&gt;&lt;/a&gt; обратно в свойства &lt;code&gt;top&lt;/code&gt;, &lt;code&gt;bottom&lt;/code&gt;, &lt;code&gt;left&lt;/code&gt; и &lt;code&gt;right&lt;/code&gt;. Со временем вы можете отказаться от этого процесса, поскольку все больше браузеров поддерживают &lt;code&gt;inset&lt;/code&gt;.  Конечно, некоторые плагины позволяют анализировать синтаксис препроцессора, который не является стандартным CSS, но вы не обязаны их использовать.&lt;/li&gt;
    &lt;li id=&quot;SZ7z&quot;&gt;&lt;strong&gt;Используйте плагины и функции, которые вам нужны.&lt;/strong&gt; PostCSS является настраиваемым, и вы можете использовать те плагины, которые вам нужны. Например, вы можете поддерживать партиклы (&lt;a href=&quot;https://github.com/postcss/postcss-import&quot; target=&quot;_blank&quot;&gt;partials&lt;/a&gt;) и &lt;a href=&quot;https://github.com/postcss/postcss-nested&quot; target=&quot;_blank&quot;&gt;вложенность&lt;/a&gt;, но не разрешать переменные, циклы, миксины, мапы и другие возможности, доступные в Sass.&lt;/li&gt;
    &lt;li id=&quot;kiqR&quot;&gt;&lt;strong&gt;Обеспечьте индивидуальную настройку для каждого проекта. &lt;/strong&gt;Индивидуальная настройка проекта может расширить или уменьшить набор плагинов, используемых в других местах. Возможности намного разнообразнее, чем у любого препроцессора.&lt;/li&gt;
    &lt;li id=&quot;bUt0&quot;&gt;&lt;strong&gt;Пишите собственные плагины для PostCSS.&lt;/strong&gt; Существует широкий спектр плагинов для расширения синтаксиса, разбора будущих свойств, добавления возвратов, оптимизации кода, обработки цветов, изображений, шрифтов и даже написания CSS на других языках, таких как &lt;a href=&quot;https://github.com/ismamz/postcss-spanish-stylesheets&quot; target=&quot;_blank&quot;&gt;испанский&lt;/a&gt; и &lt;a href=&quot;https://github.com/Semigradsky/postcss-russian-stylesheets&quot; target=&quot;_blank&quot;&gt;русский&lt;/a&gt;. Если вдруг вы не найдете то, что вам нужно, вы можете написать &lt;a href=&quot;https://github.com/postcss/postcss/blob/main/docs/writing-a-plugin.md&quot; target=&quot;_blank&quot;&gt;свой собственный плагин&lt;/a&gt; PostCSS на JavaScript.&lt;/li&gt;
    &lt;li id=&quot;aIeY&quot;&gt;&lt;strong&gt;Возможно, вы уже используете PostCSS.&lt;/strong&gt; Вы можете удалить зависимости от препроцессора, если уже используете плагин PostCSS, например AutoPrefixer. PostCSS не обязательно быстрее или легче, чем использование препроцессора, но он может обрабатывать все CSS за один шаг.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h2 id=&quot;yeIj&quot;&gt;Установка PostCSS&lt;/h2&gt;
  &lt;p id=&quot;psyU&quot;&gt;PostCSS требует &lt;a href=&quot;https://nodejs.org/en/&quot; target=&quot;_blank&quot;&gt;Node.js&lt;/a&gt;, но в этом руководстве демонстрируется, как установить и запустить PostCSS из любой папки - даже из тех, которые не являются проектами Node.js. Вы также можете использовать PostCSS из &lt;a href=&quot;https://github.com/postcss/postcss#usage&quot; target=&quot;_blank&quot;&gt;webpack&lt;/a&gt;, &lt;a href=&quot;https://github.com/postcss/postcss#usage&quot; target=&quot;_blank&quot;&gt;Parcel&lt;/a&gt;, &lt;a href=&quot;https://github.com/postcss/postcss#usage&quot; target=&quot;_blank&quot;&gt;Gulp.js&lt;/a&gt; и &lt;a href=&quot;https://github.com/postcss/postcss#usage&quot; target=&quot;_blank&quot;&gt;других инструментов&lt;/a&gt;, но мы будем придерживаться командной строки.&lt;/p&gt;
  &lt;p id=&quot;eCdY&quot;&gt;Установите PostCSS глобально в вашей системе, выполнив следующее:&lt;/p&gt;
  &lt;pre id=&quot;z6h0&quot; data-lang=&quot;css&quot;&gt;npm install -g postcss-cli&lt;/pre&gt;
  &lt;p id=&quot;G1Wm&quot;&gt;Убедитесь, что он работает, введя это:&lt;/p&gt;
  &lt;pre id=&quot;VpMV&quot; data-lang=&quot;bash&quot;&gt;postcss --help&lt;/pre&gt;
  &lt;h2 id=&quot;PQYj&quot;&gt;Установка вашего первого плагина PostCSS&lt;/h2&gt;
  &lt;p id=&quot;Lkmt&quot;&gt;Чтобы сделать что-то практичное, вам потребуется как минимум один плагин. Хорошим вариантом является плагин &lt;a href=&quot;https://github.com/postcss/postcss-import&quot; target=&quot;_blank&quot;&gt;импорта&lt;/a&gt; PostCSS, который инлайнит все объявления &lt;code&gt;@import&lt;/code&gt; и объединяет ваши CSS в один файл. Установите его глобально следующим образом:&lt;/p&gt;
  &lt;pre id=&quot;8nvw&quot; data-lang=&quot;css&quot;&gt;npm install -g postcss-import&lt;/pre&gt;
  &lt;p id=&quot;iW4S&quot;&gt;Чтобы протестировать этот плагин, откройте или создайте новую папку проекта, например &lt;code&gt;cssproject&lt;/code&gt;, затем создайте подпапку &lt;code&gt;src&lt;/code&gt; для ваших исходных файлов. Создайте файл &lt;code&gt;main.css&lt;/code&gt;, чтобы загрузить все партиклы:&lt;/p&gt;
  &lt;pre id=&quot;VKEI&quot; data-lang=&quot;css&quot;&gt;/* src/main.css */
@import &amp;#x27;_reset&amp;#x27;;
@import &amp;#x27;_elements&amp;#x27;;&lt;/pre&gt;
  &lt;p id=&quot;4lRa&quot;&gt;Затем создайте файл &lt;code&gt;_reset.css&lt;/code&gt; в той же папке:&lt;/p&gt;
  &lt;pre id=&quot;4MO6&quot; data-lang=&quot;css&quot;&gt;/* src/reset.css */
* {
  padding: 0;
  margin: 0;
}&lt;/pre&gt;
  &lt;p id=&quot;977p&quot;&gt;После этого создайте файл &lt;code&gt;_elements.css&lt;/code&gt;:&lt;/p&gt;
  &lt;pre id=&quot;L7VG&quot; data-lang=&quot;css&quot;&gt;/* src/elements.css */
body {
  font-family: sans-serif;
}

label {
  user-select: none;
}&lt;/pre&gt;
  &lt;p id=&quot;PIG3&quot;&gt;Запустите PostCSS из корневой папки проекта, передав входной CSS-файл, список плагинов для &lt;code&gt;--use&lt;/code&gt; и имя &lt;code&gt;--output&lt;/code&gt; файла:&lt;/p&gt;
  &lt;pre id=&quot;FsgZ&quot; data-lang=&quot;css&quot;&gt;postcss ./src/main.css --use postcss-import --output ./styles.css&lt;/pre&gt;
  &lt;p id=&quot;XaFp&quot;&gt;Если у вас нет ошибок, следующий код будет выведен в новый файл &lt;code&gt;styles.css&lt;/code&gt; в корне проекта:&lt;/p&gt;
  &lt;pre id=&quot;uqR8&quot; data-lang=&quot;css&quot;&gt;/* src/main.css */
/* src/reset.css */
* {
  padding: 0;
  margin: 0;
}
/* src/elements.css */
body {
  font-family: sans-serif;
}
label {
  user-select: none;
}
/* sourceMappingURL=data:application/json;base64,...&lt;/pre&gt;
  &lt;p id=&quot;oCzu&quot;&gt;Обратите внимание, что PostCSS может выводить файлы CSS в любом месте, но папка вывода должна существовать; он не будет создавать структуру папок за вас.&lt;/p&gt;
  &lt;h2 id=&quot;NJ7p&quot;&gt;Включение и отключение карт источников&lt;/h2&gt;
  &lt;p id=&quot;qoI7&quot;&gt;По умолчанию выводится встроенная карта исходного текста. Когда скомпилированный CSS-файл используется в HTML-странице, при его просмотре в инструментах разработчика браузера будет показан исходный &lt;code&gt;src&lt;/code&gt;-файл и строка. Например, при просмотре стилей &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; будет выделена строка 2 &lt;code&gt;src/_elements.css&lt;/code&gt;, а не строка 8 &lt;code&gt;styles.css&lt;/code&gt;.&lt;/p&gt;
  &lt;p id=&quot;NoYE&quot;&gt;Вы можете создать внешнюю карту источников, добавив переключатель &lt;code&gt;--map&lt;/code&gt; (или &lt;code&gt;-m&lt;/code&gt;) к команде &lt;code&gt;postcss&lt;/code&gt;. Пользы от этого немного, кроме того, что CSS-файл становится чище, и браузеру не нужно загружать карту исходников, если только не открыты инструменты разработчика.&lt;/p&gt;
  &lt;p id=&quot;S0Gc&quot;&gt;Вы можете удалить карту источников с помощью опции &lt;code&gt;--no-map&lt;/code&gt;. Всегда используйте эту опцию при выводе CSS-файлов для продакшен развертывания.&lt;/p&gt;
  &lt;h2 id=&quot;KAw4&quot;&gt;Установка и использование плагина AutoPrefixer&lt;/h2&gt;
  &lt;p id=&quot;A8r9&quot;&gt;Плагин &lt;a href=&quot;https://github.com/postcss/autoprefixer&quot; target=&quot;_blank&quot;&gt;Autoprefixer&lt;/a&gt; часто является первым знакомством разработчика с PostCSS. Он добавляет префиксы поставщиков в соответствии с использованием браузера и правилами, определенными на сайте &lt;a href=&quot;https://caniuse.com/&quot; target=&quot;_blank&quot;&gt;caniuse.com&lt;/a&gt;. Префиксы поставщиков меньше используются в современных браузерах, которые скрывают экспериментальную функциональность за флагами. Однако все еще существуют свойства, такие как user-select, для которых требуются префиксы &lt;code&gt;-webkit-&lt;/code&gt;, &lt;code&gt;-moz-&lt;/code&gt; и &lt;code&gt;-ms-&lt;/code&gt;.&lt;/p&gt;
  &lt;p id=&quot;Mlwy&quot;&gt;Установите плагин глобально с помощью этого:&lt;/p&gt;
  &lt;pre id=&quot;rjX0&quot; data-lang=&quot;css&quot;&gt;npm install -g autoprefixer&lt;/pre&gt;
  &lt;p id=&quot;Kvyo&quot;&gt;Затем укажите его как еще один параметр &lt;code&gt;--use&lt;/code&gt; в команде &lt;code&gt;postcss&lt;/code&gt;:&lt;/p&gt;
  &lt;pre id=&quot;gnxg&quot; data-lang=&quot;bash&quot;&gt;postcss ./src/main.css --use postcss-import --use autoprefixer --output ./styles.css&lt;/pre&gt;
  &lt;p id=&quot;IiJV&quot;&gt;Изучите объявление &lt;code&gt;label&lt;/code&gt; в строке 11 файла &lt;code&gt;styles.css&lt;/code&gt;, чтобы увидеть свойства, привязанные к производителю:&lt;/p&gt;
  &lt;pre id=&quot;7m69&quot; data-lang=&quot;css&quot;&gt;label {
  -webkit-user-select: none;
     -moz-user-select: none;
      -ms-user-select: none;
          user-select: none;
}&lt;/pre&gt;
  &lt;p id=&quot;YlB5&quot;&gt;AutoPrefixer использует модуль &lt;a href=&quot;https://github.com/browserslist/browserslist&quot; target=&quot;_blank&quot;&gt;browserlist&lt;/a&gt; для определения того, какие префиксы браузера необходимо добавить. По умолчанию это:&lt;/p&gt;
  &lt;ul id=&quot;mAo9&quot;&gt;
    &lt;li id=&quot;PZhH&quot;&gt;&lt;code&gt;&amp;gt; 0,5%&lt;/code&gt;: браузер с долей рынка не менее 0,5%&lt;/li&gt;
    &lt;li id=&quot;uC4l&quot;&gt;&lt;code&gt;последние 2 версии&lt;/code&gt;: последние два выпуска этих браузеров&lt;/li&gt;
    &lt;li id=&quot;vOD5&quot;&gt;&lt;code&gt;Firefox ESR&lt;/code&gt;: включая Firefox Extended Support Releases&lt;/li&gt;
    &lt;li id=&quot;8bzD&quot;&gt;&lt;code&gt;не устаревший&lt;/code&gt;: любой браузер, который не снят с производства&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;uwto&quot;&gt;Вы можете изменить эти настройки по умолчанию, создав файл &lt;code&gt;.browserslistrc.&lt;/code&gt; &lt;/p&gt;
  &lt;pre id=&quot;KLGV&quot; data-lang=&quot;css&quot;&gt;&amp;gt; 2%&lt;/pre&gt;
  &lt;p id=&quot;tU6A&quot;&gt;Или вы можете добавить массив &lt;code&gt;&amp;quot;browserslist&amp;quot;&lt;/code&gt; в &lt;code&gt;package.json&lt;/code&gt; в проекте Node.js. &lt;/p&gt;
  &lt;pre id=&quot;i3zj&quot; data-lang=&quot;css&quot;&gt;&amp;quot;browserslist&amp;quot;: [
   &amp;quot;&amp;gt; 2%&amp;quot;
]&lt;/pre&gt;
  &lt;p id=&quot;Ni5D&quot;&gt;Для адресации браузеров с долей рынка 2% и более требуется только префикс &lt;code&gt;-webkit-&lt;/code&gt; в Safari:&lt;/p&gt;
  &lt;pre id=&quot;7O6y&quot; data-lang=&quot;css&quot;&gt;label {
  -webkit-user-select: none;
          user-select: none;
}
&lt;/pre&gt;
  &lt;h2 id=&quot;tYY1&quot;&gt;Минимизация CSS с помощью cssnano&lt;/h2&gt;
  &lt;p id=&quot;a5ok&quot;&gt;&lt;a href=&quot;https://cssnano.co/&quot; target=&quot;_blank&quot;&gt;cssnano&lt;/a&gt; минимизирует CSS, удаляя пробелы, комментарии и другие ненужные символы. Результаты могут быть разными, но вы можете ожидать уменьшения файлов на 30%, которые можно развернуть на продакшен серверах для повышения производительности веб-страниц.&lt;/p&gt;
  &lt;p id=&quot;urAu&quot;&gt;Установка cssnano глобально:&lt;/p&gt;
  &lt;pre id=&quot;VpjG&quot; data-lang=&quot;css&quot;&gt;npm install -g cssnano&lt;/pre&gt;
  &lt;p id=&quot;vwJ6&quot;&gt;Затем добавьте его в команду &lt;code&gt;postcss&lt;/code&gt;. Мы также включим &lt;code&gt;--no-map&lt;/code&gt;, чтобы отключить карту источников:&lt;/p&gt;
  &lt;pre id=&quot;CnF0&quot; data-lang=&quot;bash&quot;&gt;postcss ./src/main.css --use postcss-import --use autoprefixer --use cssnano --no-map --output ./styles.css&lt;/pre&gt;
  &lt;p id=&quot;lfHD&quot;&gt;Это сокращает CSS-файл до 97 символов:&lt;/p&gt;
  &lt;pre id=&quot;ALE5&quot; data-lang=&quot;css&quot;&gt;*{margin:0;padding:0}body{font-family:sans-serif}label{-webkit-user-select:none;user-select:none}&lt;/pre&gt;
  &lt;h2 id=&quot;JQgI&quot;&gt;Автоматическая сборка при изменении исходных файлов&lt;/h2&gt;
  &lt;p id=&quot;hxsQ&quot;&gt;Опция PostCSS &lt;code&gt;--watch&lt;/code&gt; автоматически собирает ваш CSS-файл при изменении любого из исходных файлов. Вы также можете добавить переключатель &lt;code&gt;--verbose&lt;/code&gt;, который сообщает, когда происходит сборка:&lt;/p&gt;
  &lt;pre id=&quot;w559&quot; data-lang=&quot;bash&quot;&gt;postcss ./src/main.css --use postcss-import --use autoprefixer --use cssnano --no-map --output ./styles.css --watch --verbose&lt;/pre&gt;
  &lt;p id=&quot;qPWg&quot;&gt;Ваш терминал покажет &lt;code&gt;Waiting for file changes&lt;/code&gt;. Внесите изменения в любой файл, и файл &lt;code&gt;styles.css&lt;/code&gt; будет перестроен. PostCSS также сообщит о любых проблемах, таких как синтаксические ошибки.&lt;/p&gt;
  &lt;p id=&quot;Y6An&quot;&gt;Для завершения нажмите &lt;code&gt;Ctrl&lt;/code&gt; | &lt;code&gt;Cmd&lt;/code&gt; + &lt;code&gt;C&lt;/code&gt; в терминале.&lt;/p&gt;
  &lt;h2 id=&quot;JtnP&quot;&gt;Создание файла конфигурации PostCSS&lt;/h2&gt;
  &lt;p id=&quot;0VF6&quot;&gt;Команда &lt;code&gt;postcss&lt;/code&gt; становится длинной и громоздкой по мере добавления дополнительных плагинов и опций. Вы можете создать конфигурационный файл JavaScript, который определяет все опции и может логически определить, запущен ли он в среде разработки или производства.&lt;/p&gt;
  &lt;p id=&quot;sjjj&quot;&gt;Создайте файл конфигурации с именем &lt;code&gt;postcss.config.cjs&lt;/code&gt; в корне папки вашего проекта. Также обратите внимание на следующее:&lt;/p&gt;
  &lt;ul id=&quot;OnvR&quot;&gt;
    &lt;li id=&quot;t1UZ&quot;&gt;вы можете поместить файл в другую папку, но при запуске &lt;code&gt;postcss&lt;/code&gt; вам нужно будет указать &lt;code&gt;--config&lt;/code&gt; &lt;code&gt;&amp;lt;dir&amp;gt;&lt;/code&gt;&lt;/li&gt;
    &lt;li id=&quot;Qq3P&quot;&gt;вы можете использовать &lt;code&gt;postcss.config.js&lt;/code&gt; в качестве имени файла, но PostCSS может не работать в проектах Node.js, у которых &lt;code&gt;&amp;quot;type&amp;quot;: &amp;quot;module&amp;quot;&lt;/code&gt; в &lt;code&gt;package.json&lt;/code&gt;&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;QWTd&quot;&gt;Добавьте следующий код в файл &lt;code&gt;postcss.config.cjs&lt;/code&gt;:&lt;/p&gt;
  &lt;pre id=&quot;mTSR&quot; data-lang=&quot;javascript&quot;&gt;// Конфигурация PostCSS
module.exports = (cfg) =&amp;gt; {
  const devMode = (cfg.env === &amp;#x27;development&amp;#x27;);

  return {
    map: devMode ? &amp;#x27;inline&amp;#x27; : null,
    plugins: [
      require(&amp;#x27;postcss-import&amp;#x27;)(),
      require(&amp;#x27;autoprefixer&amp;#x27;)(),
      devMode ? null : require(&amp;#x27;cssnano&amp;#x27;)()
    ]
  };
};&lt;/pre&gt;
  &lt;p id=&quot;1y7c&quot;&gt;PostCSS передает объект &lt;code&gt;cfg&lt;/code&gt;, который содержит параметры командной строки. &lt;/p&gt;
  &lt;pre id=&quot;aFan&quot; data-lang=&quot;javascript&quot;&gt;{
  cwd: &amp;#x27;/home/yourname/cssproject&amp;#x27;,
  env: undefined,
  options: {
    map: { inline: true },
    parser: undefined,
    syntax: undefined,
    stringifier: undefined
  },
  file: {
    dirname: &amp;#x27;/home/yourname/cssproject/src&amp;#x27;,
    basename: &amp;#x27;main.css&amp;#x27;,
    extname: &amp;#x27;.css&amp;#x27;
  }
}&lt;/pre&gt;
  &lt;p id=&quot;AIUZ&quot;&gt;Модуль должен возвращать объект с необязательными свойствами:&lt;/p&gt;
  &lt;ul id=&quot;yae9&quot;&gt;
    &lt;li id=&quot;Lw9z&quot;&gt;&lt;code&gt;map&lt;/code&gt;: настройка карты источника&lt;/li&gt;
    &lt;li id=&quot;6kmR&quot;&gt;&lt;code&gt;parser&lt;/code&gt;: использовать ли синтаксический анализатор не-CSS (например, плагин &lt;a href=&quot;https://github.com/postcss/postcss-scss&quot; target=&quot;_blank&quot;&gt;scss&lt;/a&gt;).&lt;/li&gt;
    &lt;li id=&quot;iOxi&quot;&gt;&lt;code&gt;plugins&lt;/code&gt;: массив плагинов и конфигураций для обработки в указанном порядке&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;Xi2x&quot;&gt;Приведенный выше код определяет, есть ли у команды &lt;code&gt;postcss&lt;/code&gt; опция &lt;code&gt;--env&lt;/code&gt;. Это сокращение для установки переменной окружения &lt;code&gt;NODE_ENV&lt;/code&gt;. Чтобы скомпилировать CSS в режиме разработки, запустите &lt;code&gt;postcss&lt;/code&gt; с опцией &lt;code&gt;--env development&lt;/code&gt; и, опционально, установите &lt;code&gt;--watch --verbose&lt;/code&gt;. Это создает встроенную карту исходников и не минифицирует вывод:&lt;/p&gt;
  &lt;pre id=&quot;1MXo&quot; data-lang=&quot;bash&quot;&gt;postcss ./src/main.css --output ./styles.css --env development --watch --verbose&lt;/pre&gt;
  &lt;p id=&quot;NMvU&quot;&gt;Чтобы работать в производственном режиме и компилировать минифицированный CSS без карты исходников, используйте следующее:&lt;/p&gt;
  &lt;pre id=&quot;t83J&quot; data-lang=&quot;bash&quot;&gt;postcss ./src/main.css --output ./styles.css&lt;/pre&gt;
  &lt;p id=&quot;Zz1H&quot;&gt;В идеале, вы можете запускать их как скрипты терминала или &lt;code&gt;npm&lt;/code&gt;, чтобы еще больше сократить усилия по набору текста.&lt;/p&gt;
  &lt;h2 id=&quot;RZyv&quot;&gt;Опыт PostCSS&lt;/h2&gt;
  &lt;p id=&quot;9Yvy&quot;&gt;Теперь вы знаете основы PostCSS. Расширение функциональности - это вопрос добавления и настройки дополнительных плагинов. Потратьте немного времени, и вскоре у вас будет свой рабочий механизм, который вы сможете адаптировать для любого веб-проекта.&lt;/p&gt;
  &lt;p id=&quot;pd05&quot;&gt;В руководстве по использованию PostCSS в качестве &lt;a href=&quot;https://www.sitepoint.com/postcss-sass-configurable-alternative/&quot; target=&quot;_blank&quot;&gt;настраиваемой альтернативы Sass&lt;/a&gt; приведено больше примеров конфигурации и вариантов плагинов.&lt;/p&gt;
  &lt;p id=&quot;OO40&quot;&gt;Дальнейшие ссылки:&lt;/p&gt;
  &lt;ul id=&quot;wmFM&quot;&gt;
    &lt;li id=&quot;dOYD&quot;&gt;&lt;a href=&quot;https://postcss.org/&quot; target=&quot;_blank&quot;&gt;Домашняя страница&lt;/a&gt; PostCSS&lt;/li&gt;
    &lt;li id=&quot;Vqfj&quot;&gt;PostCSS &lt;a href=&quot;https://github.com/postcss/postcss-cli&quot; target=&quot;_blank&quot;&gt;CLI&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;7WPl&quot;&gt;&lt;a href=&quot;https://github.com/postcss/postcss/blob/main/docs/plugins.md&quot; target=&quot;_blank&quot;&gt;список плагинов&lt;/a&gt; для PostCSS&lt;/li&gt;
    &lt;li id=&quot;vD1E&quot;&gt;&lt;a href=&quot;https://www.postcss.parts/&quot; target=&quot;_blank&quot;&gt;каталог плагинов&lt;/a&gt; для PostCSS с возможностью поиска&lt;/li&gt;
    &lt;li id=&quot;Ll76&quot;&gt;&lt;a href=&quot;https://www.npmjs.com/search?q=keywords:postcss&quot; target=&quot;_blank&quot;&gt;плагины на npmjs.com&lt;/a&gt; для PostCSS&lt;/li&gt;
    &lt;li id=&quot;JXdJ&quot;&gt;&lt;a href=&quot;https://github.com/postcss/postcss/blob/main/docs/writing-a-plugin.md&quot; target=&quot;_blank&quot;&gt;Написание плагина&lt;/a&gt; для PostCSS&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;wgeH&quot;&gt;Источник: &lt;a href=&quot;https://www.sitepoint.com/an-introduction-to-postcss/&quot; target=&quot;_blank&quot;&gt;https://www.sitepoint.com/an-introduction-to-postcss/&lt;/a&gt;&lt;/p&gt;

</content></entry></feed>