D8DX: Improving the D8 developer experience

Last updated on
6 October 2020

The Goal

One of the things that makes Drupal great is the power it puts into the hands of non-developers to do awesome and amazing things on the web. A large portion of our community made a transition from non-developer to developer thanks to the accessibility/hackability of Drupal from an API perspective in Drupal 7 and below. In Drupal 8, however, things have become more... complicated. While flexibility is greatly increased, so too is the mental overhead as well as verbosity for doing even simple tasks.

This initiative is about making some key changes to the "DX" (developer experience) of Drupal in order to make it more accessible to people who need to extend Drupal to make it do cool things, but don't necessarily have a background in programming.

Reporting DX Issues

I tried porting my module to Drupal 8, and I'm concerned about D8's developer experience. How can I help fix it?

Please tell the core developers about it; we'd love for you to love Drupal 8 as much as we do!

  1. Search for open or all 8.x issues with the DX (Developer Experience) tag.
  2. If you don't find an existing issue, create an issue with the DX (Developer Experience) tag.
  3. Include some details like what you expected, what you tried, what happened instead, where you got stuck, what would've worked better for you, etc.
  4. Post a link to the D8 DX meta issue to bring it to the attention of those watching the issue.

We'll use this "user testing" data in order to formulate a plan of attack for fixing DX in D8.

Guiding Principles

  • Newbies learn first and foremost by copy/paste/modify. We should continue to support the ability for folks to do this, particularly on basic tasks.
  • We should make the common things easy, the less common things doable. https://gist.github.com/webchick/4409685 is a list of all D6 and D7 hooks, sorted by usage to help ferret these out.
  • Drupal 8 at this point is not going to fundamentally change the way it does things; for example, we're not going to switch back to procedural functions for everything, we're not going to remove the plugin system.
  • However, we can certainly look for ideas to abstract away complexity, tedious amounts of "boilerplate" code, and other mental hurdles, especially for the "90% cases" in contrib.

A vocabulary for discussing DX issues

DX issues tend to fall into the following buckets:

  • Complexity: When we're exposing way too much "how the sausage is made" details in user-space code. Back when we had silly things like $this->translationManager()->translate($string) instead of $this->t(). As a module developer, should not need to know or care that there's a translationManager in order to simply print a translatable string.
  • Verbosity: These aren't complex (in most cases they're easy to learn and/or copy/paste) but are little annoying pebbles in your shoe that grate on you every time you encounter them. Over-abundance of boilerplate code is an example of this.
  • Learnability: An overwhelming number of new concepts, a lack of a mental model to tie everything together, etc. (This definition needs work.)

The (DRAFT) Hit-List

In general, any major/critical issues with the DX (Developer Experience) tag. Here are a few specifics. This list is still under heavy development while we work out a broader plan. Feel free to add your own here as well!

High-impact

* #1971198: [policy] Drupal and PSR-0/PSR-4 Class Loading: PSR-0 was defined as a way for different PHP frameworks to share code with one another. By contrast, contributed Drupal modules are Drupal-specific and not intended to be shared, and directory structures that promote code re-use are overly verbose and irrelevant for this case. The upcoming PSR-4 standard helps address this.

* #2049159: Create a ControllerBase class to stop the boilerplate code madness: Right now, making even a simple "hello world" page requires grappling with concepts like the Dependency Injection Container. This patch introduces a base class with common dependencies already there so that module developers can just get to work creating their page callbacks.

* #2059245: Add a FormBase class containing useful methods: Ditto for forms.

* In general, stop the leaky abstraction insanity:
#2087279: Add a config() method to FormBase
#2018411: Figure out a nice DX when working with injected translation

* #2023613: Move event registration from services.yml to events.yml: Turns 2 PHP classes and 4 lines of YAML into 4 lines of YAML. Nice.

* #2106873: [meta][policy, no patch] Make Drupal 8 developer docs more discoverable: This is the most frequently-accessed resources of developers; let's make sure they can find all the things.

* #2107875: [meta] Centralize documentation for Drupal 8 on *.Drupal.org: Fragmentation is a huge DX issue. There are tons of valuable resources out there, but it's really hard to find them.

* #2138867: Allow dangling commas in annotations: This bites every single person who is trying out annotations for the first time (and even the 10th time). By making these arrays behave like PHP arrays, it greatly reduces the irritation associated with using them.

*#2408013: Adding Assertions to Drupal - Test Tools.: Nothing stops a 3 day bug hunt safari like a well placed assert. Adding assertions to catch what would otherwise be obscure error messages raised by bad config yml files will reduce a lot of stress.

*#2444089: Completely overhaul the error catching and logging system.: Longer term (8.1.x) overhaul the error handling system to stop the phenomena of the white screen of doom once and for all and insure that something useful can be learned about any error.

...

Low-hanging fruit

* #2057589: [Docs clean-up] Rename ControllerInterface to ContainerInjectionInterface: "ControllerInterface" as a name is too generic, and implies it should be used for all page controllers, even though it's really only needed for those who want dependency injection. Rename this so it's more clear.

* #2051097: Change "pattern" to "path" in *.routing.yml files: Symfony has changed from "pattern" to "path" as the name of the YAML key to define a route path. We should adopt the same so people don't get confused when reading Symfony documentation.

* #2053489: Standardize on \Drupal throughout core: Right now, we use Drupal in modules but \Drupal in classes. This consistently screws up everyone and makes patch reviews harder. See broader discussion at #1614186: Coding standards for using "native" PHP classes like stdClass in namespaced code.

Somewhere in-between / not evaluated yet

* #1391694: Use type-hinting for entity-parameters: Type-hinting with interfaces rather than classes provides for more flexibility in contrib, but EntityInterface is too generic. Introduce entity-specific interfaces to help with this, as well as give developers an easy reference to see what properties/methods $node has.

* #2085429: Provide a simple list controller for config entities: Reduce the number of classes needed to define a new plugin type.

* #2081945: [Policy, no patch] Reintroduce 'private' visibility to object-oriented code.: We switched to OO code in most places, but aren't making any use of one of the fundamental concepts of OO code. This is silly.

* There are a series of issues around simplifying plugin discovery to make it more approachable:
#2065571: Add YAML Plugin discovery
#2074407: Write tests for hook-based plugin discovery
... ?

* #1966246: [meta] Introduce specific annotations for each plugin type: @Plugin is too generic, and there are no docs for what e.g. an Block plugin needs vs. a Views plugin. By introducing plugin type-specific annotations, this can be resolved.

* #1880976: [meta] Port examples (including submodules) to D9.4+ and #1532612: Move Examples Project into Drupal core: Be sure all these new DXs have high-quality code to copy and paste.

* #2025883: Drupal's PHPUnit bootstrap.php does not register module namespaces out of /core and #2056607: /core/phpunit.xml.dist only finds top-level contrib modules: Allow module developers to use PHPUnit so they can write high-quality code.

* #2090353: Don't require to put the use statement into plugin classes: Don't require silly use statments on plugins

* #2098795: Create Base Class for RouteSubscriber Class: Simplify the process to add dynamically-generated routes.
also #2092529: [meta] Improve DX for defining custom routes

* #2100511: Make routing.yml files have a delightful DX: Improve the process to add static routes via YAML
* #2104347: Unify argument order between \Drupal\Core\Entity\EntityAccessControllerInterface access and createAccess methods: Makes things more consistent
* #2107137: Fix the DX for declaring custom access checkers: Don't know exactly how yet, but we need to make this easier to do.
* #2105557: Add an admin_permission to EntityType annotations to provide simple default access handling: Boilerplate--;
* #2100131: Simplify the way to register access checkers: Same :)

Help improve this page

Page status: No known problems

You can: