Replies: 10 comments 16 replies
-
Adding @azaozz @desrosj @hellofromtonya and @SergeyBiryukov to the CC list. I'll ponder this a little more before committing any notes to the ticket. |
Beta Was this translation helpful? Give feedback.
-
Hi @adamziel Thanks for creating this issue and starting this discussion, it's always good to reassess past decision and see whether they're still good decision for what has to come. Before doing so though, it's important that we decontextualize how the architecture of Gutenberg came to be, the history and the reasoning behind it as the issue right now seem to go directly into a "solution" by omitting a lot of context. First, it's important to note that Gutenberg has been built from the start as packages, in fact, originally it was organized as a single monolith, using folders, very close to the suggestion here. You can check old tags like here. Quickly though, some use-cases started to emerge:
This led us to the necessity of modularizing our code into semantically valid units which increased by an order of magnitude the separation of concerns in the project. You mention that it's not perfect, and I agree but I think it's decent and in fact the big issues we might have right now pre-dates the introduction of packages (block-library, editor package). I've seen a number of times that the packages force people to think where to put components, hooks, where's the right place for things. At start, people get frustrated about not being able to just put the code wherever they want and ship but that's a good thing to force people to think about the modularization and separation of concerns. In fact, with the initial folder based architecture, we were supposed to have folders with dedicated roles but people fell too easily in the trap of just mixing stuff together. (For instance using post related data in block editor specific components...)
Next, came the integration with Core, and how to move the code into Core. Packages were not the only option explored, in fact, we also tried git submodules but npm packages ended up being the best option there. Now, later third-party npm users benefited from all of these packages to build integrations in Tumblr, Drupal, Laravel and way more... There's also the merge of the Gutenberg packages with the mobile packages which I know has helped the folks working on the mobile applications a lot. I'm not entirely familiar with this area, so we'd need their input here as well. Each one of these steps were discussed in #core-js meetings between several folks, at the time these meetings were very lively and productive. RequirementsThis is to say, that any change we make here, we should be mindful of all these requirements that accumulated over time: 1- Enforced awareness and listing rules to guarantee separation of concerns (and modularity) as much as we can. Proposed solutionThe proposed solution is basically to just merge all the packages inside one using folders, so:
If I'm understand properly, we just publish a single package to npm instead of publishing multiple ones. PromisesSo now, let's analyze the proposed solution and the promises above:
There's an issue right now, which I'd call a "bootstrapping" issue, in the sense that if you want to build a block editor, you need a provider, to load blocks, to load formats, and have some providers... and these can come from several packages. Most of these are optional because they are exchangeable: you can decide to not load blocks and bring your own, bring your own formats, load shortcuts or not... You guessed it, it's not easy to bootstrap an editor. Moving to a single package though won't change anything to the fact that you still need to figure out what you need to load and what you don't need to load, the only thing that changes is that you'll do
In the current approach, we do this by marking all So basically, with the new solution, we'd have to find a way to recreate this behavior using webpack or any other bundler. I think it's probably the exact same config we have now, expect the name of the externals to change (assuming folders work as externals too which I'm not sure about and in which case we'd need to build a custom bundler plugin)
Unfortunately, I don't think this solves that at all. Here's an example. I want to introduce a new The block editor code would do something like The bundler doesn't have any knowledge that allow him to differentiate "internal" components from "public" ones, both are imported in the same way. Pros & cons
So far, for me, the only advantage that is clear is the removal of complex lerna publishing and scripts... (assuming we keep a single package of course). I also feel this is largely underestimating the effort it takes to accomplish what it is proposed. At this point at least, I feel it's a giant project for a small outcome unfortunately. The "bootstrapping" issue is a real pain point though and a less impactful and way more straightforward solution is the "proxy" package that is proposed in the alternatives above. In fact, it's an approach that has already been taken by some third-party developers including the Drupal folks that built their own "proxy" package here or the isolated block editor by a8c. An official "proxy/bootstrap" package (so a single package to import and bootstrap with settings or something like that) would be a good addition anyway. |
Beta Was this translation helpful? Give feedback.
-
Could this be moved to a discussion thread instead? I personally don't think this is worth the effort and see very few upsides (if any?), but pros and cons can be discussed more granularly there in comment threads. |
Beta Was this translation helpful? Give feedback.
-
I see this as the biggest single advantage of this proposal -- it's certainly something I've run in to in a previous role -- but I agree with @youknowriad that the separation of packages enforces an increased awareness of sound architectural decisions. As I mainly work in wordpress-develop, I have more experience as a consumer and super packages such as As long as the |
Beta Was this translation helpful? Give feedback.
-
The big benefit is that it'd be simple to update. The main reason it's complex right now is that You must update every For example, it's not uncommon for someone to add a new WP dependency to our monorepo, or to update a dep individually if they're looking for a new feature. But this pretty much always creates unexpected issues in the repo, since that new version is out of sync with the rest of the repo. And this new version would now pull along updates from all the transitive dependencies -- often including undocumented breaking changes -- making things very complex. Recently, I updated a dependency that uses WP packages, and the package manager started resolving the new versions, whereas the rest repo is somewhat out of date. (Due to updates being challenging and time-consuming.) The new versions pulled in tons of new changes, including the React 18 update, which then pulled in a lot of other transitive dependencies, like newer React 18 types. This of course created lots of issues, and I had to go in and manually enforce dependency resolution to stay at what the rest of the repository was using. All of this, just because I was bumping the version of one package which happened to use WordPress packages internally. I definitely think this problem (compatibility among package versions) needs to be better solved. One Package To Rule Them All definitely does that, but I suppose there are other ways. For example, the bi-weekly package release could get a new major version every time, and that version could be the same across all the packages. Maybe difficult to make the change at first, but that would prevent package managers from doing unexpected updates to the latest semver-compatible versions. TLDR: package versions from different releases aren't typically fully compatible with each other, but this is not enforced at any level. |
Beta Was this translation helpful? Give feedback.
-
I agree with @noahtallen that this goal could be very well achieved with another, much less drastic change: unify the versioning of all This makes upgrading the monorepo much easier, as you can quickly detect if your packages are out of sync, just by scanning the lockfile or the On the other hand, if my project depends on Additionally, we are very bad at maintaining changelogs. If you want to know what changes are there between So, the basic suggestion would be to adopt the Jest convention and release Gutenberg packages in one version line. There's also a more radical version of the suggestion: screw semver and use the same version for the Gutenberg plugin and the NPM packages. When releasing Gutenberg 14.9.2, release also the NPM packages with version 14.9.2. I'm not sure if that's even technically possible, but as a consumer, I would love to see it. |
Beta Was this translation helpful? Give feedback.
-
Hi, folks! Thanks for doing the hard work of figuring out what to do here. I don't have much opinion about which direction should be taken, but I wanted to let you know the current situation has been quite painful for us on the Day One Web team as consumers of @WordPress packages. Specifically, package version mismatches have wasted hours of developer debugging time. We'd vote for any way to better know what versions to install when upgrading packages so we don't get multiple copies of dependencies that cause subtle logical bugs (like using two different copies of |
Beta Was this translation helpful? Give feedback.
-
Continuing from #49140 I am also experiencing similar issues with the current versioning scheme. Of the options I like @jsnajdr's suggestion of unified versioning the best. It's simple, at a glance block authors can see what version of Gutenberg they are targeting. Thank you @gziolo for pointing out I can see how this isn't an important issue outside of the monorepo, because it doesn't matter what the versions are. It's almost arbitrary because of the liberal use of |
Beta Was this translation helpful? Give feedback.
-
@gziolo Edit: I actually think |
Beta Was this translation helpful? Give feedback.
-
Another (potentially easy to implement) idea is to use For example, say a new function is added to |
Beta Was this translation helpful? Give feedback.
-
What is this issue about?
Gutenberg could be released as a single
@wordpress/gutenberg
package instead of 40+ packages. It’s an idea @dmsnell had and shared with me recently.What are the upsides?
Here’s what it would do:
@wordpress
dependencies. This includes Gutenberg releases and WordPress core merges. It would be impossible to run into problems with mismatched packages versions.tsconfig.json
files and problematic cross-package dependenciespackage.json
files andbuild
,build-module
, andbuild-style
setupAnecdotally, maintaining wordpress-playground got significantly easier after I migrated the monorepo from four internal packages to a single repository-wide package.
What are the downsides?
First, let me flip the question – what value is added by having 40+ packages? Or, as @dmsnell phrased it:
I've heard the following concerns so far:
The existing packages wouldn’t disappear from
npm
. They would get deprecated. Every package would ship one final release where every relevant member would get re-exported from@wordpress/gutenberg
.A single package would make it even easier. Figuring out which of the 40+ packages are needed is a hit-and-miss trial-and-error process.
The bundler would take care of that automatically with tree shaking. The package consumer would import the bits they are interested in, and the bundler would remove all the irrelevant code. If two entrypoints require the same package, the bundler would move it to a separate chunk to avoid downloading the same code twice.
A single package could still produce the same set of JavaScript files as the existing 40+ packages.
This can continue to work in the same way. If necessary, a webpack plugin would take care of that. There could also be a new and explicit
registerStore()
utility.The logical split and the directory structure would remain exactly the same as it is now. Only the
package.json
files would be gone. As a side note, Gutenberg's separation of concerns isn't nearly perfect despite the use of packages.What are the alternatives?
@wordpress/bootstrap
) that would re-export everything from the existing 40+ packages. That would be a win for package consumers.Both would improve some things, but would not address the complexity related to Lerna, version management, and
__experimental
exports discussed earlier.What do you think?
CC @youknowriad @gziolo @mcsf @noisysocks @priethor @aristath @peterwilsoncc @carolinan @tellthemachines @talldan @georgeh @artemiomorales @kevin940726 @ramonjd @andrewserong @ellatrix
Beta Was this translation helpful? Give feedback.
All reactions