Refactoring for Distribution: Preparing WordPress Plugins for Production
Learn how to refactor your WordPress plugin for production by removing dead code, modularizing assets, and finalizing your build configuration for distribution.
Previously in this course, we covered Versioning and Release Management to establish a baseline for tracking our plugin's maturity. Now that we have a stable versioning strategy, we must turn our attention to the physical state of the repository. Shipping a codebase that includes test suites, documentation source files, and development-only configuration leads to bloated downloads and potential security risks.
Refactoring for production is about narrowing the scope of your distribution to the absolute minimum required for the plugin to function in the wild.
The Principle of "Distributable Minimum"
When you package your plugin, you are creating a contract with the end-user: only ship the code that executes. Everything else—Docker configs, phpunit.xml, .git directories, and unminified source maps—is overhead.
To achieve this, we treat our distribution process as a destructive, one-way transformation. We don't "clean" the development folder; we copy the necessary files into a temporary dist/ directory, perform final optimizations, and zip that directory.
Modularizing Production Assets
As we discussed in Modern Build Tooling with Vite, your frontend assets should already be transpiled. However, production modularity goes deeper. You must ensure that your PHP autoloader and dependency graph do not pull in development-only packages.
If you are using Composer, your composer.json likely contains require-dev dependencies like phpunit/phpunit or wp-cli/wp-cli. When preparing for distribution, you must run:
Bashcomposer install --no-dev --optimize-autoloader
This command ensures that only production-essential dependencies are present in the vendor/ directory and that the class map is optimized for high-performance lookups.
Finalizing Build Configuration
A robust production build requires a "clean-room" approach. We will add a build.sh script to our project root that handles the orchestration of these tasks.
Bash#!/bin/bash # build.sh - Finalizing the Knowledge Base plugin for distribution # 1. Clean the previous build rm -rf dist/ mkdir dist/ # 2. Copy production-ready files rsync -av --exclude-from='.distignore' . dist/ # 3. Optimize dependencies cd dist/ composer install --no-dev --optimize-autoloader --no-interaction # 4. Finalize assets (assuming Vite) npm install npm run build echo "Build complete in ./dist"
The key here is the .distignore file. Much like .gitignore, this file defines exactly what stays out of your ZIP package.
The .distignore Schema
Create a .distignore file in your root to keep your distribution lightweight:
TEXT.git .github .vscode tests/ phpunit.xml composer.json composer.lock package.json package-lock.json vite.config.js tailwind.config.js src/
Note: If you are shipping your source files for transparency, you might include src/, but for a commercial plugin, you typically only ship the compiled dist/ or assets/ and the transpiled PHP classes.
Hands-on Exercise: The Production Audit
- Identify Dead Code: Use a tool like
phpstanor simply search your codebase forvar_dump,error_log, andprint_rstatements. Remove these entirely, or wrap them in a constant check:PHPif ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { error_log( 'Debug info' ); } - Verify Asset Minification: Ensure your Vite configuration is set to
minify: truein yourvite.config.js. - Execute the Build: Create your
.distignorefile and run a test build. Usels -lhto check the size of your generated ZIP file. If it's over a few megabytes, investigate which folders are sneaking into the package.
Common Pitfalls
- Including
node_modules: This is the #1 cause of bloated plugins. Ensurenode_modulesis explicitly ignored in your.distignoreand never copied into the build folder. - Hardcoded Development Paths: If your code references absolute paths like
/Users/dev/project/..., it will break on production servers. Always useplugin_dir_path( __FILE__ ). - Forgetting Source Maps: While useful for debugging, source maps (the
.mapfiles generated by Vite) expose your original source code. For production, consider disabling them in your build config to protect your intellectual property.
Recap
Refactoring for production is the final gatekeeper of quality. By utilizing an automated build script and a strict .distignore file, you ensure that your plugin is secure, performant, and free of the "cruft" that accumulates during development. As we've explored in Production Build Pipeline for WordPress Plugins, consistency in this process is what separates a hobbyist plugin from a professional-grade product.
Up next: We will tackle Plugin Lifecycle Management, focusing on robust uninstall scripts to ensure that when a user deletes your plugin, they aren't left with orphaned database tables or stale options.
Work with me

Custom WordPress Plugin Development
Custom WordPress & WooCommerce plugins built to standard — by the developer behind a plugin with 5,000+ active installs and a SaaS with 10,000+ users.

Custom WordPress Theme Development
A custom WordPress theme built exactly to your design — fast, clean, and easy to manage. No bloated page builders, no compromises.