Дружим 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
Вот собственно и все. Теперь можно облегчить себе жизнь при разработки новой темы и воспользоваться всеми современными возможностями. Есть вопросы ? Задавайте их в комментариях.