Asset Building using Webpack & Babel

Modern WordPress development often separates source code (ES6+, SCSS, modules) from production-ready assets (minified JS/CSS). Tools like Webpack and Babel enable this workflow.

Key Concepts

  • Module Bundling: Combines multiple JavaScript files into a single optimized bundle.

  • Transpilation: Converts modern JavaScript (ES6+) into backward-compatible versions.

  • Tree Shaking: Removes unused code from final bundles.

  • Loaders & Plugins: Extend Webpack functionality (e.g., handling CSS, images).

Typical Project Structure

theme/
├── src/
│   ├── js/
│   │   └── index.js
│   ├── scss/
│   │   └── style.scss
├── dist/
│   ├── bundle.js
│   └── style.css
├── webpack.config.js
├── package.json

Webpack Configuration Example

const path = require('path');

module.exports = {
  entry: './src/js/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js',
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
        },
      },
      {
        test: /\.scss$/,
        use: ['style-loader', 'css-loader', 'sass-loader'],
      },
    ],
  },
  mode: 'production',
};

Babel Configuration (.babelrc)

{
  "presets": ["@babel/preset-env"]
}

Enqueuing Compiled Assets in WordPress

function theme_enqueue_assets() {
    wp_enqueue_script(
        'theme-bundle',
        get_template_directory_uri() . '/dist/bundle.js',
        array(),
        '1.0',
        true
    );

    wp_enqueue_style(
        'theme-style',
        get_template_directory_uri() . '/dist/style.css',
        array(),
        '1.0'
    );
}
add_action('wp_enqueue_scripts', 'theme_enqueue_assets');

Internal Mechanics

Understanding WordPress internals is essential for extending functionality and debugging.

Core Architecture

  • Core: Base system files (do not modify directly).

  • Themes: Control presentation layer.

  • Plugins: Extend functionality.

  • Database: Stores content, settings, metadata.

Execution Flow

  1. Request hits index.php

  2. Loads wp-blog-header.php

  3. Initializes WordPress environment

  4. Queries database

  5. Loads template hierarchy

  6. Outputs HTML

Hooks System

WordPress uses an event-driven architecture via hooks:

  • Actions: Execute functions at specific points

  • Filters: Modify data before output

Action Example
function add_custom_footer_text() {
    echo '<p>Custom Footer</p>';
}
add_action('wp_footer', 'add_custom_footer_text');
Filter Example
function modify_excerpt_length($length) {
    return 20;
}
add_filter('excerpt_length', 'modify_excerpt_length');

Template Hierarchy

Determines which template file is used:

  • single.php → single posts

  • page.php → static pages

  • archive.php → archives

  • index.php → fallback

The Loop

Core mechanism for displaying posts:

if (have_posts()) :
    while (have_posts()) : the_post();
        the_title();
        the_content();
    endwhile;
endif;

Accessibility (WCAG 2.2)

Web Content Accessibility Guidelines 2.2 define how to make web content accessible to users with disabilities.

Core Principles (POUR)

  • Perceivable: Content must be visible/audible

  • Operable: Interface usable via keyboard

  • Understandable: Content must be clear

  • Robust: Compatible with assistive technologies

Semantic HTML

Use proper elements instead of generic containers:

<header>
  <nav>
    <ul>
      <li><a href="/">Home</a></li>
    </ul>
  </nav>
</header>

ARIA Roles and Attributes

Enhance accessibility when semantics are insufficient:

<button aria-expanded="false" aria-controls="menu">
  Toggle Menu
</button>

<div id="menu" hidden>
  <!-- menu items -->
</div>

Keyboard Accessibility

Ensure all interactive elements are keyboard operable:

document.addEventListener('keydown', (e) => {
  if (e.key === 'Escape') {
    closeModal();
  }
});

Color Contrast

  • Minimum contrast ratio:

    • Normal text: 4.5:1

    • Large text: 3:1

Accessible Forms

<label for="email">Email Address</label>
<input type="email" id="email" name="email" required>

<span id="emailHelp">We'll never share your email.</span>

WordPress-Specific Accessibility Practices

  • Use wp_nav_menu() with proper fallback

  • Add screen-reader-text classes

  • Ensure themes follow accessibility-ready guidelines

  • Use alt attributes for all images

the_post_thumbnail('full', array(
    'alt' => get_the_title()
));

Testing Tools

  • Browser DevTools accessibility panel

  • Screen readers (e.g., NVDA, VoiceOver)

  • Automated tools (Lighthouse, axe)