Rollup is a powerful JavaScript module bundler that’s particularly well-suited for WordPress theme development. This guide covers everything you need to know about setting up and troubleshooting Rollup in a WordPress theme context.

Basic Setup

Required Dependencies

First, install the necessary packages:

bashCopynpm install --save-dev rollup @rollup/plugin-commonjs @rollup/plugin-node-resolve @rollup/plugin-babel @rollup/plugin-replace @rollup/plugin-terser rollup-plugin-postcss autoprefixer cssnano sass

Project Structure

A typical WordPress theme with Rollup should look like this:

Copyyour-theme/
  ├── rollup.config.js
  ├── assets/
  │   ├── js/
  │   │   └── index.js
  │   └── scss/
  │       └── main.scss
  ├── dist/
  │   ├── main.min.js
  │   └── main.min.css
  └── package.json

Basic Configuration

Here’s a basic Rollup configuration that handles both JavaScript and SCSS:

javascriptCopyimport commonjs from '@rollup/plugin-commonjs';
import resolve from '@rollup/plugin-node-resolve';
import babel from '@rollup/plugin-babel';
import replace from '@rollup/plugin-replace';
import terser from '@rollup/plugin-terser';
import postcss from 'rollup-plugin-postcss';
import autoprefixer from 'autoprefixer';
import cssnano from 'cssnano';

export default {
  input: 'assets/js/index.js',
  output: {
    file: 'dist/main.min.js',
    format: 'iife',
    sourcemap: true
  },
  plugins: [
    postcss({
      extensions: ['.scss', '.css'],
      plugins: [autoprefixer(), cssnano()],
      extract: 'dist/main.min.css',
      minimize: true,
      sourceMap: true,
      use: ['sass']
    }),
    resolve({
      browser: true
    }),
    commonjs(),
    babel({
      babelHelpers: 'bundled',
      exclude: 'node_modules/**'
    }),
    replace({
      'process.env.NODE_ENV': JSON.stringify('production'),
      preventAssignment: true
    }),
    terser()
  ]
};

Advanced Configuration

For more complex needs, you might want to separate your JS and CSS configurations:

javascriptCopyconst jsConfig = {
  input: 'assets/js/index.js',
  output: {
    file: 'dist/main.min.js',
    format: 'iife',
    sourcemap: true,
  },
  plugins: [/* ... */]
};

const cssConfig = {
  input: 'assets/scss/main.scss',
  output: {
    file: 'dist/main.min.css.js',
    format: 'es',
  },
  plugins: [/* ... */]
};

export default [jsConfig, cssConfig];

Common Issues and Solutions

1. JSON Import Issues

If you’re getting JSON import errors, install and add the JSON plugin:

bashCopynpm install --save-dev @rollup/plugin-json

Then add to your config:

javascriptCopyimport json from '@rollup/plugin-json';
// ...
plugins: [
  json(),
  // other plugins...
]

2. SASS Import Problems

If you’re encountering SASS import issues:

  • Make sure sass is installed: npm install --save-dev sass
  • Use the correct postcss configuration:
javascriptCopypostcss({
  use: ['sass'],
  extensions: ['.scss', '.css']
})

3. Path Issues

When working with WordPress themes, pay attention to your output paths:

javascriptCopy// In rollup.config.js
output: {
  file: 'dist/main.min.js'  // This path is relative to your rollup.config.js location
}

// In your PHP file
$css_file = get_template_directory() . '/dist/main.min.css';  // Make sure these paths match

Best Practices

1. Development vs Production

Use environment variables to handle different environments:

javascriptCopyconst isProduction = process.env.NODE_ENV === 'production';

export default {
  // ...
  plugins: [
    // ...
    isProduction && terser()
  ].filter(Boolean)
};

2. Source Maps

Always include source maps during development:

javascriptCopyoutput: {
  sourcemap: !isProduction
}

3. Error Handling

Add warning handlers for cleaner output:

javascriptCopyonwarn: (warning, warn) => {
  if (warning.code === 'CIRCULAR_DEPENDENCY') return;
  warn(warning);
}

Integrating with WordPress

1. Enqueuing Scripts and Styles

In your theme’s functions.php:

phpCopyfunction theme_enqueue_assets() {
    $js_file = get_template_directory() . '/dist/main.min.js';
    $css_file = get_template_directory() . '/dist/main.min.css';

    if (file_exists($js_file)) {
        wp_enqueue_script(
            'theme-scripts',
            get_template_directory_uri() . '/dist/main.min.js',
            [],
            filemtime($js_file),
            true
        );
    }

    if (file_exists($css_file)) {
        wp_enqueue_style(
            'theme-styles',
            get_template_directory_uri() . '/dist/main.min.css',
            [],
            filemtime($css_file)
        );
    }
}
add_action('wp_enqueue_scripts', 'theme_enqueue_assets');

2. NPM Scripts

Add these to your package.json:

jsonCopy{
  "scripts": {
    "build": "rollup -c",
    "watch": "rollup -c -w",
    "dev": "rollup -c --environment NODE_ENV:development",
    "prod": "rollup -c --environment NODE_ENV:production"
  }
}

Troubleshooting Tips

  1. Clear Build Directory: Before each build, consider clearing your dist directory
  2. Check File Paths: Ensure your input and output paths are correct
  3. Module Resolution: Use the browser option in resolve plugin for frontend code
  4. Dependencies: Keep your package.json and package-lock.json in sync
  5. Cache Issues: Clear node_modules and package-lock.json if you encounter persistent issues

Conclusion

Rollup is a powerful tool for WordPress theme development when configured correctly. The key is to start with a basic configuration and gradually add complexity as needed. Remember to keep your development environment consistent and your paths properly aligned with your WordPress theme structure.

Remember that while this guide covers most common scenarios, your specific needs might require additional configuration. Always consult the official Rollup documentation for the most up-to-date information.