• Начните использовать ES6 и SASS в браузерах сегодня

    javascript

    Браузеры всегда были очень инертной средой для исполнения наших программ. Даже когда язык JavaScript ещё не развивался так быстро как сейчас, браузеры уже не успевали за ним. Годами на троне сидел какой-нибудь хтонический монстр вроде IE6 и заставлял с ним считаться каждого. Нам пришлось на долгое время забыть об использовании чистых языковых конструкций и научиться доверять очередной библиотеке, знающей разницу между браузерами и их версиями. Появились армии разработчиков, неплохо знающих jQuery, но как огня боящихся самого языка JavaScript. В то же время, дела со стилями в чем-то были еще хуже. Несмотря на появление множества новых свойств, сам формат не получил вообще никаких значимых улучшений и, в сыром виде, даже сейчас едва ли может быть удобен кому-либо.

    Конечно, со временем, ситуация начала исправляться: поддержка JavaScript стала лучше, появились полифиллы для устаревших браузеров, компиляторы CSS и, наконец, транспайлеры в ES6. Но, к сожалению, это всё не доступно из коробки каждому, это удовольствие нужно настраивать разработчику и не всем из нас ясно как же это сделать. На первый взгляд всё кажется намного сложнее, чем дела обстоят на самом деле. Кажется, что если у вас нет специального сервера для сборки, CI, CD, какого-нибудь хитрого сборщика, то не стоит и пытаться что-то сделать. Но, на самом деле, это и не требуется.

    Полифилл — это библиотека, которая добавляет в старые браузеры поддержку возможностей, которые в современных браузерах являются встроенными

    Транспайлер — это процесс компиляции программы с одного языка программирования в коды другого языка программирования, при условии одинакового уровня абстракции этих языков

    Установка Node.Js и npm

    Node.Js — это среда исполнения JavaScript, основанная на JavaScript движке V8, и предлагающая асинхронное API для работы с сетью и диском.

    npm — это менеджер пакетов для Node.Js

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

    curl -sL https://deb.nodesource.com/setup_5.x | sudo -E bash -
    sudo apt-get install nodejs build-essential
    
    node -v 
    v5.8.0
    
    npm -v
    3.7.3

    А теперь создадим новый пакет:

    npm init

    Ответьте на все вопросы мастера. По результатам будет сгенерирован файл package.json подобного вида:

    {
      "name": "awesome-website",
      "version": "1.0.0",
      "description": "",
      "main": "index.js"
    }

    JavaScript: сборка модулей в один файл

    Для сборки всех файлов и модулей в один файл, готовый к «отгрузке» клиентскому браузеру, мы используем browserify. Установим его:

    npm install --save-dev browserify

    Данная команда найдет подходящую версию для browserify, установит её и сохранить информацию об этой зависимости в секции «devDependencies» файла «package.json».

    Теперь создадим скрипт для npm, который будет запускать сборку JavaScript. Для этого измените секцию «scripts» в файле «package.json» следующим образом:

    "scripts": {
      "build-js": "browserify ./src/bundle.js > ./dist/bundle.js"
    }

    Сейчас и в дальнейшем, можно запускать сборку следующей командой:

    npm run build-js
    
    > awesome-website@1.0.0 build-js /var/www/project/www
    > browserify ./src/bundle.js > ./dist/bundle.js

    Не беда, что browserify недоступен как исполняемый файл глобально. npm самостоятельно разберется с путями до ./node_modules/.bin, если запускать команду через npm run.

    JavaScript: транспайлинг из ES6 в ES5

    Нет сомнений, что сборка модулей в один файл это уже очень неплохо и большой шаг вперед, пока мы всё еще ждем HTTP2. Но пока мы не можем использовать никаких современных возможностей ES6, так как всё еще не настроили транспайлинг. Самое время сделать это. Для начала, установим сам транспайлер, плагины к нему, а также адаптер для интеграции с browserify:

    npm install --save-dev babel babel-preset-es2015 babel-preset-react babelify

    После этого, модифицируйте скрипт «build-js» в файле «package.json» следующим образом:

    "scripts": {
      "build-js": "browserify ./src/bundle.js -t babelify -d > ./dist/bundle.js"
    }

    Также потребуется указать, как именно мы хотим проводить транспайлинг. В нашем случае, мы установили babel-preset-es2015, который позволит использовать возможности ES6. При желании, аналогичным образом можно также поставить и другие вариант транспиляции, например для преобразования jsx или ES7 в ES5. Добавьте новую секцию «browserify» следующего содержания в «package.json» и укажите, какие именно преобразования необходимо произвести над исходным кодом:

    "browserify": {
      "transform": [["babelify", { "presets": ["es2015", "react"}]]
    }

    JavaScript: добавление полифилла для ES5

    На данном этапе, код, который мы получаем от транспайлера, может работать в любом браузере, поддерживающем ES5. К сожалению, есть небольшой процент браузеров, которые не в полной мере поддерживают ES5. Мы можем использовать так называемый shim, добавляющий часть возможностей ES5. К сожалению, не все методы могут быть реализованы таким образом. Но хоть что-то — уже не так плохо.

    npm install --save-dev es5-shim
    "scripts": {
      "build-js": "browserify -r \"es5-shim\" ./src/bundle.js -t babelify -d > ./dist/bundle.js"
    }

    JavaScript: обфускация и минификация

    Хотя на прошлом шаге мы уже добились исполнения JavaScript ES6 в браузере, он всё еще не оптимизирован по размеру. Для обфускации и уменьшения размера файла можно использовать, например, uglifyjs:

    npm install --save-dev uglifyjs
    "scripts": {
      "build-js": "browserify -r \"es5-shim\" ./src/bundle.js -t babelify -d | uglifyjs -mc warnings=false > ./dist/bundle.js"
    }

    CSS: компиляция из SASS

    Аналогичным образом, мы можем обработать и SASS, преобразовав его в CSS, понимаемый всеми браузерами, обфусцировав его. Для начала, установим компилятор из SASS в CSS:

    npm install --save-dev node-sass

    Добавим новый скрипт для сборки стилей:

    "scripts": {
      "build-css": "node-sass ./src/bundle.scss ./dist/bundle.css"
    }
    npm run build-css
    
    > astgo@1.0.0 build-css /var/www/astgo/www
    > node-sass ./src/bundle.scss ./dist/bundle.css

    CSS: расстановка префиксов

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

    npm install --save-dev postcss-cli autoprefixer
    "scripts": {
      "build-css": "node-sass ./src/bundle.scss | postcss --use autoprefixer -b 'last 2 versions' > ./dist/bundle.css"
    }

    CSS: обфускация и минификация

    npm install --save-dev cssmin
    "scripts": {
      "build-css": "node-sass ./src/bundle.scss | postcss --use autoprefixer -b 'last 2 versions'  | cssmin > ./dist/bundle.css"
    }

    Пример

    Результат можно посмотреть в репозитарии:
    https://bitbucket.org/astartsky/modern-es6-sass-boilerplate

    git clone https://bitbucket.org/astartsky/modern-es6-sass-boilerplate .
    npm install
    npm run build-css
    npm run build-js
    node dist/bundle.js
    
    my awesome es6 is working fine!

    Итоги

    Итак, теперь ничто не мешает нам писать код на современном диалекте JavaScript, а стили на SASS. Что самое приятное в данном подходе — он применим практически в любом случае. Вам не требуется ни сервер сборки, ни современный код, ни определенная архитектура, ни разработка проекта с нуля. Вы можете применять этот подход в любом самом запущенном legacy-проекте, развернув небольшой параллельный стек технологий рядом с основным. Даже ваш бекенд не обязан об этом ничего знать и может быть любым.