Недавно я собрал интерфейсный набор инструментов для проекта WordPress. Как и в случае с большинством вещей, которые вы начинаете с нуля, было много первоначальных поисков в Google уже известных решений, прежде чем я создал свое собственное. Благодаря этому гуглению я нашел много разрозненных фрагментов того, что хотел, но ничего конкретного, поэтому решил задокументировать все, что нашел здесь. Но сначала позвольте мне рассказать о требованиях, которые я имел в виду, когда собирал это вместе.

Требования

  1. Не следует использовать Gulp или Grunt.
  2. Будет использовать сценарии NPM.
  3. Сохранит зависимости как можно меньше.
  4. Будет использовать BrowserSync для ввода/перезагрузки ресурсов без прокси.
  5. WebPack для связывания моего JavaScript.
  6. LESS для компиляции моего CSS.

Сначала я решил настроить мою часть сайта BrowserSync. Обычно, когда я работаю над статическим сайтом HarpJS или проектом Angular, у меня будет встроенный серверный прокси-сервер BrowserSync для приложения или локального размещения кода. Это очень простое решение, но, поскольку это проект WordPress, я не хотел проксировать свой сайт.

Среда разработки WordPress

Настройка WordPress использует Varying Vagrant Vagrants или VVV. Если вы знакомы с Vagrant, это профиль Vagrant, который поставляется с множеством специальных возможностей WordPress для разработки. В дополнение к VVV мы используем WordPress Packagist в сочетании с композитором для управления зависимостями наших плагинов. Чтобы начать нашу тему, у нас есть базовая тема Подчеркивания, которая была сильно урезана.

Настройка NPM

Ниже я перечислил все зависимости, которые мы использовали для этого проекта. Помимо очевидных вариантов, я расскажу, почему я использую такие пакеты, как nodemon и одновременно.

Одновременно

Когда я пишу сценарии NPM, бывают случаи, когда я хочу запустить два или более сценариев одновременно с использованием одной команды. Это в том же духе, что и Gulp или Grunt.

С bash вы можете запускать две команды синхронно с оператором &&. Например, git fetch && git pull — это обычное сочетание, которое вы видите. Это происходит, если git fetch завершается успешно, а затем запускает git pull. Кроме того, если вам нужно, чтобы две задачи выполнялись одновременно, вы можете использовать файл |. Если вы примените это к сценариям NPM, вы можете запустить два сценария с помощью одной команды, например:

“dev”: “npm run build && npm run watch”,
“build”: “npm run build:css | npm run build:js”

С этой настройкой я могу затем выполнить npm run dev, и мой сценарий наблюдения будет выполняться только после успешного завершения сценария сборки. К сожалению, используя | это специфичная для платформы команда, которая работает только в UNIX-подобной среде.

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

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

“dev”: “concurrently — raw ‘npm run build’ ‘npm run watch’”,
“build”: “concurrently — raw ‘npm run build:css’ ‘npm run build:js’”

Нодемон

Nodemon — это зависимость, которую я неохотно включил в проект из-за нашего выбора инструментов. Для этого конкретного проекта мы должны были использовать LESS. Обычно я являюсь поклонником SASS, и самое замечательное в инструментах командной строки для node-sass то, что они имеют встроенную команду наблюдения. Команда sass в Ruby тоже имеет этот функционал, но я не хотел тянуть Ruby в среду разработки, если в этом нет крайней необходимости. Это возвращает нас к LESS, у которого, к сожалению, нет возможности смотреть.

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

“watch:css”:”nodemon -q -e less -x lessc — source-map-map-inline site/theme/less/main.less site/theme/assets/css/bundle.css”

Приведенная выше команда делает пару вещей. Флаг -q отключает вывод nodemon, так как я не считаю, что это необходимо для разработки. Соответствующий вывод исходит от BrowserSync, но мы вернемся к этому позже. Флаг -e означает расширение, и он будет отслеживать все файлы меньшего размера в вашем проекте, если он заметит изменение в любом из этих файлов, он затем выполнит команду lessc. Это достигается с помощью -x части команды.

С компиляцией CSS я смог заняться сборкой своего JavaScript.

Связка Webpack и JavaScript

Раньше я использовал Browserify во всех своих проектах. Я действительно не видел необходимости использовать Webpack, потому что установка Browserify, которая у меня была, работала так хорошо. Только недавно я узнал, что Browserify имеет тенденцию создавать очень большие пакеты, которые браузеру требуется много времени для обработки из-за отсутствия встряхивания дерева. Подробнее об этом вы можете прочитать, прочитав книгу Нолана Лоусона Стоимость малых модулей.

Вооружившись этими новыми знаниями, я счел уместным попробовать Webpack для объединения.

Webpack разбит на три файла конфигурации, а не на один, они называются webpack.base.config.js, webpack.dev.config.js и webpack.prod.config.js. Конфигурация по умолчанию содержит все основные входные и выходные параметры и модули, которые я планирую использовать. Два других файла имеют специфичные для среды конфигурации. У разработки есть опция просмотра, а у производства есть плагин для минимизации. Каждая конфигурация вызывается в зависимости от среды или сценария, в котором необходимо ее использовать.

webpack.base.config.js

main: './site/theme/js/main.js'
path: './site/theme/assets/js'
configFile: './.eslintrc'

webpack.dev.config.js

var config = require('./webpack.base.config');
config.devtool = 'source-map';
config.output.sourceMapFilename = '[file].map';

webpack.prod.config.js

var webpack = require('webpack');
var config = require('./webpack.base.config');
config.plugins = (config.plugins || []).concat([
new webpack.optimize.UglifyJsPlugin({
except: ['$', 'exports', 'require']

Затем на каждый файл ссылаются в команде сценария NPM:

“build:js”: “webpack — config build/webpack.prod.config.js”,
“watch:js”: “webpack — config build/webpack.dev.config.js”

Настройка BrowserSync

Имея решения JavaScript и LESS, мне пришлось связать все это вместе с BrowserSync, чтобы во время разработки нам не приходилось постоянно обновлять наш браузер, чтобы увидеть наши изменения. Эта часть решения заняла у меня больше всего времени, потому что у меня возникли проблемы с настройкой того, как мой сервер VVV ссылается на JavaScript BrowserSync.

Существует несколько распространенных способов запуска BrowserSync: один из них — проксировать существующий сервер или настроить собственный сервер, на котором размещены активы BrowserSync. Я выбрал позднее.

Первое, что я сделал, это сгенерировал базовый файл конфигурации для BrowserSync, запустив browser-sync init.

Если вы затем запустите BrowserSync без указания прокси в конфигурации, вы получите сообщение, похожее на это:

<script id="__bs_script__">//<![CDATA[
document.write("<script async src='http://HOST:3000/browser-sync/browser-sync-client.js?v=2.16.0'><\/script>".replace("HOST", location.hostname));
//]]></script>

Проблема, с которой я столкнулся, заключается в том, что когда это было добавлено на мой сайт, оно заменяло имя хоста моим URL-адресом разработчика, а затем искало клиентский JavaScript в моей файловой системе в VVV. Я мог бы разместить его там, но тогда, когда я внес изменения в конфигурацию, мне пришлось бы повторно копировать код и обновлять свою локальную копию. Это было далеко не идеально. Чтобы решить эту проблему, я внес пару изменений в конфигурацию BrowserSync.

В моих файлах темы я обновил приведенный выше скрипт следующим образом:

<?php if ( $_SERVER['HTTP_HOST'] == 'local.dev'):?>
<script id="__bs_script__">//<![CDATA[
document.write("<script async src='http://localhost:3000/browser-sync/browser-sync-client.js?v=2.16.0'><\/script>");
//]]></script>
<?php endif; ?>

Теперь это загружает BrowserSync с локального хоста и загружает скрипт только тогда, когда я запускаю сайт в локальной разработке. (Я признаю, что, вероятно, есть более элегантное решение, но оно работает.)

Затем мне также пришлось обновить конфигурацию сокета для BrowserSync, чтобы она указывала на localhost:3000. Это делается в параметре сокета конфигурационного файла, который был сгенерирован выше. Недвижимость называется domain.

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

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

часы-browsersync.js

'use strict';
var bs = require('browser-sync').create('VVV Server');
var BS_CONFIG = require('./bs-config');
bs.watch('./site/theme/**/*.less', function(event, file) {
if (event === 'change') {
console.log('\x1b[36m%s\x1b[0m', 'Less changed: \x1b[35m' + file + '\x1b[0m');
}
});
bs.watch('./site/theme/assets/css/bundle.css', function(event) {
if (event === 'change') {
    bs.reload('style.css'); // stream endpoint
}
});
bs.watch('./site/theme/assets/js/*.js', function(event) {
if (event === 'change') {
    bs.reload();
}
});
bs.watch('./site/theme/**/*.php', function(event) {
if (event === 'change') {
   bs.reload();
}
});
bs.init(BS_CONFIG);

Если мне нужно добавить больше функциональности в то, как работает BrowserSync, этот скрипт позволяет это сделать.

Окончательные сценарии

Со всеми вышеперечисленными частями окончательный пакет скриптов в итоге выглядел так:

“build”: “concurrently — raw ‘npm run build:css’ ‘npm run build:js’”,
“build:css”: “lessc -x site/theme/less/main.less site/theme/assets/css/bundle.css”,
“build:js”: “webpack — config build/webpack.prod.config.js”,
“dev”: “concurrently — raw ‘npm run watch:css’ ‘npm run watch:js’ ‘npm run watch’”,
“lint”: “eslint site/theme/js”,
“watch”: “node ./build/browser-sync.js”,
“watch:css”: “nodemon -q -e less -x lessc — source-map-map-inline site/theme/less/main.less site/theme/assets/css/bundle.css”,
“watch:js”: “webpack — config build/webpack.dev.config.js”

Вывод

Я был очень доволен этой конфигурацией, потому что она казалась минимальной и не требовала написания большого количества скриптов в Gulp или настройки в Grunt. Кроме того, при использовании сценариев NPM разработчику не нужно будет устанавливать LESS, Webpack или любой другой инструмент, установленный глобально, для запуска инструментов разработки проекта.

Первоначально опубликовано на сайте gautsch.codes 22 сентября 2016 г.