How to setup JS and CSS environment files for WordPress plugin development

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.


1. PHP
2. Dart-SASS

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.


assets
|-- build
|---|-- css
|---|-- js
|-- css
|-- js
|-- scss

An example file structure for the JS files, that are located in assets/js 

init.jsmodule loader script (used for development only)
utils.mjsmethods shared between the modules
module1.mjsset of methods and actions for module 1
module2.mjsset of methods and actions for module 2
module3.mjsset 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';

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

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.


Was this post helpful?

Leave a Comment