I got the method I’ll describe below from Krasen Slavov, who shared it on his blog wprotary.com back in December ’21, and I’ve been using it for my WordPress plugins ever since.
If you require anything more complicated with eslint, stylelint, and PHP standards, I recommend using Composer + nodeJS, or looking into Gulp.
Requirements
Both need to have a SET_PATH to the executable files added into your global system environment paths.
If you are using XAMPP then you probably have the above two already set up and can move on to the next step.
Structure
assets |-- build |---|-- css |---|-- js |-- css |-- js |-- scss
Development Setup
An example file structure for the JS files, that are located in assets/js
init.js | module loader script (used for development only) |
utils.mjs | methods shared between the modules |
module1.mjs | set of methods and actions for module 1 |
module2.mjs | set of methods and actions for module 2 |
module3.mjs | set of methods and actions for module 3 |
For development, I use Ajax to load all the files:
var UUID = UUID || {};
var $ = jQuery || {};
UUID.pluginURL = 'https://domain.com/';
UUID.loadModules = function ()
{
if (this.pluginURL) {
var jsURL = this.pluginURL + 'assets/js/';
this.require(jsURL + 'utils.mjs');
this.require(jsURL + 'module1.mjs');
this.require(jsURL + 'module2.mjs');
this.require(jsURL + 'module3.mjs');
} else {
throw new Error('Base URL is not defined!');
}
};
UUID.require = function (script)
{
$.ajax({
url: script,
dataType: 'script',
async: true,
success: function () {},
error: function () {
throw new Error('Could not load script ' + script);
}
});
};
(function ($, undefined) {
UUID.loadModules();
})(jQuery);
To generate the development mode CSS files inside assets/css
I run a --watch
option for Dart-Sass, this will save and update the CSS contents every time you make changes to your SCSS files.
sass --watch uuid.scss ../css/uuid.css
For SCSS I have one main file with modules imported inside, files are added into assets/scss
_variables.scss |
_base.scss |
_typo.scss |
_container.scss |
uuid.scss |
The main SCSS file:
@import 'variables'; @import 'base'; @import 'typo'; @import 'container';
Production Setup
For building the JS and CSS production files I use 2 PHP scripts:
run.php
<?php
ob_start();
include 'utils.mjs';
include 'module1.mjs';
include 'module2.mjs';
include 'module3.mjs';
$data = ob_get_clean();
$expressions = array(
'MULTILINE_COMMENT' => '\Q/*\E[\s\S]+?\Q*/\E',
'SINGLELINE_COMMENT' => '(?:http|ftp)s?://(*SKIP)(*FAIL)|//.+',
'WHITESPACE' => '^\s+|\R\s*'
);
foreach ($expressions as $key => $expr) {
$data = preg_replace('~' . $expr . '~m', '', $data);
}
echo $data;
build.php
<?php
exec('php ../js/run.php > js/uuid.min.js');
exec('sass ../scss/uuid.scss css/uuid.min.css --style compressed');
Now every time you want to generate new production files into your build/css
and build/js
directories just run php build.php
At the end your file and directory structure should look something like this:
assets |-- build |---|-- css |---|---|-- uuid.min.css |---|-- js |---|---|-- uuid.min.js |-- css |---|-- uuid.css |-- js |---|-- init.mjs |---|-- utils.mjs |---|-- module1.mjs |---|-- module2.mjs |---|-- module3.mjs |-- scss |---|-- _variables.scss |---|-- _base.scss |---|-- _typo.scss |---|-- _container.scss |---|-- uuid.scss
Loading Dev/Prod Files
To switch between development and production you need to have a boolean variable in your WordPress theme or plugin which will be used to load these files.
<?php
define('DEV_MODE', true);
if (DEV_MODE) {
wp_register_script('unique_name', get_template_directory_uri() . 'assets/js/init.js', array('jquery'), '1.0', true);
wp_register_style('unique_name', get_template_directory_uri() . 'assets/css/uuid.css', array(), '1.0', 'all');
} else {
wp_register_script('unique_name', get_template_directory_uri() . 'build/js/uuid.min.js', array('jquery'), '1.0', true);
wp_register_style('unique_name', get_template_directory_uri() . 'build/css/uuid.min.css', array(), '1.0', 'all');
}
By going to DevTools and looking at Network > Fetch/XHR you can easily identify that you running in development mode if all the modules are loading there.