Еще Один Способ Уменьшить Размер Spa-Приложения (Веб-Пакета).

Так уж получилось, что в последнее время мне приходится осваивать новые инструменты.

Еще одним таким инструментом был веб-пакет .

Инструмент интересный, но после перехода с Google Closure* для меня стало загадкой, почему веб-пакет не сжимает имена классов, как это делают таблицы стилей закрытия Google. За день, стоя на коленях, я написал плагин, который неплохо реализовал этот функционал.

Более подробное описание ниже.

И так начнем с технических характеристик.

Это сделано, во-первых, для себя, а во-вторых, для тех, кто еще не понял, что происходит, но каким-то образом оказался на этой странице.

Лично мне нравится писать большие, красивые и длинные имена классов, по которым сразу становится понятно, что происходит. Например:

  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
   

.

header { position: fixed; top: 0; .

} .

header a { display: block; float: right; .

} .

sidebar { float:right; max-width: 30%; .

} .

sidebar a { font-size: 16px; .

}

Но ты можешь сократить его заголовок до час боковая панель до с , тем самым сэкономив немало байт не только в CSS, но и в JS-файлах, т.к.

скорее всего ваш JS будет содержать селекторы имен классов.

Однако такое сокращение повлияет на читаемость кода и, как следствие, на скорость разработки.

Поэтому необходимо создать инструмент, позволяющий осуществлять эту замену автоматически.



Небольшое объяснение того, как это работает в Closure

Google Closure состоит из нескольких инструментов, одним из которых являются таблицы стилей Google Closure, которые являются одновременно препроцессором и постпроцессором для таблиц стилей.

По препроцессору он похож на всех своих собратьев, но больше всего на SCSS/SASS. В качестве постпроцессора он анализирует имена классов для создания словаря замен и заменяет все имена классов их короткими обозначениями.

Например, приведенный выше код будет выглядеть так:

.

a { position: fixed; top: 0; .

} .

a a { display: block; float: right; .

} .

b { float:right; max-width: 30%; .

} .

b a { font-size: 16px; .

}

И словарь замены будет:

{ "header": "a", "sidebar": "b" }

На самом деле функционала гораздо больше, но статья не об этом.

Еще есть Closure Templates — хороший шаблонизатор, в котором нужно пометить все имена классов специальной директивой, чтобы затем применить к шаблонам словарь замен.

Например:

{namespace test} /** * Test template * */ {template .

test} <div class="{css header}">Header<a href="#">Home</a><a href="#">About</a><header> .

<div class="{css sidebar}">Sidebar<header>

Также не следует забывать, что у нас есть JS, в котором нам также нужно «модифицировать» имена всех CSS-классов:

var header = goog.dom.getElementByClass(goog.getCssName('header')); var sidebar = goog.dom.getElementByClass(goog.getCssName('sidebar'));

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

если у вас есть класс, который используется только для выбора DOM-элемента из JS, то он может не попасть в словарь (или может быть, но я Оговорюсь, что данная статья не является обзором Closure Tools).



Вернёмся к плагину

Мне показалось не очень удобно разбрасывать повсюду функции, поэтому я решил задать имена классов по маске ___<%className%> __ .

Таким образом, стили будут выглядеть так:

.

___header__ { position: fixed; top: 0; .

} .

___header__ a { display: block; float: right; .

} .

___sidebar__ { float:right; max-width: 30%; .

} .

___sidebar__ a { font-size: 16px; .

}

И работа с DOM в JS, на примере jQuery:

var header = $('.

___header__'); var sidebar = $('.

___sidebar__');

Использование React в качестве примера:

function Header(props) { return ( <div className="___header__"> {props.children} </div> ); }

Использование Backbone в качестве примера:

module.exports = Backbone.View.extend({ tagName: 'div', className: '___header__' });

УПД: Для углового пример оказался толстым.

Сразу скажу, что структуры типа:

var genClassName = function(v) { return '___' + v + '__'; } module.exports = Backbone.View.extend({ tagName: 'div', className: genClassName('header') });

не будет работать.

То же, что и стили:

[class*="bold"] { font-weight:bolder; }



Первые шаги

Установка пакета:

npm install --save cssrename-webpack-plugin

И немного доработав его вебпак.

config.js :

const CssRenameWebpackPlugin = require('cssrename-webpack-plugin'); .

module.exports = { .

plugins: [ CssRenameWebpackPluginConfig, .

] };

В процессе сборки появится следующая строка: «Прибыль: 355» Который сообщит, сколько байт было сохранено.



Неудобства и их решения

Но если в разнообразном животном мире JS существует огромное количество библиотек, которые невозможно охватить одним парсером, то CSS в этом вопросе гораздо человечнее, и парсить его (CSS) гораздо проще.

В простейшей форме это будет одно регулярное выражение.

Поэтому почему бы не добавить аналогичный загрузчик, который избавит нас от добавления подчеркиваний хотя бы в CSS.

npm install --save cssrename-loader

Следующие мутации вебпак.

config.js :

module.exports = { module: { loaders: [ { test: /\.

css$/, loader: "style-loader!css-loader!cssrename-loader" } ] } };

Что случилось с тестовым проектом Обновлять: Это не то, о чем я хотел написать, но видимо это нужно добавить.

Ниже рассматриваются только стили; выигрыш от JS и шаблонов посчитать не так-то просто.

Для таблиц стилей закрытия Google:

Веб-сайт/файл Исходный том/zip Полученный том/zip Процент экономии (zip)
acs.io Bundle.488facb7.css 13,8 КБ/4,4 КБ 13,3 КБ/4,0 КБ ≈9%
getbem.com/introduction getbem.com.1.0.0.css 13,3 КБ/3,3 КБ 12 КБ/3,1 КБ ≈6%
Бутстрап 121,2 КБ/18,7 КБ 96,9 КБ/16,7 КБ ≈10%
хабрахабр.

ру global_main.css

212,3 КБ/30,6 КБ 155,2 КБ/26,9 КБ ≈13%
Доказательство Что не вошло в таблицы стилей закрытия Google: Для Atomic нам пришлось сделать две замены регулярных выражений:

\\\(((?:(?!\\\)).

)*?)\\\) => --$1-- \\.

=> --

Для БЭМ «не пролезло»:

@supports (display: -moz-box) { [class*=LineClamp] { display: block } } @-webkit-keyframes bounce { 0% { -webkit-transform: translateY(-100%); transform: translateY(-100%); -webkit-filter: blur(5px); filter: blur(5px) } 100%, 40% { -webkit-transform: translateY(0); transform: translateY(0) } 60% { -webkit-transform: translateY(-10%); transform: translateY(-10%) } } @keyframes bounce { 0% { -webkit-transform: translateY(-100%); transform: translateY(-100%); -webkit-filter: blur(5px); filter: blur(5px) } 100%, 40% { -webkit-transform: translateY(0); transform: translateY(0) } 60% { -webkit-transform: translateY(-10%); transform: translateY(-10%) } }

Из Bootstrap «не влезло»:

border-top: 4px solid \9; @media all and (transform-3d),(-webkit-transform-3d) @-ms-viewport { width: device-width }

От Хабра «не дошло»:

@charset "UTF-8"; @-moz-document url-prefix() { .

search-field__select { text-indent: .

01px; text-overflow: '' } }

Теги: #webpack #JavaScript #CSS #frontend #фронтальная разработка #препроцессор #разработка веб-сайтов #CSS #JavaScript

Вместе с данным постом часто просматривают: