User:Evad37/Script modules

From Wikipedia, the free encyclopedia

Script libraries are bits of Javascript code intended to be easily reused by userscripts.

The basics[edit]

Script libraries add an object to the Window object. This object contains one or more pieces of code intended to be used by other scripts – typically functions or classes.

Window.libSomethingUseful = {
    doThis: function(param) { 
        // ...
        return something;
    },
    doThat: function(p1, p2) {
        // ...
        return somethingElse;
    }
}

The name used should be quite unique, and unlikely to be unintentionally overridden by other scripts.

To minimise the number of network requests, related functionality should all be contained within a single module, rather than several small modules. To minimise the size of network requests, unrelated functionality should be split between separate modules, rather than one huge module.

Dependencies[edit]

Script libraries should, if possible, avoid having dependencies themselves. This allows scripts to easily use them:

mw.loader.getScript( /* script url */ ).then(function() {
    // the library is now available on the Window object
    // ...
} );

If necessary, then there are two options for handling dependencies:

  1. Specify dependencies in the documentation, and require scripts loading the library to be responsible for loading dependencies:
    mw.loader.using( /* dependencies */ ).then(function(
        mw.loader.getScript( /* script url */ ).then(function() {
            // the library is now available on the Window object
            // ...
        } );
    } );
    
  2. Load dependencies within the library itself, and attach a Promise/Deferred object to the window. Script using the library will need to access it using something like
    mw.loader.getScript( /* script url */ ).then(function() {
        // A Promise is now available on the window object. 
        $.when( /* library Promise */ ).then(function(libraryName) { // script gets to decide what to call the library
            // the library is now available, as a variable scoped to this function
            // ...
        } );
    } );
    

Test cases[edit]

Should be required. Requires a little bit of effort to set up, but invaluable for making changes/updates much less likely to break things. Which could break a lot of things for a lot of users, if the library becomes widely used. Examples using QUnit: User:Evad37/rater/test.js, User:Evad37/Covery/sandbox.js

Pseudo-namespace?[edit]

Should script modules be stored in a pseudo-namespace like MediaWiki:Script module/? This means that only code approved by Interface Admins can be exported to other scripts, who could require non-minor updates to pass a WP:Code review.

Module authors wanting to add or update a script module would use an edit request, or post a request at the Interface administrators' noticeboard.

  • Advantages: Less likely to break things; better security
  • Disadvantages: More bureaucracy; likely take longer for bugs to be fixed; harder for non-intAdmin authors to maintain their stuff

Library ideas[edit]

  • API helper. Make working with returned values easier – extracting response page or pages from the response data structure; format an error message from the response parameters; etc. Stuff I'm doing in XFDcloser which could be used more generally.
  • OOUI helper. Multibutton confirm window like XFDcloser; open a process dialog with only a few lines of code, rather than the current method of having to create a whole new class per mw:OOUI/Windows/Process Dialogs; custom widgets I've made for various scripts
  • Wikitext parsing. Stuff that can actually be a bit tricky, like parsing dates, signatures, and especially templates.