Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a backward compatibility document #18499

Merged
merged 33 commits into from
Nov 14, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1 +1,65 @@
# Backward Compatibility

Historically, WordPress has been known for preserving backward compatibility across versions. Gutenberg follows this example wherever possible in its production public APIs. There are rare occasions where breaking backward compatibility is unavoidable and in those cases the breakage:

* Should be constrained as much as possible to a small surface area of the API.
* Should be documented as clearly as possible to third-party developers using Dev Notes.

## What qualifies as a production public API
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
## What qualifies as a production public API
## What qualifies as a production public API?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we do that, we should do it for all the titles that are written as questions.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "Hows" read more like statements.

Although technically, this can also be a statement, it reads more like a question, but it might be just me.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a content clause, it's perfectly fine as is.


The Gutenberg code base is composed of two different types of packages:
- **production packages**: these are packages that are shipped as WordPress scripts (example: wp-components, wp-editor...).
- **development packages**: these are made up of developer tools that can be used by third-party developers to lint, test, format and build their themes and plugins (example: @wordpress/scrips, @wordpress/env...). Typically, these are consumed as npm dependencies in third-party projects.

Backward compatibility guarantees only apply to the production packages, as updates happen through WordPress upgrades.

Production packages use the `wp` global variable to provide APIs to third-party developers. These APIs can be JavaScript functions, variables and React components.

### How to preserve backward compatibility for a JavaScript function

* The name of the function should not change.
* The order of the arguments of the function should not change.
* The function's returned value type should not change.
* Changes to arguments (new arguments, modification of semantics) is possible if we guarantee that all previous calls are still possible.

### How to preserve backward compatibility for a React Component

* The name of the component should not change.
* The props of the component should not be removed.
* Existing prop values should continue to be supported. If a component accepts a function as a prop, we can update the component to accept a new type for the same prop, but it shouldn't break existing usage.
* Adding new props is allowed.
* React Context dependencies can only be added or removed if we ensure the previous context contract is not breaking.

### How to preserve backward compatibility for a Block

* Existing usage of the block should not break or be marked as invalid when the editor is loaded.
* The styling of the existing blocks should be guaranteed.
* Markup changes should be limited to the minimum possible, but if a block needs to change its saved markup, making previous versions invalid, a [**deprecated version**](/docs/designers-developers/developers/block-api/block-deprecation.md) of the block should be added.

## Class names and DOM updates

Class names and DOM nodes used inside the tree of React components are not considered part of the public API and can be modified.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was just thinking today how unsustainable and regrettable I find the changes of #14420. I'd be happy to see those old classes removed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that we have just started the development cycle for WordPress 5.4 it should be a good moment to clean this up. We would need to include it in dev notes, but given that it's a simple string replace action for theme authors, it should be straightforward to apply for them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's possible to remove them today, especially as we refactor some of these components. We just need to make sure to write dev notes about these.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll make a note to put together a pull request. I think it will save much confusion for everyone, since the duplication of class names makes it very unclear which is the preferred, and how to name new classes. it seems reasonable enough to me that a DevNote should cover this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Follow-up at #19050

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One fundamental concern I have here (and apologies for the late revisit) is that currently it is only possible to build a block which renders child blocks horizontally by targeting class names, as the InnerBlocks component does not offer declarative UI configuration (e.g. isHorizontal or shouldWrapBlocks-style props).

I love the idea here but it feels like this is a case where it might be warranted to make an exception until a declarative alternative is available.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good point, I think the Navigation block has started building a declarative API for that, the columns block is also a horizontal container, it should be possible to offer a better API here.

Copy link
Member

@aduth aduth Dec 11, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this example contradicts the general recommendation though. If there's need for something like this, we shouldn't want that the developer feel need to target the classes, but instead offer it as an option via the component interface. It appears that's what's already being said in this comment chain, but I want to point out that I think it's consistent with treating the class names as unstable.

Put another way: I don't think there should be exceptions, because these aren't supported use-cases. If they were supported use-cases, there would be a component interface for them, and not a reliance on a specific class name. There's nothing to stop a developer from choosing to target the class names anyways if they so choose, but the framework shouldn't be held responsible to upholding support for that usage.

For me, if the purpose of this document is to outline the intended support commitments, then we should be consistent to them.


Changes to these should be done with caution as it can affect the styling and behavior of third-party code (Even if they should not rely on these in the first place). Keep the old ones if possible. If not, document the changes and write a dev note.

## Deprecations

As the project evolves, flaws of existing APIs are discovered, or updates are required to support new features. When this happens, we try to guarantee that existing APIs don't break and build new alternative APIs.

To encourage third-party developers to adopt the new APIs instead, we can use the [**deprecated**](/packages/deprecated/README.md) helper to show a message explaining the deprecation and propose the alternative whenever the old API is used.

## Dev Notes

Dev notes are [posts published on the make/core site](https://make.wordpress.org/core/tag/dev-notes/) prior to WordPress releases to inform third-party developers about important changes to the developer APIs, these changes can include:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Dev notes are [posts published on the make/core site](https://make.wordpress.org/core/tag/dev-notes/) prior to WordPress releases to inform third-party developers about important changes to the developer APIs, these changes can include:
Dev Notes are [posts published on the make/core site](https://make.wordpress.org/core/tag/dev-notes/) prior to WordPress releases to inform third-party developers about important changes to the developer APIs, these changes can include:

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggested the opposite earlier because elsewhere we use "dev notes" in text. Only in a title words are capitalised, at the start of a sentence, or in a label.

* New APIs.
* Changes to existing APIs that might affect existing plugins and themes. (Example: classname changes...)
* Unavoidable backward compatibility breakage, with reasoning and migration flows.
* Important deprecations (even without breakage), with reasoning and migration flows.

### Dev Note Workflow

* When working on a pull request and the need for a dev note is discovered, add the **Needs Dev Note** label to the PR.
youknowriad marked this conversation as resolved.
Show resolved Hide resolved
* If possible, add a comment to the PR explaining why the dev note is needed.
youknowriad marked this conversation as resolved.
Show resolved Hide resolved
* When the first beta of the upcoming WordPress release is shipped, go through the list of merged PRs included in the release that are tagged with the **Needs Dev Note** label.
* For each one of these PRs, write a dev note and coordinate with the WordPress release leads to publish the dev note.
youknowriad marked this conversation as resolved.
Show resolved Hide resolved
* Once the dev note for a PR is published, remove the **Needs Dev Note** label from the PR.
youknowriad marked this conversation as resolved.
Show resolved Hide resolved