Page MenuHomePhabricator

Document which modules do not need to be added to the dependencies of other modules
Closed, ResolvedPublic


Could someone complement the docs[1] with information on which ResourceLoader modules are supposed to be always loaded by default?

I keep forgetting this, and others might benefit from it.

See e.g. the case of "user.options" on [2] and Krinkle's comment on Change-Id: Ia2c87a32f692da2347ad670cdbcf6d6e6d171f15


Version: unspecified
Severity: normal



Event Timeline

bzimport raised the priority of this task from to Needs Triage.Nov 22 2014, 3:24 AM
bzimport set Reference to bz63674.
bzimport added a subscriber: Unknown Object (MLST).

Krinkle has just posted an excellent comment on [[en:MediaWiki talk:Common.js#Protected edit request on 7 April 2014]], reproducing here for posterity:

Let me clarify. There's three things at play:

  • The mediawiki base module (mediawiki). This one can't be declared as dependency (and doesn't have to be) because it is the base module that actually defines mw.loader itself. If memory serves, it currently defines mw.Map, mw.config, mw.messages, mw.Message, mw.loader, mw.html, mw.hook and a few miscellaneous methods. None of these have their own module (it's not that you can't or shouldn't depend on it, they simply don't exist as a module, e.g. there is no such module as mediawiki.config or mediawiki.html, it would throw "Unknown dependency" if you try).
  • Page modules: There are various modules that are loaded by default on a page (either because the Skin needs it, or because we use it for enhancing page content, or because an extension added it to the load queue etc.). This usually includes mediawiki.user, mediawiki.legacy.wikibits and others. Though these are loaded by default, they absolutely must not be assumed as being available at all times. If you use mw.user, you *have* to declare that dependency. Two reasons for this:
    1. The default list can change (either in general or for some pages). There is nothing that says they will always be loaded, they are loaded because some part of the application uses them (just like your preferences panel will add a gadget if you tell it to, and if that gadget is on every page and loads mw.Title then that module will be on every page, but that's just a coincidence). They are not part of the "this is always available, use freely" and never have been.
    2. While they are loaded by default, even now things load in parallel (this is by design). If you want your code to execute after "mediawiki.user" has finished loading, you have to indicate this through a dependency or else there will be race conditions where mw.user is still undefined and your code will fail.
  • Globally embedded page modules. These modules (such as user.options) are embedded within the page for security and/or performance reasons. Since they execute synchronously and are embedded before any load queue, these not only load by default but also "finish" loading before any module, gadget or otherwise starts loading. Which means technically you can get away with not specifying user.options as a dependency because it's impossible for them not to be there. However, once again, do not rely on the arbitrary implementation detail that this particular module is being embedded right now.

In short: Just declare all your direct module dependencies and let
ResourceLoader do its job.

So, to sum up: there are exactly two such modules, 'jquery' and
'mediawiki' (and in fact since Ic8b4ed45 in core, PHP unit tests will
fail if you try to create a module that depends on them server-side).
All other ones should be explicitly declared as dependencies, even if
the code works when you don't.