backdrop-ops / docs.backdropcms.org

Website for displaying Backdrop CMS documentation and API source code.
https://docs.backdropcms.org/
6 stars 6 forks source link

Developer docs: document strategy for bundling third-party libraries #188

Closed bugfolder closed 2 years ago

bugfolder commented 2 years ago

Follow-up from a discussion at the 3/3 weekly meeting

I've created a documentation page on Using libraries that borrows heavily from the Libraries module README, plus points raised in the meeting discussion and [Zulip follow-up]()https://backdrop.zulipchat.com/#narrow/stream/218635-Backdrop/topic/Weekly.20Meetings).

Feel free to suggest further edits or changes.

indigoxela commented 2 years ago

One suggestion:

An example might be a library for creating PDFs

To my understanding hook_library_info() is for JS and CSS. If something creates PDF files, it's almost certainly PHP (correct me if I'm wrong), which would not work with backdrop_add_library(). So this might be a bit confusing.

It's of course possible to add a PHP library in one's module and leverage that in this one module (I did that before).

bugfolder commented 2 years ago

Ah, good point. I'll change the example.

bugfolder commented 2 years ago

Should we suggest a strategy for unbundling a library from an existing 3rd-party module (since that's an issue that triggered the recent discussion)?

indigoxela commented 2 years ago

Should we suggest a strategy for unbundling a library from an existing 3rd-party module

I'm not sure about that. It might be information, that's only needed in edge-cases. And probably @jenlampton might want to chime in here, as she seems to have strong feelings about "modules that don't do anything".

indigoxela commented 2 years ago

A tiny typo: "Librairies" :wink:

An example might be a JS library for working with dates...

Oh yes, that's a much better example. :+1:

implementing hook_library_info() and hook_library_info_alter())

In general hook_library_info() does the job, hook_library_info_alter() is rather for overriding existing libraries (providing a different version...).

bugfolder commented 2 years ago

Thanks, typo fixed and hook_library_info_alter() dropped in that sentence.

Should we suggest a strategy for unbundling a library from an existing 3rd-party module

I'm not sure about that. It might be information, that's only needed in edge-cases.

I was thinking that since we already say "the 3rd party library should be split out of the “parent” module that it used to ship with, and moved into a new contrib library-only module" (which is text taken from the Library API node page), we've already dipped our toes into that edge case; but I guess we can leave it at that.

And probably @jenlampton might want to chime in here, as she seems to have strong feelings about "modules that don't do anything".

Yes; I tried to address the point she made at the weekly meeting by leading with the "recommended practice" comment, but would welcome further input.

jenlampton commented 2 years ago

Oh yeah, if the library is already in a module, it definitely shouldn't be removed from that module (as that will break existing sites). The secondary module should depend on the primary one.

But in the cases where there aren't any modules yet, we should write some guidelines on how to decide whether there should be one module or two. The 80% rule should be mentioned, maybe with examples.

jenlampton commented 2 years ago

Here's a first pass at an example:

When deciding where to bundle the library, user experience should be valued over the preference of the developer. Whenever possible, a person should be able to install a single project to accomplish the task at hand.

One of the most frustrating experiences for people using Drupal is that it often requires locating, downloading, and installing at least 3 different modules -- in addition to an external library -- just to build something like an image gallery. In many cases, the versions of these different projects start to diverge over time, creating a more and more frustrating experience.

In Backdrop, with views (and ctools) in core, we should be able to reduce this process to installing a single module (that includes the library). When the library is bundled with the integration it provides, it greatly reduces the risk that the version of the library will not work with the integration.

If the primary purpose of your library is for building an image gallery, it's probable that at least 80% of the time the library is needed, it would be for a views display. As such, the views integration for the library should be included in the module that bundles the library.

It's also possible that people might want to use the library on a field display. Ideally, the field integration would also be part of the module that adds the views integration, but if people feel strongly that this feature will be used less than 80% of the time, the next-best location for the field integration wold be in a sub-module that is part of the same project (so still only one project needs to be installed by a site architect).

The next best location for the field integration would be in a separate add-on module that can be downloaded and installed separately from the original module, and in this case, the separate module should add the dependencies[] line to the info file, to indicate that the primary module is needed.

The least best scenario for this image gallery would be to have one project for the library only, a second for the views integration, and a third for the field integration. This would put Backdrop only one small step ahead of Drupal in terms of the user experience.

Having a library-only module is not only problematic in terms of version compatibility, but it can also create a frustrating experience for site architects. After installing such a module, many people will search the admin interface for the feature it provides - only to learn later that the module does not provide any features.

Modules that do not provide any features should be clearly labeled as such on the module's README file, as well as in the project name. The "Youtube" module, for example, should not only implement the YouTube API, without including any features. People are not likely to read the project description (or the README file) if the project name exactly matches their expectations. Telling people that they should have read the README, after the fact, does not negate the frustration they have already experienced. Anything we can do to eliminate the frustration before it happens, should be attempted. In this example, it might have helped if the name of this module was "Youtube API".

There are, of course, many different types of libraries, and not all of them provide such clear examples of which features meet the 80% use case. We leave the decision of where to place the library up to those creating the modules, but this should serve as a useful guide to help make that decision.

bugfolder commented 2 years ago

Some suggested edits/rewordings. To facilitate comparison, I'm quoting paragraphs that I've majorly rewritten, with the rewritten version immediately following it. If you just want to see my version, ignore all the quoted bits.

Where to bundle

When deciding where to bundle the library, user experience should be valued over the preference of the developer. Whenever possible, a person should be able to install a single project to accomplish the task at hand.

One of the most frustrating experiences for people using Drupal is that it often requires locating, downloading, and installing at least 3 different modules -- in addition to an external library -- just to build something like an image gallery. In many cases, the versions of these different projects start to diverge over time, creating a more and more frustrating experience.

Trying to avoid slagging Drupal directly in our documentation...

Developers often favor a fine-grained bundling strategy (i.e., spreading functionality over several related modules), but it can be frustrating to site architects to have to locate, download, and install 2 or 3 (or more) modules just to accomplish a single goal.

Consider, for example, an image gallery based on an external library.

In Backdrop, with views (and ctools) in core, we should be able to reduce this process to installing a single module (that includes the library). When the library is bundled with the integration it provides, it greatly reduces the risk that the version of the library will not work with the integration.

With the functionality that exists in Backdrop core, we should be able to reduce the installation process to installing a single module that includes the library, rather than making the user find the multiple modules that its functionality is spread over. Furthermore, when the library is bundled with the integration it provides, it greatly reduces the risk that the version of the library will not work with the integration.

If the primary purpose of your library is for building an image gallery, it's probable that at least 80% of the time the library is needed, it would be for a views display. As such, the views integration for the library should be included in the module that bundles the library.

Note that if the primary purpose of your library is for building something like an image gallery, it's probable that at least 80% of the time the library is needed, it would be for a views display, and so the views integration for the library should also be included in the module that bundles the library.

It's also possible that people might want to use the library on a field display. Ideally, the field integration would also be part of the module that adds the views integration, but if people feel strongly that this feature will be used less than 80% of the time, the next-best location for the field integration wold be in a sub-module that is part of the same project (so still only one project needs to be installed by a site architect).

It's also possible that people might want to use the library on a field display. Ideally, then, the field integration would also be part of the module that adds the views integration.

If, however, you believe that this feature would be used less than 80% of the time, the next-best location for the field integration wold be in a sub-module that is part of the same project, so that still only one project needs to be installed by the site architect.

The third-best location for the field integration would be in a separate add-on module that can be downloaded and installed separately from the original module, and in this case, the separate module should add the dependencies[] line to the .info file, to indicate that the primary module is needed.

The least best scenario for this image gallery would be to have one project for the library only, a second for the views integration, and a third for the field integration. This would put Backdrop only one small step ahead of Drupal in terms of the user experience.

The least-best scenario for this image gallery would be to have one project for the library only, a second for the views integration, and a third for the field integration. But this brings us back to the "fractured" user experience that Backdrop CMS is trying to avoid.

Having a library-only module is not only problematic in terms of version compatibility, but it can also create a frustrating experience for site architects. After installing such a module, many people will search the admin interface for the feature it provides - only to learn later that the module does not provide any features.

As noted above, a library-only module can create version compatibility problems if a library and module must be updated in sync. It can also create a frustrating experience for site architects; after installing a library-only module, many people will search the admin interface for the feature it provides, only to learn (eventually) that the module does not provide any features.

Modules that do not provide any features should be clearly labeled as such on the module's README file, as well as in the project name. The "Youtube" module, for example, should not only implement the YouTube API, without including any features. People are not likely to read the project description (or the README file) if the project name exactly matches their expectations. Telling people that they should have read the README, after the fact, does not negate the frustration they have already experienced. Anything we can do to eliminate the frustration before it happens, should be attempted. In this example, it might have helped if the name of this module was "Youtube API".

Modules that do not provide any features directly should make this clear in two ways:

For example, a module titled "YouTube" should not just implement the YouTube API, but should provide features that support that API. If the library really is just a wrapper for the YouTube API, then a better module name would be "YouTube API".

Be aware that even if the module's README file states that it is library-only, people are not likely to read the project description (or the README file) if the project name exactly matches their expectations. (Telling people that they should have read the README, after the fact, does not negate the frustration they have already experienced.) Anything we can do to eliminate the frustration before it happens, should be attempted; hence the suggested hinting in the module name.

There are, of course, many different types of libraries, and not all of them provide such clear examples of which features meet the 80% use case. We leave the decision of where to place the library up to those creating the modules, but this should serve as a useful guide to help make that decision.

There are, of course, many different types of libraries, and not all of them provide clear examples of which features meet the 80% use case that warrant bundling. In the end, the decision of where to place the library falls to those creating the modules, but the considerations above can serve as a guide to help make that decision.

jenlampton commented 2 years ago

All these changes are much better!

bugfolder commented 2 years ago

Those changes are now implemented.

https://docs.backdropcms.org/documentation/using-libraries

jenlampton commented 2 years ago

This looks really good :)

I added a section about when Libraries API is necessary (when the library is not GPL-Compatible and cannot be bundled into a module).