Problem/Motivation
There's huge resistance to adding front-end libraries (e.g. jQuery, Backbone.js, etc.) in core, because our current policy is to never update them once a stable release of Drupal core comes out. This means we're constantly lagging behind other front-end communities on compatibility, reducing the utility of these libraries, and create a janky experience for sites in the process (e.g. "deprecated" warnings from using out-dated versions of jQuery).
Proposed resolution
@sun proposes the following in #7:
- Commit multiple versions of a library over time, and have consuming code specify the exact version it is compatible with.
- Once there's a new version in core, the compatibility definition of consuming code would turn into a min/max version range.
- As soon as all consumers are compatible with a new version, the new one is loaded and the old one no longer.
- This means that consuming code can (should) progressively advance to use new features/APIs of the new library version β however, either using fallback/polyfill code for the case when the old version is loaded, or loading an entirely different consumer/integration file per version.
This might sound similar to Libraries API's (/Wysiwyg's) approach, which turns the situation entirely around and says "The library is always supplied by the user, your consuming code must be able to work with whatever version the user has downloaded." β however, the situation is not the same with libraries that are shipped/bundled/distributed with core (or a module), because in that case, there is a given contract that the bundled library is known to exist in that version and variant; it cannot and must not simply change under the hood without careful planning, notice, and updates of consuming code.
Therefore, the above proposal takes that into account, by allowing consuming code to progressively improve/renew.
If you're running on core only, then you will immediately use the new library versions (assuming that core immediately adapts its consuming code for updated library versions). If you're running 100 contributed modules, then the community needs to patch those modules for a new library version; and as soon as all dependencies on the old version are resolved, the new version is used.
Now that we're using JS only via libraries, it essentially boils down to additionally specifying compatible versions and/or version-dependent integration files per library.
@effulgentsia further follows up in #38:
- Any JS added to drupal that has a dependency on anything else must be added via drupal_add_library(), not drupal_add_js(). Therefore, all dependencies can be registered in hook_library_info(). I think we're already doing this in D8.
- Within hook_library_info(), we specify 'js' and 'dependencies' on a per version basis. E.g.:
$libraries['jquery_ui']['version']['2.0'] = array(
'js' => 'path/to/jquery-ui-20.js',
'dependencies' => array('system', 'jquery', '2.0'),
);
$libraries['jquery_ui']['version']['2.1'] = array(
'js' => 'path/to/jquery-ui-21.js',
'dependencies' => array('system', 'jquery', '2.1'),
);
Exact syntax on allowing ranges TBD.
- Calls to drupal_add_library() don't specify version, just the library. If you want a specific version, register your own custom library in hook_library_info(), list the dependency that JS code has, and then call drupal_add_library() of that custom library.
- When Drupal renders the scripts for the page (e.g., within drupal_get_js() or similar), it looks at the entire list of libraries added to the page, and runs some algorithm to determine which version of each library to provide: requiring compatibility, and among options that are all compatible, choosing the maximum. Details of this algorithm TBD.
- If it's impossible to satisfy version compatibility for all libraries (e.g., Library A depends on jQuery 2.1 and Library B depends on jQuery 2.0), Drupal starts dropping top-level libraries (ones that no other library on this page depends on) until it can output a set that are version compatible. [EDIT: To be replaced with AMD's methodology when/if
π
Use AMD for JS architecture
Closed: won't fix
happens.)
- Dropping libraries? Is that ok? Yes, because page markup needs to work without JS anyway. It should always be possible to drop a library (that no other library depends on) and still have a functioning (accessible) site, just with a degraded UX.
Make sure to read and understand the consequences of this concept outlined in #51.
Original report by effulgentsia
In
#1774312-40: Create.js: yay or nay *and*: when? β
, nod_ said:
core needs to decide on a strategy about library updates. If we can't/won't update during D8 stable release, [adding Create.js to core] will not work.
It's very unfortunate if our current approach of freezing JS library versions for an entire major Drupal version prevents us from adding really good libraries that can benefit core. At the same time, we need to be conservative about introducing BC breaks into minor releases: otherwise, people will stay on outdated minor releases and not be able to receive security updates.
How can we solve this?
#586146: [policy, no patch] Decide if and how to implement semantic versioning for Drupal 8.x β
might be one way. Any others?
Note, this isn't just about Create.js and its stack. Recent comments on
#1252178: Add Modernizr to core β
are wanting Modernizr in core too.