Hi,
Preface: I understand very little about how ResourceLoader works.
I was trying to use the mw.Api module to do some API calls, following the general example of the documentation:
*var api = new mw.Api();* *api.get( {* * action: 'query',* * meta: 'userinfo'* * } ).done ( function ( data ) {* * console.log( data );* * } );*
However, I was getting an error in the JS console:
*TypeError: undefined is not a constructor (evaluating 'new mw.Api()')*
For our dev server and on my local instance of MediaWiki (on a Mac), $wgResourceLoaderDebug is set to *true* so we can debug our individual JS files. For kicks, I set this value to *false *in my page URL (e.g. " http://mywiki/index.php/MyPage?*debug=false*"), allowing ResourceLoader to do its magic - the error went away, giving me the data I wanted. When I flipped it back to *true*, the error returned.
Is this known behavior, a bug? Or could I have some other strange configuration which is causing this problem?
Thanks, -- Jason Ji jason.y.ji@gmail.com
On Wed, Mar 11, 2015 at 5:09 PM, Jason Ji jason.y.ji@gmail.com wrote:
I was trying to use the mw.Api module to do some API calls, following the general example of the documentation:
*var api = new mw.Api();* *api.get( {*
- action: 'query',*
- meta: 'userinfo'*
- } ).done ( function ( data ) {*
- console.log( data );*
- } );*
However, I was getting an error in the JS console:
*TypeError: undefined is not a constructor (evaluating 'new mw.Api()')*
You probably forgot to load mediawiki.api, either by dependencies in $wgResourceModules if you're writing an extension or using mw.loader.using( 'mediawiki.api', function () { ... } );
So it's strange, about ten or fifteen minutes after I posted that, the error went away while I was fiddling with something or other. One of those really strange (and terrible) magically disappearing bugs... so the following is no longer urgent, but more for my own edification.
You're right that I never load mediawiki.api. (However, I'm still not loading it and the problem has resolved itself.) But why would I need to load mediawiki.api, and not other mediawiki JS modules? I've been able to use other mw modules in JavaScript without any issues (example: mw.user for getting tokens, or mw.config to get various $wg variables).
-- Jason Ji jason.y.ji@gmail.com
On Wed, Mar 11, 2015 at 7:22 PM, Brad Jorsch (Anomie) <bjorsch@wikimedia.org
wrote:
On Wed, Mar 11, 2015 at 5:09 PM, Jason Ji jason.y.ji@gmail.com wrote:
I was trying to use the mw.Api module to do some API calls, following the general example of the documentation:
*var api = new mw.Api();* *api.get( {*
- action: 'query',*
- meta: 'userinfo'*
- } ).done ( function ( data ) {*
- console.log( data );*
- } );*
However, I was getting an error in the JS console:
*TypeError: undefined is not a constructor (evaluating 'new mw.Api()')*
You probably forgot to load mediawiki.api, either by dependencies in $wgResourceModules if you're writing an extension or using mw.loader.using( 'mediawiki.api', function () { ... } );
-- Brad Jorsch (Anomie) Software Engineer Wikimedia Foundation
Mediawiki-api mailing list Mediawiki-api@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-api
On Wed, Mar 11, 2015 at 7:28 PM, Jason Ji jason.y.ji@gmail.com wrote:
So it's strange, about ten or fifteen minutes after I posted that, the error went away while I was fiddling with something or other. One of those really strange (and terrible) magically disappearing bugs... so the following is no longer urgent, but more for my own edification.
Ah, caching issues! If I recall correctly, debug=true bypasses some internal ResourceLoader caching. debug=false tries to check file mtimes and such to avoid serving stale caches, but sometimes it gets confused.
For my own local development, I sometimes use a shell script that clears memcached and redis and runs the clearMessageBlobs.php script from the WikimediaMaintenance extension. You probably wouldn't want to do all that on a production server, though.
You're right that I never load mediawiki.api. (However, I'm still not loading it and the problem has resolved itself.) But why would I need to load mediawiki.api, and not other mediawiki JS modules? I've been able to use other mw modules in JavaScript without any issues (example: mw.user for getting tokens, or mw.config to get various $wg variables).
Some stuff is loaded by default, but I don't think mediawiki.api is part of that. For something as commonly used as mediawiki.api, though, you might be getting lucky in that something else on the page might be loading it for you.
Thanks for the responses, Brad. Is there some documentation somewhere for which modules are loaded by default and which ones aren't (e.g. mediawiki.api)?
-- Jason Ji jason.y.ji@gmail.com
On Thu, Mar 12, 2015 at 10:22 AM, Brad Jorsch (Anomie) < bjorsch@wikimedia.org> wrote:
On Wed, Mar 11, 2015 at 7:28 PM, Jason Ji jason.y.ji@gmail.com wrote:
So it's strange, about ten or fifteen minutes after I posted that, the error went away while I was fiddling with something or other. One of those really strange (and terrible) magically disappearing bugs... so the following is no longer urgent, but more for my own edification.
Ah, caching issues! If I recall correctly, debug=true bypasses some internal ResourceLoader caching. debug=false tries to check file mtimes and such to avoid serving stale caches, but sometimes it gets confused.
For my own local development, I sometimes use a shell script that clears memcached and redis and runs the clearMessageBlobs.php script from the WikimediaMaintenance extension. You probably wouldn't want to do all that on a production server, though.
You're right that I never load mediawiki.api. (However, I'm still not loading it and the problem has resolved itself.) But why would I need to load mediawiki.api, and not other mediawiki JS modules? I've been able to use other mw modules in JavaScript without any issues (example: mw.user for getting tokens, or mw.config to get various $wg variables).
Some stuff is loaded by default, but I don't think mediawiki.api is part of that. For something as commonly used as mediawiki.api, though, you might be getting lucky in that something else on the page might be loading it for you.
-- Brad Jorsch (Anomie) Software Engineer Wikimedia Foundation
Mediawiki-api mailing list Mediawiki-api@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-api
On Thu, Mar 12, 2015 at 10:24 AM, Jason Ji jason.y.ji@gmail.com wrote:
Thanks for the responses, Brad. Is there some documentation somewhere for which modules are loaded by default and which ones aren't (e.g. mediawiki.api)?
Not that I know of, although I'm not terribly familiar with the details of ResourceLoader. It appears that the list is 'jquery' and 'mediawiki', but the latter module includes the mw.config and mw.user objects (and anything else in mediawiki.js[1] rather than a different file).
[1]: https://git.wikimedia.org/blob/mediawiki%2Fcore.git/master/resources%2Fsrc%2...
On 12 Mar 2015, at 14:24, Jason Ji jason.y.ji@gmail.com wrote:
Thanks for the responses, Brad. Is there some documentation somewhere for which modules are loaded by default and which ones aren't (e.g. mediawiki.api)?
Nothing is loaded by default.
If you make use of interfaces provided by a module, you must add a dependency on that module.
Just like your code, there is also other code on the same page (either from core or other extensions). Under race conditions (=unreliable), naturally something has to be the first module to run. Since "mediawiki.api" is quite popular, there is a good chance something somewhere might have declared a dependency on it – thus instructing ResourceLoader to load it from the server.
Other times, when your code might be the first to run, it won't be there (yet).
Even modules like "mediawiki.user" which are loaded from (almost!) every page, it still can't be guaranteed because:
1) It loads asynchronously, so while it might be requested on every page, it might be finished downloading in time before your code.
2) What wiki pages do and do not need is subject to change, just like your code might change over time to make use of different modules.
So, always always always declare your dependencies. Don't worry about other modules providing it already or about slowing things down. ResourceLoader takes care of combining requests in batches (and if more than one, in parallel). It also keeps track of modules that are already underway. Declare what you need, and it will take care of the rest.
https://www.mediawiki.org/wiki/ResourceLoader/Features
-- Krinkle
On Mon, Mar 23, 2015 at 3:08 AM, Krinkle krinklemail@gmail.com wrote:
Nothing is loaded by default.
If you make use of interfaces provided by a module, you must add a dependency on that module.
I must have misunderstood something. If all dependencies have to be declared then why does ResourcesTest::testIllegalDependencies() explicitly complain about 'jquery' and 'mediawiki'?
On Mon, 23 Mar 2015 14:56:47 +0100, Brad Jorsch (Anomie) bjorsch@wikimedia.org wrote:
If you make use of interfaces provided by a module, you must add a dependency on that module.
I must have misunderstood something. If all dependencies have to be declared then why does ResourcesTest::testIllegalDependencies() explicitly complain about 'jquery' and 'mediawiki'?
All dependencies with the exception of these two. 'jquery' and 'mediawiki' are required for the code which loads other modules, and therefore they're loaded in a special way themselves.
(Specifying them as dependencies was mostly harmless up to MW 1.23, if I recall, and now will break your code in horrible ways starting with 1.24. This is a messy bug caused by nasty internals that no one really wants to fix, I'm afraid.)
On 23 Mar 2015, at 13:56, Brad Jorsch (Anomie) bjorsch@wikimedia.org wrote:
On Mon, Mar 23, 2015 at 3:08 AM, Krinkle krinklemail@gmail.com wrote: Nothing is loaded by default.
If you make use of interfaces provided by a module, you must add a dependency on that module.
I must have misunderstood something. If all dependencies have to be declared then why does ResourcesTest::testIllegalDependencies() explicitly complain about 'jquery' and 'mediawiki'?
jquery and mediawiki are not modules. They are raw files leveraging parts of ResourceLoader to deliver itself. Obviously it can't load itself, so it wouldn't make sense as a dependency. It's part of the base environment. If you're registering a module and managed to get it loaded, by definition it must already be there.
Similar to how websites using RequireJS wouldn't have one add a dependency on "requirejs" on every module that calls require() somewhere. Granted, our base module provides a fair bit more than just mw.loader but the paradigm does apply.
We could refer to them as the "base" environment. But not "default" or "modules", that would understandably be confusing.
-- Krinkle
PS: In theory one could make them no-ops removed at run time server-side, but would just be wasted efforts for developer and server. I won't make the same mistake most C-family language designers made when allowing the curly brace to be placed either at the end or on the next line. We could've done it the way of needing to depend on jquery, but we didn't. Better one way consistent, than two ways (which isn't a way). A minor confusion here and there is I think worth it, compared to the wasted efforts, bikeshedding and stronger confusion about why they are and sometimes aren't.
On Tue, Mar 24, 2015 at 3:09 AM, Krinkle krinklemail@gmail.com wrote:
On 23 Mar 2015, at 13:56, Brad Jorsch (Anomie) bjorsch@wikimedia.org wrote:
On Mon, Mar 23, 2015 at 3:08 AM, Krinkle krinklemail@gmail.com wrote:
Nothing is loaded by default.
If you make use of interfaces provided by a module, you must add a dependency on that module.
I must have misunderstood something. If all dependencies have to be declared then why does ResourcesTest::testIllegalDependencies() explicitly complain about 'jquery' and 'mediawiki'?
jquery and mediawiki are not modules. They are raw files leveraging parts of ResourceLoader to deliver itself
Ah, there's the confusion. Despite being in Resources.php in the same data structure and in the same format as all (other) modules, and being named by a method named "getStartupModules", and being delivered via the usual module loader script where they're specified as "modules=jquery%2Cmediawiki", and generally being referred to as "modules" in code comments and so on, you don't consider them modules because they're loaded specially by the bootstrapping "module"[1] and aren't passed to mw.loader.register().
[1]: I'm guessing 'startup', implemented by ResourceLoaderStartUpModule, is not a module either by your definition.
On 24 Mar 2015, at 14:13, Brad Jorsch (Anomie) bjorsch@wikimedia.org wrote:
On Tue, Mar 24, 2015 at 3:09 AM, Krinkle krinklemail@gmail.com wrote: On 23 Mar 2015, at 13:56, Brad Jorsch (Anomie) bjorsch@wikimedia.org wrote:
On Mon, Mar 23, 2015 at 3:08 AM, Krinkle krinklemail@gmail.com wrote: Nothing is loaded by default.
If you make use of interfaces provided by a module, you must add a dependency on that module.
I must have misunderstood something. If all dependencies have to be declared then why does ResourcesTest::testIllegalDependencies() explicitly complain about 'jquery' and 'mediawiki'?
jquery and mediawiki are not modules. They are raw files leveraging parts of ResourceLoader to deliver itself
Ah, there's the confusion. Despite being in Resources.php in the same data structure and in the same format as all (other) modules, and being named by a method named "getStartupModules", and being delivered via the usual module loader script where they're specified as "modules=jquery%2Cmediawiki", and generally being referred to as "modules" in code comments and so on, you don't consider them modules because they're loaded specially by the bootstrapping "module"[1] and aren't passed to mw.loader.register().
[1]: I'm guessing 'startup', implemented by ResourceLoaderStartUpModule, is not a module either by your definition.
That is accurate.
This predates my involvement somewhat, but as a low priority task I've been meaning to abstract this further. However every time I tried it seems to only add infrastructure without added value. The terminology and comments around it could do with improvement. But abstracting the implementation away from using load.php?modules= and Module subclasses in PHP wouldn't improve it.
-- Krinkle
mediawiki-api@lists.wikimedia.org