This guide is written from the perspective of a senior engineer who is relatively new to the WooCommerce Monorepo codebase. In my recent work, I focused on enhancing the email experience for both merchants and customers. This included adding an email preview feature, modernizing the email design, and introducing theme-based email settings to improve flexibility and customization.
Development environment
I began by following Woo Monorepo’s Getting Started guide’s important basic instructions:
- Check out the repo.
- Ensure you have all prerequisites installed.
nvm install
pnpm install
pnpm build
Now, you are ready to start developing any of the monorepo packages or plugins. From here on, I’ll only reference the Core WooCommerce plugin located in /plugins/woocommerce, as I mainly worked there, but the process is very similar in other monorepo plugins.
pnpm
The way pnpm
can be used, is that you can call commands both from the monorepo root, but also from the specific plugin directory. To call pnpm commands for the WooCommerce Core plugin from the root, you’ll use --filter='@woocommerce/plugin-woocommerce'
argument.
For example, running these two from the root will have the same result:
cd plugins/woocommerce && pnpm [COMMAND]
pnpm --filter='@woocommerce/plugin-woocommerce' [COMMAND]
The second one has the added benefit that it will also work from the plugin’s directory, so consider always use --filter
which should work consistently. You can also check out the list of shortcuts for pnpm.
wp-env
WooCommerce Core comes with wp-env, WordPress’ local development environment tool. You can run it with by usin pnpm --filter='@woocommerce/plugin-woocommerce' env:dev
and start developing at http://localhost:8888/. You can also check out the list of shortcuts for wp-env.
Working with the codebase
There are a lot of files, and there are legacy ways to do things (which, ideally, you shouldn’t use) and current ways. I won’t go into too much detail, as it depends on what you are building, but here are two good-to-know things:
- PHP classes
- includes/ – contains legacy code. You shouldn’t create new classes here, but it’s okay to fix bugs. You can read more here.
- src/ – home to new WooCommerce class files under the
Automattic\WooCommerce
namespace using PSR-4 file naming with autoloading. You’ll most likely work here.- ⚠️ Any direct children directories should be considered final, backwards compatible, and available for 3rd-party developers to interact with.
- If you have work-in-progress classes or something likely to change, you should put it in the Internal folder (with
Automattic\WooCommerce\Internal
namespace), where backward compatibility is not guaranteed. This is where we added email improvement classes, including REST endpoints.
- JS files
- client/legacy/ – good old jQuery files. Again, nothing new should go here.
- client/admin/client/ – a place for new React components (in TypeScript). You’ll most likely work here. This is where we have added email improvements.
WooCommerce Blocks
One thing to be aware of with Blocks is that currently, the front-end (JS and CSS) lives in its own plugin in plugins/woocommerce-blocks/
while the server-side counterpart for each block is still in plugins/woocommerce/
.
Writing code
Taken from the PR template, you should follow the WooCommerce Contributing Guidelines and the WordPress Coding Standards and review your code for security best practices.
Watching changes
pnpm --filter=@woocommerce/plugin-woocommerce watch:build
should do the trick. This command will build, watch for changes, and compile them. The initial run will take some time to get to the “watching” state. Now you are ready to make changes in TypeScript or SCSS files (and many others), and they’ll be automatically compiled in real-time.
Linting PHP
There are two useful commands:
pnpm --filter=@woocommerce/plugin-woocommerce lint:php:changes
- checks unstaged changes
pnpm --filter=@woocommerce/plugin-woocommerce lint:php:changes:branch
- checks all committed changes in the current branch
💡 In my flow, whenever I commit a change in PHP files, I run the first command to ensure code styles, security, and best practices are respected.
Linting JS
For JS, your IDE should automatically show ESLint errors.
There are linters and checkers, but I don’t find these helpful, as they check the whole codebase and show unrelated errors to your changes, so I rely on my IDE.
Pre-commit hooks
There are none. You can commit just about anything, but GitHub actions will eventually stop you.
Slotfills
Sometimes, you need to place a React component at a specific location in the PHP code. For that, you can register a slotfill. Here is an example used in the email preview.
Running tests
End-to-end tests
To run an end-to-end test, run pnpm --filter=@woocommerce/plugin-woocommerce test:e2e ./tests/e2e-pw/[path/to/test.js]
E2e tests rely on proper environment setup. If, for any reason, your e2e tests fail to start, try running pnpm --filter=@woocommerce/plugin-woocommerce env:restart
, which resets your local environment as well as the one used in e2e tests.
Unit tests
To run unit tests on a single file, run pnpm --filter=@woocommerce/plugin-woocommerce test:unit:env -- --filter=[YourTestClassName]
. Tests live in tests/php/ and follow the same structure as the classes they are testing.
Pull Requests
The PR template explains most of the stuff, but here are a couple of specifics:
Running actions
GitHub actions are only run for PRs, not for all commits. So, if you want to get your branch fully tested on GitHub, you must at least create a draft PR.
Changelog
Every PR requires a changelog. You can add it by runningpnpm --filter=@woocommerce/plugin-woocommerce changelog add
.
Alternatively, you can specify the changelog data (significance, type, and message) in the PR template, which will auto-generate the changelog for you.
I prefer using the command, as I find it easier to generate via command line than writing the fields out in the PR template. If you do use a command, you can remove the “Changelog” section from the PR description.
Template @version
Whenever you change a template, you should also bump it’s @version. There is also a GitHub action which checks for this in PRs.
Beyond setting up
As you dive into WooCommerce development, remember, you’re not alone.
Join our community on Slack – Connect with fellow developers, share ideas, and ask questions.
Engage in regular Office Hours – It’s the perfect place to learn, get advice, and stay up to date.
Stay connected, share your insights, and let’s continue building WooCommerce together.
Leave a Reply