Изучаем Gutenberg — 6 часть — Настраиваем webpack

Gutenberg приносит современный стек JavaScript в экосистему WordPress, что означает, что необходимо изучить некоторые новые инструменты. Хотя такие инструменты, как create-guten-block, невероятно полезны, также полезно знать, что происходит под капотом.

Файлы, которые мы будем настраивать, должны быть знакомы из части 3 create-guten-block.

Начало работы

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

Мы собираемся следить за изменениями в некоторых пользовательских файлах блоков и компилировать их с помощью Babel для создания файлов JavaScript, которые могут быть прочитаны большинством браузеров. Это также объединит любые зависимости, которые мы импортируем. Но сначала нам нужно место для хранения фактических настроек webpack и внешних файлов. В третьей части, когда мы разбирались с файлами, сгенерированными create-guten-block, мы увидели, что он создал инфраструктуру для плагина WordPress.

Настройка плагина

В локальной установке WordPress перейдите d папку wp-content/pluginsи создайте новую папку с именем card-block.

Затем внутри card-blockсоздайте файл с именем card-block.php. Это будет эквивалент plugin.phpиз create-guten-block. Затем добавьте этот блок комментариев, чтобы WordPress признал этот каталог плагином и отобразил его на странице плагинов панели инструментов:

<?php
   /*
   Plugin Name: Card Block
   */

WordPress ищет эти комментарии, чтобы зарегистрировать плагин так же, как он ищет комментарии вверху style.css в теме. Это сокращенная версия того, что вы найдете в верхней части основных файлов других плагинов. Если вы планируете выпустить его в хранилище плагинов WordPress, вам нужно добавить описание и номер версии, а также информацию о лицензии и авторе. Активируйте плагин через панель управления WordPress.

Начало работы с webpack

Первое, что нам нужно сделать, это инициализировать npm . Запустите команду в корне вашей папки плагина ( wp-content/plugins/card-block):

npm init

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

Далее установим webpack:

npm install webpack --save-dev

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

Затем запустите это:

npm install extract-text-webpack-plugin@next --save-dev

И зависимости Sass и CSS:

npm install node-sass sass-loader css-loader --save-dev

Теперь NPX позволяет нам использовать наши локальные зависимости вместо глобальных:

npm install npx -g

Наконец, запустите это:

npm install webpack-cli --save-dev

Это установит интерфейс командной строки

Теперь, когда мы все это установили, мы должны создать конфигурационный файл. В корне вашего плагина создайте файл webpack.config.jsи откройте его.

С этим файлом webpack мы будем работать с традиционным кодом ES5 для максимальной совместимости, потому что он работает с Node JS. Вы можете использовать ES6 и Babel, но в этом уроке все будет максимально просто.

Давайте добавим некоторые константы и импорт. Добавьте следующее прямо вверху
файла webpack.config.js:

var ExtractText = require('extract-text-webpack-plugin');
var debug = process.env.NODE_ENV !== 'production';
var webpack = require('webpack');

Переменнаяdebug определяет режим debug. Это режим по умолчанию, но его можно переопределить, добавив команды webpack с помощью NODE_ENV=production.

Как видите, нам нужны некоторые зависимости. Давайте вместо этого сосредоточим наше внимание на ExtractText. По сути, это ExtractTextпозволяет нам включать файлы, отличные от JavaScript. Нам это понадобится для файлов Sass. По умолчанию, webpack предполагает, что все написано на JavaScript, поэтому ExtractText типа переводит другие типы файлов.

Давайте добавим немного конфигурации. Добавьте следующее после определения  webpack:

var extractEditorSCSS = new ExtractText({
  filename: './blocks.editor.build.css'
});

var extractBlockSCSS = new ExtractText({
  filename: './blocks.style.build.css'
});

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

Хорошо, после этого добавьте следующее:

var plugins = [ extractEditorSCSS, extractBlockSCSS ];

Здесь у нас есть два массива плагинов. Экземпляры ExtractText живут в наборе основных плагинов, и у нас есть пара плагинов оптимизации, которые добавляются в основной набор плагинов, только если мы не в debugрежиме. Мы используем эту логику в самом конце.

Затем добавьте объект конфигурации SCSS:

var scssConfig = {
  use: [
    {
      loader: 'css-loader'
    },
    {
      loader: 'sass-loader',
      options: {
        outputStyle: 'compressed'
      }
    }
  ]
};

Этот объект расскажет нашему экземпляру webpack, как вести себя при работе с scssфайлами.

Конфиг:

module.exports = {
  context: __dirname,
  devtool: debug ? 'inline-sourcemap' : null,
  mode: debug ? 'development' : 'production',
  entry: './blocks/src/blocks.js',
  output: {
    path: __dirname + '/blocks/dist/',
    filename: 'blocks.build.js'
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'babel-loader'
          }
        ]
      },
      {
        test: /editor\.scss$/,
        exclude: /node_modules/,
        use: extractEditorSCSS.extract(scssConfig)
      },
      {
        test: /style\.scss$/,
        exclude: /node_modules/,
        use: extractBlockSCSS.extract(scssConfig)
      }
    ]
  },
  plugins: plugins
};

Это весь наш конфиг, поэтому давайте разберемся с ним.

Скрипт начинается с module.exportsМы можем определить, что мы выставляем для того, что импортирует наш код, что означает, что мы могли бы запустить код выше module.exports, например, для выполнения некоторых сложных вычислений.

Далее, давайте посмотрим на некоторые из этих следующих свойств:

  • context— это база, где будут резолвиться пути. Мы прошли __dirname, который является текущим рабочим каталогом.
  • devtoolгде мы определяем, какую карту исходного кода мы можем или не можем хотеть. Если мы не в debugрежиме, мы передаем nullс троичным оператором.
  • entryИменно здесь мы говорим Webpack, чтобы он начал работу. В нашем случае это путь к нашему blocks.jsфайлу.
  • output Мы передаем объект, который определяет выходной путь и имя файла, который мы хотим вызвать.

Следующее: module, о чем мы поговорим подробнее. Раздел module может содержать несколько правил. В нашем случае единственное ruleчто у нас есть, это поиск файлов JavaScript и SCSS. Это делается путем поиска с помощью регулярного выражения, определенного свойством test. Конечная цель правила — найти правильный тип файлов и передать их в загрузчик, в нашем случае babel-loader. Как мы узнали из предыдущего урока этой серии, Babel — это то, что превращает наш современный код ES6 в более поддерживаемый код ES5.

Наконец, раздел плагинов. Здесь мы передаем массив экземпляров плагинов. У нас есть плагины, которые минимизируют код, удаляют дубликаты кода и один, который уменьшает длину часто используемых идентификаторов. Это все для того, чтобы наш код был оптимизирован.

Для справки, вот как должен выглядеть ваш полный конфигурационный файл:

var ExtractText = require('extract-text-webpack-plugin');
var debug = process.env.NODE_ENV !== 'production';
var webpack = require('webpack');

var extractEditorSCSS = new ExtractText({
  filename: './blocks.editor.build.css'
});

var extractBlockSCSS = new ExtractText({
  filename: './blocks.style.build.css'
});

var plugins = [extractEditorSCSS, extractBlockSCSS];

var scssConfig = {
  use: [
    {
      loader: 'css-loader'
    },
    {
      loader: 'sass-loader',
      options: {
        outputStyle: 'compressed'
      }
    }
  ]
};

module.exports = {
  context: __dirname,
  devtool: debug ? 'inline-sourcemap' : null,
  mode: debug ? 'development' : 'production',
  entry: './blocks/src/blocks.js',
  output: {
    path: __dirname + '/blocks/dist/',
    filename: 'blocks.build.js'
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'babel-loader'
          }
        ]
      },
      {
        test: /editor\.scss$/,
        exclude: /node_modules/,
        use: extractEditorSCSS.extract(scssConfig)
      },
      {
        test: /style\.scss$/,
        exclude: /node_modules/,
        use: extractBlockSCSS.extract(scssConfig)
      }
    ]
  },
  plugins: plugins
};

Регистрация нашего блока

Возвращаясь в card-block.php, нашей главной задачей сейчас является подключение файлов JavaScript и CSS, которые мы будем генерировать с WebPack. В теме мы бы сделали это с помощью wp_enqueue_scriptи wp_enqueue_style. По сути, мы делаем то же самое, за исключением того, что вместо этого мы ставим скрипты и стили в очередь с помощью функции, специфичной для блоков.

Вставьте этот код ниже вступительного комментария в card-block.php:

function my_register_gutenberg_card_block() {

  // Register our block script with WordPress
  wp_register_script(
    'gutenberg-card-block',
    plugins_url('/blocks/dist/blocks.build.js', __FILE__),
    array('wp-blocks', 'wp-element')
  );

  // Register our block's base CSS  
  wp_register_style(
    'gutenberg-card-block-style',
    plugins_url( '/blocks/dist/blocks.style.build.css', __FILE__ ),
    array( 'wp-blocks' )
  );
  
  // Register our block's editor-specific CSS
  wp_register_style(
    'gutenberg-card-block-edit-style',
    plugins_url('/blocks/dist/blocks.editor.build.css', __FILE__),
    array( 'wp-edit-blocks' )
  );  
  
  // Enqueue the script in the editor
  register_block_type('card-block/main', array(
    'editor_script' => 'gutenberg-card-block',
    'editor_style' => 'gutenberg-card-block-edit-style',
    'style' => 'gutenberg-card-block-edit-style'
  ));
}

add_action('init', 'my_register_gutenberg_card_block');

Как показывают вышеприведенные комментарии, мы сначала регистрируем наш скрипт в WordPress, используя дескриптор gutenberg-card-blockс двумя зависимостями: wp-blocksи wp-elements. Эта функция только регистрирует скрипт, но не ставит его в очередь. Мы делаем что-то подобное для редактирования и основных таблиц стилей.

Наша последняя функция register_block_type ставит в очередь. Он также дает блоку имя, card-block/mainкоторое идентифицирует этот блок как mainблок в пространстве имен card-block, а затем идентифицирует скрипт и стили, которые мы только что зарегистрировали, как основной скрипт редактора, таблицу стилей редактора и первичную таблицу стилей для блока.

Если вы знакомы с разработкой тем, вы, вероятно, использовали get_template_directory()для обработки путей к файлам такие. Для разработки плагина мы используем функцию plugins_url(), которая делает почти то же самое, только вместо конкатенации этого пути: get_template_directory() . '/script.js'plugins_url()принимает путь строки в качестве параметра и делает конкатенацию для нас. Второй параметр, _ FILE _это одна из магических констант PHP, которая соответствует полному пути к текущему файлу.

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

Запуск Babel

Babel превращает наш код ES6 в лучше поддерживаемый код ES5, поэтому нам нужно установить некоторые зависимости. В корне вашего плагина ( wp-content/plugins/card-block) выполните следующее:

npm install babel-core babel-loader babel-plugin-add-module-exports babel-plugin-transform-react-jsx babel-preset-env --save-dev

npm install --save-dev @babel/core @babel/preset-env

npm install @babel/core babel-loader babel-plugin-add-module-exports babel-plugin-transform-react-jsx @babel/preset-env --save-dev

npm install --save-dev @babel/preset-react babel-preset-minify @babel/core @babel/cli @babel/preset-en

module.exports = function (api) {
  return {
    presets: [
      [
        "@babel/preset-react",
        {
          "pragma": "wp.element.createElement"
        }
      ],
      "minify",
      "@babel/env"
    ]
  };
}

Эта большая установка добавляет все зависимости Babel. Теперь мы можем добавить файл .babelrc, который хранит для нас некоторые настройки. Это позволяет нам не повторять их снова и снова в командной строке.

В папке темы добавьте следующий файл: .babelrc.

Теперь откройте его и вставьте следующее:

{
  "presets": ["env"],
  "plugins": [
    ["transform-react-jsx", {
      "pragma": "wp.element.createElement"
    }]
  ]
}

Обновление апреля 2019 года: с Babel 7, вам, вероятно, нужно"presets": ["@babel/preset-env"],

Итак, у нас есть две вещи:

"presets": ["env"]. Он автоматически определяет, какие функции ES использовать для генерации кода ES5. Раньше нам приходилось добавлять разные пресеты для всех разных версий ES (например, ES2015), но это было упрощено.

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

Создать заглушки

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

Перейдите в каталог плагинов и создайте папку с именем blocksи внутри нее создайте две папки: одну вызываемую srcи другую вызываемую dist.

Внутри srcпапки создайте следующие файлы. Мы также добавили пути, чтобы вы разместили их в нужном месте:

  • blocks.js
  • common.scss
  • block/block.js
  • block/editor.scss
  • block/style.scss

Теперь, когда вы создали эти файлы, откройте blocks.jsи добавьте этот однострочный файл и сохраните:

import './block/block';

Хорошо, теперь мы сгенерировали минимальное количество вещей, давайте запустим webpack. Откройте свой терминал и перейдите в текущую папку плагинов — тогда мы можем запустить следующее, что запустит веб-пакет:

npx webpack

Завершение

Мы настроили webpack, Babel и WordPress, чтобы все работали как одна команда для создания пользовательского блока Gutenberg (и будущих блоков). 

1 Comment

  1. Артём12.07.2019

    «В папке темы добавьте следующий файл: .babelrc.»
    не в папку темы, а в папку плагина! Я полдня искал почему же не компилится!

    Ответить

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Scroll to top