Build and distribution

Since Wordless uses Webpack, we have to manage build and distribution strategies for dev and staging/production.

The source asset code is placed in src/{javascripts|stylesheets|images}, while built/optimized code is placed - automatically by Webpack - in dist/{javascripts|stylesheets|images}

We offer standard approaches for both environments. They are handled - as expected - through package.json ‘s scripts [1]:

  "scripts": {
    "server": "npx nf start",
    "build:dev": "webpack --debug --env.NODE_ENV=development",
    "build:prod": "yarn sign-release && webpack -p --bail --env.NODE_ENV=production",
    "clean:js": "rimraf dist/javascripts/*",
    "clean:css": "rimraf dist/stylesheets/*",
    "clean:images": "rimraf dist/images/*",
    "clean:dist": "yarn clean:js && yarn clean:css && yarn clean:images",
    "sign-release": "git rev-parse HEAD | cut -c 1-8 > release.txt",
    "lint": "yarn lint:sass",
    "lint:sass": "npx stylelint --report-needless-disables 'src/stylesheets/**/*.sass' && npx stylelint 'src/stylesheets/**/*.sass'"

It is expected - but it’s still up to you - that before every build you will clean the compiled files. yarn clean:dist will do the cleanup.

Build for development

yarn clean:dist && yarn build:dev


Most of the time you’ll be working using the built-in development server through yarn server, but invoking a build arbitrarily is often useful.

Build for production

yarn clean:dist && yarn build:prod

Production build will essentially:

  • enable Webpack’s production mode
  • do not produce source maps for CSS
  • do minimize assets


By default the production build will produce source-maps for JS; this is done to lower the debugging effort, to respect the readability of the source code in users’ browser and to simplify the shipping of source-maps to error monitoring softwares such as Sentry.

You can easily disable this behaviour setting devtool: false in inside the prodOptions object.

Release signature

You notice that build:prod script will invoke sign-release too. The latter will write the SHA of the current GiT commit into the release.txt file in the root of the theme.

You can easily disable this behaviour if you’d like to.

release.txt is implemented to have a reference of the code version deployed in production and to integrate external services that should requires release versioning (for us in Sentry).

Code linting

Wordless ships with preconfigured linting of SASS (indented syntax) using Stylelint.

It is configured in .stylelintrc.json, you can add exclusion in .stylelintignore; all is really standard.

The script yarn lint is preconfigured to run the the lint tasks.


Code linting could be chained in a build script, e.g.:


Code linting could be integrated inside a Wordmove hook


You can force linting on a pre-commit basis integrating Husky in your workflow.

PHUG optimizer

When performance is a must, PHUG ships a built-in Optimizer. You can read about it in the phug documentation:

The Optimizer is a tool that avoids loading the Phug engine if a file is available in the cache. On the other hand, it does not allow to change the adapter or user post-render events.

Wordless supports enabling this important optimization by setting an environment variable (in any way your system supports it) or a global constant to be defined in wp-config.php. Let’s see this Wordless internal code snippet:

                if ($this->ensure_dir($tmp_dir)) {
                    if ( getenv('ENVIRONMENT') ) {
                        $env = getenv('ENVIRONMENT');
                    } elseif ( defined('ENVIRONMENT') ) {
                        $env = ENVIRONMENT;
                    } else {
                        $env = 'development';

                    if ( in_array( $env, array('staging', 'production') ) ) {
                            'displayFile', [$template_path, $locals], WordlessPugOptions::get_options()
                    } else {
                        $pug = new Pug(WordlessPugOptions::get_options());
                        $pug->displayFile($template_path, $locals);

where we search for ENVIRONMENT and thus we’ll activate PHUG’s Optimizer if the value is either production or staging.


Arbitrary values are not supported.

The simplest approach is to to define a constant inside wp-config.php.

:caption: wp-config.php

define('ENVIRONMENT', 'production');


Wordless is agnostic about the deploy strategy. Our favourite product for deploying WordPress is Wordmove.