ResourceLoader/Requirements/Neil Kandalgaonkar
This page is obsolete. It is being retained for archival purposes. It may document extensions or features that are obsolete and/or no longer supported. Do not rely on the information here being up-to-date. Current information lives at ResourceLoader/Architecture. |
NeilK starting this page off -- this is just my opinions, so far. -- NeilK
There is also the ResourceLoader/Requirements/Michael Dale page.-- Mdale 20:37, 6 June 2010 (UTC)
Suggest good practice
edit- clear separation between libraries for reuse by anyone, and scripts for use on a page.
Manage namespace
edit- control a particular namespace in JS, such as
mw.*
- have strong conventions and facilities for managing this namespace. Should be easy to carve out one's own part of the
namespace and work within that. It should be easy to guess what PHP extension or gadget is managing what namespace and vice versa. e.g.
myExtension.php --> (mw.ext.myExtension). someGadget.js --> (mw.gad.someGadget)
Manage dependencies
edit- scripts and packages should be able to declaratively state dependencies on JS packages, and optionally versions of these packages.
- the system should translate these dependency declarations into URLs from which we load JS. This should be highly configurable as such URLs are often deployment-specific. (e.g. local server in dev, CDN in production).
- multiple dependencies may be batch-requested, and the server will send a compressed and optimized package.
- the server will extract and enable scripts in such a way that, before a script executes, its dependencies should be already loaded.
- dependencies, and the dependencies of dependencies (etc.) should be loaded in the correct order.
- it should also be possible to load libraries at runtime.
- if script loading fails the user gets useful error messages about what went wrong.
- By default, libraries already loaded in one session should not be reloaded. Nevertheless, one can force a reload or overwrite a namespace if you really want to.
- I think this is covered via the nature of the language ie mw.load('mw.SomeClass') .. then I want to completely override 'someClass' for some reason you would just say mw.SomeClass = null; mw.load('mw.MyClass', function(){ mw.SomeClass = mw.MyClass } ... or something like that depending if you wanted to just override prototypes or override a global instance -Mdale 20:43, 6 June 2010 (UTC)
Packaging - loading multiple libraries in one HTTP request
edit- Requests for a set of libraries or scripts in a particular language can result in creating compressed package(s) on the fly. These packages should be cached for subsequent requests.
- Nice to have -- precaching commonly requested packages, so there's no "first hit" penalty.
Manage skew
edit(This may be a separate issue from JS management, but we might as well consider it).
During development, one can simply assume that the latest version of a package is the one wanted, and any discrepancies fixed by purging the browser cache, or shift-reload.
In production, we have the issue of skew; it is possible for the PHP-emitted HTML and the loaded Javascript to get out of sync. This can happen as we deploy new features across servers, or simply due to browser caches or other intermediate caches.
Therefore, it is highly desirable that a Javascript Management system solve the problem of skew, between PHP-generated HTML and Javascript files. While we're at it, the same could be done for other secondarily loaded resources such as CSS and images.
There seem to be two use cases for dealing with skew on Wikipedia:
- Deployment of a new feature. As we deploy, we deal with statically cached versions of old pages, servers that have yet to be flipped over, etc. etc.
- The new PHP should invoke the new JS
- The old PHP should not invoke the new JS, and should continue to get the JS it wanted.
- Fixing a critical bug.
- Tim Starling points out that in the case of Wikipedia, which depends on static caching of millions of pages, we may want to purge and rev buggy JS files *without* revving the PHP that generates the page. This suggests that the server may have to know how to do a redirect to a version of the file that is now preferred, or otherwise make judgments about what version of JS the client should have.
Development & testing
edit- Should be able to turn compression + packaging on and off, with something simple like LocalSettings.php configuration and/or URL parameter
- When debugging scripts in tools like Firebug, line numbers must match the line numbers of the script on the filesystem.
Localization
edit- JS should obtain your preferred language exactly as every other part of MediaWiki does
- Scripts should be supplied with strings that they need, in the preferred language, from the standard MediaWiki string database.
- Declaration of 'needed' strings can be done piecemeal, but by default it should load the 'ExtensionName.i18n.php' file, or
equivalent for gadgets (?), without any special action or configuration.
- JS should have access to the similar pluralization/gender/modifier facilities as PHP.
Strong jQuery integration
edit- jQuery should be the standard for how JS interacts with the page
- jQuery plugins should be the standard for how JS is reused
- Easy to use and reuse a standard set of jquery plugins for MediaWiki
- ability to add to this standard set on a per-project basis (Wikipedia, Wikimedia Commons, etc.)
- installing a PHP extension can install jquery components that are then available to other extensions and gadgets.
??? Uncertain; should they be available at a standard URL and load into the standard JS namespace? Or should such components be in a URL related to their extension, and in their own JS namespace? e.g.
myExtension/js/foobar.js -> http://mysite/myExtension/js/jquery/jquery.foobar.js OR http://mysite/jquery/jquery.foobar.js
P.S. Things I'm uncertain about with JS2 / mwEmbed
edit- 'standalone' capability; the JS doesn't have to be the same whether framework is there or not.
- To me (NeilK) this seems like overreaching, particularly when it starts doing things like parsing Javascript to extract info it needs.
- The javascript is very different when the framework is there, and when its not. One line function calls like mw.includeAllModuleMessages() get replaced for the actual messages when used with the script-loader. When used in raw file mode the includeAllModuleMessage function call results in all the messages being included before the class becomes available.
Having "zero" php javascript file reading would mean you would assume mw.includeAllModuleMessages for certain files or map out what js files need what in php. Then in "debug / raw file mode" you would have to pre-load all these mappings and php-generated javascript for every class of your module. Then some other js would take thous "real file" mappings and load the js file. An array is an array be hosted in javascript or php. I thought putting that info in javascript would ease maintenance and development and work better user-scripts. But if we want to add support for php to host those mapping it would be pretty easy to add in. -Mdale 05:49, 6 June 2010 (UTC)
- The javascript is very different when the framework is there, and when its not. One line function calls like mw.includeAllModuleMessages() get replaced for the actual messages when used with the script-loader. When used in raw file mode the includeAllModuleMessage function call results in all the messages being included before the class becomes available.
- mwEmbed has random string and time functionality. Should move off to a library.
- Core helper functions are present because they are thought to be generally useful. ( For example your ( NeilK ) upload wizard and my embedPlayer use the same time functions. I agree these core helpers could be split into other "components" for improved maintainability. This has already been done with components like mw.Language and mw.Parser. -Mdale 05:49, 6 June 2010 (UTC)