Page MenuHomePhabricator

Provide a single-module registration mechanism for skin modules in ResourceLoader
Open, MediumPublic

Description

Background

Modules in ResourceLoader are allowed to vary by language and skin. This is why conditionally loaded scripts are not registered as their own module each, but rather as a single module that varies as necessary.

For example, moment and jquery.ui.datepicker vary by language but register only a single publicly loadable bundle, which ships additional scripts as needed based on the context.

Using the same principal, skins augment modules from core and extensions through $wgResourceModuleSkinStyles.

Problem

The startup manifest of loadable bundles for the current context contains all skins, yet it is very unlikely one would want to lazy-load the main stylesheet of skin X on a page view for skin Y.

Rather than having the startup manifest grow linearly based on the number of registered skins, it should only register modules for the current skin.

Outcome

The extension registry and MW configuration will:

  • allow skins to register modules in a way that allows RL to know they are "skin modules".
  • encourage skins to register only one style module, whilst also allowing additional ones to be registered.
Proposal

Developer facing:

  • New attribute SkinModule - takes which the form like a single entry in ResourceModules. Process and registered as a standard module called "skin". This is similar to the recently introduced QUnitTestModule attribute, in that it encourages a single module to be used with a standardised name.
  • New attribute ExtraSkinModules – similar to ResourceModules but only conditionally registered based on the skin. Modules in ResourceModules are available always and would be what extensions use. ExtraSkinModules is what skins would use to register extra modules and would not be loadable from page view that uses a different skin.

Internally:

  • New config wgResourceSkinModules, similar to ResourceModules but with an extra key layer for skin name. E.g. wgResourceSkinModules['timeless']['skins.timeless.foo'] would be a module skins.timeless.foo only loadable in contexts where the skin is timeless.
  • The extension processor would add SkinModule entries to wgResourceSkinModules[info.name]["skin"].
  • The extension processor would add ExtraSkinModules entries to wgResourceSkinModules[info.name].

This proposal is a minimal alternative to T253582: Let ResourceLoader only register skin modules for the current skin. If that task gains traction, then this task is probably not warranted so as to keep the skin interface simple and easy to use.

Event Timeline

Restricted Application added a subscriber: Aklapper. · View Herald Transcript

Why skins? Why not let people just mark modules as 'stylemodules', not worry about what the hell is providing them, and then not add them to the giant js bloat pile and be done with it?

@Isarra That's an interesting idea. Roan had the same idea a few weeks back. Unfortunately, that's not compatible with how MW works. All style modules must be loadable on-demand. A number of systems depend on that. The only exception to that are skin modules, hence this proposal.

Regular style modules from core and extension features that style HTML output, are enqueued through ParserOutput, which mw.loader.load() needs to be able to translate into an on-demand requirement. Used by Live Preview, VisualEditor (while editing after inserting new nodes, as well as post-save for the new version of the article), and possibly in future lazy-loading endeavours. In cases like these, there is addModuleStyles() calls made on content that is saved in the ParserOutput, but served through the API to a JS client (instead of as a regular page view).

@Isarra That's an interesting idea. Roan had the same idea a few weeks back. Unfortunately, that's not compatible with how MW works.

Comments like this really aren't helpful. If you have counter examples that show something won't work as described, please just start with that and avoid telling people that their ideas are just bad, and also someone else already beat them to it. Not only is this really not necessary, it is frankly very off-putting and discourages productive discussion or collaborative working toward a better understanding on all sides. (For instance you could just say 'Roan brought this up and we looked into it and we found ... <content example>' and suddenly all the 'how interesting, you clearly don't know how mw works' implications are gone.)

Even in this particular case, that is only one specific example. Do we really have no other module categories beyond 'this skin', 'content and things that could become content', and 'javascript'? Do no extensions add base interface styles besides skins, that will just be there from the start?

If the problem here is that the list has gotten out of hand, do we have any reason to expect it won't keep getting more so, even with this one category removed? Why not categorise the modules in terms of when/how to make them listable/loadable? Instead of a giant list of modules, have a list of categories of modules, and only load the categories that make sense from the start (no content on non-content pages unless explicitly requested, no skins that aren't the current skin, don't get the rest of VE until people actually load VE), but let the js go get the other lists as needed (like if we added a fancy skin preview in special:preferences, configuresite, whatever, we'd maybe load the skins lists there after all, but we still likely wouldn't need it anywhere else). Each skin becomes its own category, most extensions just add to standard categories like 'content' or 'interface' or whatever, more complex extensions like VE define new categories probably with the same interface as skins use...

I'm sorry that my comment discouraged you, this was not my intention. The emphasis and tone of words are sometimes hard to receive through the written word...

I specifically choose to reference our previous work to motivate your thinking along these lines. The idea was very much not "clearly wrong". On the contrary. It was something we also thought of (thinking alike) and took seriously. We found the aforementioned issues, but that doesn't mean it was obvious. Your idea was independently thought of and demonstrates you understand the system's intent and model quite well. There's not many people whom I can say that about.