An experiment building a WordPress-centric React app without any build tools.
A vision for how much simpler life could be. At least, in theory. Let's find out what the real-world tradeoffs and limitations are...
- Activate the plugin
- Open a
.js
file - Make changes
- Refresh
Seriously, that's it. 🥃 🍰
You can write standard React components with ES6, ES modules, and use any of the components/packages that Gutenberg provides. The only difference is that you'll write templates with HTM instead of JSX.
You can run the same source/
scripts in production if you'd like. For smaller projects, or new-to-JS devs, that can be a great entry point.
If that's where you're at, you can rm .gitignore babel.config.js package.json package-lock.json
, and revel in how tidy your root folder is.
If want to optimize performance, or need to support older browsers, then you can use the build
step for your production files. You'll still be able to develop locally without any watch
tooling, though.
npm install
npm run build
- Deal with all the normal build tool problems 🙁 😞 😖 🥃 😩 😢 🥃 😭 😡 🥃 🤬 🥃 🥃 🥃 🥱 🛌 💤 🔁
- Once the transpiled files exist in
build/
, the plugin will automatically switch to enqueue them instead ofsource/
. That lets you easily test them before deploying to production. - Once you're done testing,
rm -rf build/*
, and thesource/
files will automatically be enqueued again.
There are two ways to import dependencies, depending on your needs and preferences.
-
Modern CDN: This method is the easiest, and avoids any need for tooling.
Skypack is a remote CDN that's designed for modern web apps. It transparently up-converts modules to ESM, splits code into cacheable modules, tailors the package to every browser request to avoid unnecessary polyfills, etc.
-
Locally bundled packages: You can also bundle packages locally if you prefer, but still much faster and more conveniently than traditional approaches.
Snowpack is used to generate bundles 10x faster than Webpack, and only when needed. You don't need to run the
watch
task, justnpm run bundle
when you add/remove a dependency. It still does tree-shaking, will automatically up-convert CommonJS modules to ESM, and has a much more ergonomic approach to package locking.
npm run watch
will add additional features, but it's not required.
- Today: PostCSS, Hot Module Reloading, and automated testing.
- Future: React Fast Refresh.
The plugin creates a wp-admin screen where it demonstrates what can be achieved without any tooling, and some optional enhancements if you do want some tooling.
Build tools are the worst part of modern JavaScript. They create a large barrier for new-to-JS devs, and are a recurring pain to set up and use regardless of experience level. They break randomly for opaque reasons, which are difficult to diagnose and fix. Even when they do work, they're slow.
They've also been increasingly unnecessary for years, but it can feel like we're still stuck with a "complexity stockholm syndrome".
If we want the vast majority of WP developers to build rich JS applications, then we need to make it as simple as possible to get started. Most folks don't work at Automattic/10up/etc, and don't have the privilege of spending hundreds of hours learning over-engineered abstractions and lengthy toolchains on top of ES6 and React, just to build a simple plugin. WordPress got to 40% of the Web in large part because it was easy for hobbyists and tinkerers to hack on their sites with very little knowledge, and then grow over time into professional developers.
Right now there's a big wall between most folks and building what they want, in the ways that we want them to build it. If we don't make it simple, the closest that most devs (and their users) will ever get to the promise of Gutenberg is blocks built in PHP.
That's not a criticism of ACF, they've done a great thing by making it simple. But if we want folks to build seamless dynamic interfaces, then we have to internalize the importance of simplicity again. Until we re-learn that lesson, we won't be able to make modern JS development in WordPress something that's accessible to everyone.
Right now this is just a proof-of-concept. Fork it and play around with it, see if it's useful in some real-world projects, etc. Give feedback by reporting bugs & feature requests, and starting discussions. What kinds of problems or limitations do you run into? What's needed to make this live up to the vision?
If we can get this approach working well for a range of small/medium-sized plugins, then we can make a proposal for Core to support it, so that everything in core/
will be provided to plugins automatically.
This paradigm is often referred to as "buildless" or "unbundled development".
- Back to Basics: A Possible Future Without JavaScript Build Tools by Andrew Duthie
- Don't Build That App! by Luke Jackson [ article | presentation ].
- A Future Without Webpack by Pika.
- Comparing the New Generation of Build Tools by Hugh Haworth
- Developing Without a Build by Lars den Bakker.
- "...but at what cost?" by Luke Jackson
- How it feels to learn JavaScript in 2016 by Jose Aguinaga, which is still relevant in 2021.