Дружим Wordpress и Webpack
Разработку фронтенда сегодня уже тяжело представить без webpack, а все потому что он предоставляет очень удобные возможности для автоматизации многих процессов. Это очень сильно облегчает процесс разработки и само-собой ускоряет его. В этот раз, когда я решил обновить тему для своего блога, я решил попробовать использовать его возможности. Особенно мне хотелось использовать sass при создании темы и добавить postcss с autoprefixer. Ну что же, есть желание, то надо пробовать.
Поискав в Интернете — ничего толкового не нашел, поэтому решил написать свою конфигурацию. Скажу сразу — она не идеальная и возможно подойдет не всем, но с помощью огромного количества разных плагинов каждый сможет ее переделать под свои нужды.
В качестве менеджера пакетов я использую yarn. Поэтому заходим в корневую директорию (где у нас находится wordpress) и устанавливаем нужные нам пакеты. В итоге у меня получился вот такой package.json:
{
"dependencies": {
"autoprefixer": "^7.1.4",
"babel": "^6.23.0",
"babel-loader": "^7.1.2",
"babel-plugin-transform-builtin-extend": "^1.1.2",
"babel-polyfill": "^6.26.0",
"babel-preset-env": "^1.6.0",
"babili-webpack-plugin": "^0.1.2",
"copy-webpack-plugin": "^4.0.1",
"css-loader": "^0.28.7",
"cssnano": "^3.10.0",
"extract-text-webpack-plugin": "^3.0.0",
"file-loader": "^1.1.5",
"jquery": "^3.2.1",
"node-sass": "^4.5.3",
"postcss-loader": "^2.0.6",
"postcss-smart-import": "^0.7.5",
"replace-in-file-webpack-plugin": "^1.0.0",
"sass-loader": "^6.0.6",
"style-loader": "^0.18.2",
"webpack": "^3.6.0"
},
"browserslist": {
"production": [
"iOS >= 7",
"Chrome >= 38",
"Firefox >= 30",
"Explorer >= 11"
],
"development": [
"iOS >= 7",
"Chrome >= 38",
"Firefox >= 30",
"Explorer >= 11"
]
},
"scripts": {
"start": "webpack"
}
}
Если вы планируете использовать мой набор плагинов, то не забудьте воспользоваться командой yarn install для установки пакетов.
Вот такой набор минимально необходимых плагинов получился. Как вы можете заметить тут я использую postcss и указываю какие браузеры мне необходимо поддерживать. Для него нужен свой фаил конфигурации postcss.config.js, который у меня выглядит вот так:
module.exports = {
plugins: [
require('postcss-smart-import')(),
require('autoprefixer')({remove: false}),
require('cssnano')({
preset: 'default',
}),
]
};
Ну и теперь остается добавить только саму конфигурацию вебпака что бы все завелось. Содержимое конфигурационного файла webpack.config.js будет выглядеть следующим образом:
const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const ReplaceInFileWebpackPlugin = require('replace-in-file-webpack-plugin');
const webpack = require('webpack');
// Укажите название вашей темы
const THEME_NAME = 'vexell-ru';
// Директория с темами
const appPath = path.join(__dirname, `wp-content/themes/${THEME_NAME}`);
// Основной JS файл в который мы будем подключать все, что нам необходимо
const jsPath = path.join(appPath, '/assets/js/index.js');
// Директория куда будет происходить билд проекта
const outPath = path.join(appPath, '/assets/js/');
// Разделяем Sass файлы и CSS в отдельный фаил
const extractSass = new ExtractTextPlugin({
filename: '../../style.css'
});
const extractCss = new ExtractTextPlugin({
filename: '../../style.css'
});
const rules = [
// Обработка всех JS файлов с помощью Babel. Можем использовать все новые фишки ES
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['env'],
"plugins": [
["babel-plugin-transform-builtin-extend", {
globals: ["Error"]
}]
]
}
}
},
// Подгрузка обычных файлов css. Делал так вначале. Потом все перевел на sass
{
test: /\.css$/,
use: extractCss.extract([
{
loader: 'css-loader',
options: {
minimize: true
}
},
'postcss-loader'
])
},
// Обработка Sass файлов. Минифицирум, делаем постобработку
{
rules: [{
test: /\.scss$/,
use: extractSass.extract({
use: [{
loader: "css-loader",
options: {
minimize: true
}
}, {
loader: "sass-loader"
}, {
loader: 'postcss-loader'
}],
fallback: "style-loader"
})
}]
},
/* Вместо обычного копирования файлов с новом хэшем в имени
добавляем хэш как query атрибут. Использую это в стилях для картинок.
*/
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
context: 'public',
name: 'assets/images/[name].[ext]?v=[hash]',
publicPath: './',
},
},
]
}
];
const plugins = [
extractCss,
extractSass,
/*
Следующий плагин делает основную магию, которая
версионирует каждый раз фаил со стилями и JS.
Подробнее описано ниже.
*/
new ReplaceInFileWebpackPlugin([{
dir: appPath,
files: ['functions.php'],
rules: [{
search: new RegExp('\'_bld_(.*?)\'','ig'),
replace: function() {
return `'_bld_${Number(new Date())}'`
}
}]
}]),
/*
Для использования jQuery вебпаку нужно указать, что она будет глобальна
*/
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery'
})
];
module.exports = {
context: appPath,
entry: [
'babel-polyfill',
jsPath
],
resolve: {
modules: [path.resolve(__dirname), 'node_modules']
},
output: {
path: outPath,
publicPath: '/',
filename: 'build.js'
},
module: {
rules: rules
},
plugins: plugins,
watch: true,
externals: {
'jquery': 'jQuery'
}
};
Как известно, что бы подключить свои стили в wordpress необходимо воспользоваться следующим хуком:
function site_scripts() {
wp_enqueue_style('font-awesome', get_template_directory_uri() . '/assets/css/font-awesome.css', array(), '4.7.0', 'all' );
wp_enqueue_style('site-style', get_stylesheet_uri(), array(), '_bld_1507921193074' );
wp_enqueue_script('site-script', get_template_directory_uri() . '/assets/js/build.js', array('jquery'), '_bld_1507921193074', true );
wp_localize_script( 'site-script', 'screenReaderText', array(
'expand' => esc_html__( 'expand child menu'),
'collapse' => esc_html__( 'collapse child menu'),
) );
}
add_action( 'wp_enqueue_scripts', 'site_scripts' );
Поэтому в нашей конфигурации webpack при каждой новой сборки мы обновляем параметр когда произошла сборка. Replace плагин находит вхождение «_bld_» и заменяет его. Соответсвенно в вашем файле необходимо сначала будет указать версию файлов как «_bld_». Получится примерно так:
wp_enqueue_style('site-style', get_stylesheet_uri(), array(), '_bld_' );
Теперь можно запустить webpack командой yarn start — проект запустится и время сборки будет добавляться автоматически.
Основной javascript файл у меня содержит все мои необходимые скрипты
import '../css/my.scss'; import 'jquery'; import './libs/navigation'; import './libs/skip-link-focus-fix'; import './libs/custom-scripts'; import './libs/jquery.matchHeight';
Всегда разрабатываемую тему я храню в git — это очень удобно так как есть полная история что происходило (но это совсем другая история). Что бы не хранить весь wordpress в git — я там храню только выбранную тему. Для этого у меня в .gitignore вот такая конфигурация:
.idea/ node_modules/ /*.* wp-admin/ wp-includes/ wp-content/index.php wp-content/plugins wp-content/uploads wp-content/gallery wp-content/languages wp-content/ngg wp-content/themes/index.php !.gitignore !package.json !webpack.config.js !postcss.config.js !wp-config.php !yarn.lock
Вот собственно и все. Теперь можно облегчить себе жизнь при разработки новой темы и воспользоваться всеми современными возможностями. Есть вопросы ? Задавайте их в комментариях.