Getting SharePoint to do more can’t easily be done without JavaScript and is mostly accomplished by loading the JavaScript from each page individually or from the master page.  Without a functionality implementation of modular code, either of these methods becomes tedious and hard to maintain.

Why RequireJS on SharePoint?

The short sales pitch in favor of RequireJS can be summarized in these points –

  • On demand asynchronous loading of JavaScript libraries.
  • Modular Client-Side Code.
  • All client-side code is manged in one place (Source controlled).

Getting Started

Generally the most inclusive starting point is the Master Page, because this (by default) is shared by sites and sub-sites of a site collection.

Minimal Download Strategy (MDS) and RequireJS don’t mix

Because MDS loads only the parts of a page i.e. the parts that are different for each page, Realmen.gifRequireJS runs into some trouble with the relative paths when loading different pages. For this reason, when implementing RequireJS on non-publishing infrastructure this feature should be disabled; however when publishing is-enabled, MDS feature becomes unavailable. (Read more on MDS…)

SharePoint Master Page

Out of the box SharePoint 2013 master page location is :

/_catalogs/masterpage/seattle.master

Add  a good-old-fashioned tag since “SharePoint:ScriptLink” has no support for a “data-main” attribute with one or two other caveats for this approach as well.



   type = "text/javascript" 

   data-main = "/Style Library/sharetip/on.jssrc = "/Style%20Library/sharetip/LIB/require.js" >


What gives above?

  • [type]
    This is the Internet Media Type and for the most part obsolete. (Read More…).
  • [data-main]
    Is needed (not “required” by RequireJS) [ha-ha] to indicate the starting point of the client-side code. The value of data-main shown above as :

/Style Library/sharetip/on.js
This is the site relative path to the start of the client-side code.

  • [src]
    Do not confuse the src attribute with the data-main attribute.  src is there to tell browsers where to obtain require.js from; The data-main attribute is used by RequireJS on where to find the start of the client side application.

RequireJS, data-main gets client-side going

Again, why do we like RequireJS? Because it presents us with the ability to write or use modular generated code as well as improve the ability to load scripts on an on-demand basis.

Starting at the start of the client-side code; the main starting point is “on.js“, in most other examples this is shown as app.js or main.js – it really doesn’t matter what it is called, as long as it corresponds with the value specified within the data-main attribute.

data-main = "/Style Library/sharetip/on.js"

When RequireJS loads the file on.js; RequireJS can be “fed” additional parameters.  The primary method “.config” as well as “.onError” is called from within “on.js” –

require.onError();
require.config();

 

Remember that .onError() is loaded first, to tell require what to do when an error occurs –

Example of “require.onError()” added to “on.js“:

require.onError = function (err)
{
    if (console) {               //Console is open
        console.log('Type of Require Error:');    
        console.log(err.requireType);
        console.log('Require Error Message:');
        console.log(err.message);
 
        switch (err.requireType) {
            case 'timeout':       //Timeout loading a module
                console.log('Require Timeout');
                break;
            case 'scripterror':
                console.log('Require Script Error'); //error
                break;
            default:
                console.log('REQUIREJS Error: ' + err.message);
                break;
        }
    }
};

Example of “require.config()” added to “on.js

require.config( {
  'urlArgs': "sharetipon=v1",
  'baseUrl': '/Style%20Library/sharetip',
  'paths': {
             jquery: ['LIB/jquery-1.10.2.min'],
             bootstrap: ['LIB/bootstrap.min'],
             on: ['on'] },
   shim: {
             'bootstrap': ['jquery']
        }
});

define(['jquery', 'on'], function ($, on){ 
   alert('YaY I have a client-side program');
   on.go();  //Another article discusses Namespaces and external modules
});

  • urlArgs

Without this entry, think “Caching problems…“.  Some sites recommend using this entry in a development environment to add the date/time.  Adding the date and time gives the browser a unique variable each time; thus refreshing the local cache each time. This is what the entry looks like for a development environment:

urlArgs‘: “sharetipon=” + new Date().getTime(),

Using this on a “production” environment, ensure that a controllable version is added to the key-value-pair since refreshing the file in the cache each time over the internet is not practical. Remember to increment v1 each time a new version is released, how the number is done is up to you.

urlArgs‘: “sharetipon=v1”,

  • baseUrl

The baseUrl is the default top-most folder for the client-side application. Any key-value-pair specified in the path property uses the baseUrl to figure out where it is located.

  • paths

Each module that is loaded (when needed) by the client-side code can either be specified later within the code or here at the beginning within the .config() method.

jquery: [‘LIB/jquery-1.10.2.min’],

This entry indicates that jquery is loaded and this is where it is located.  Take special notice of the fact that this entry does not end with .js; additional reading on implementing jquery with RequireJS is available here….

  • shim

Shim, in a nutshell describes the load dependencies within modules that do not support Asynchronous Module Definition (AMD).  Want to know more about shim’ing? Read more here…

Very useful tip:

When loading other JavaScript Libraries through AMD (Require.JS) those libraries often include there on define([‘module’]) dependencies.  DO NOT attempt to load these libraries manually, but use the packages option given by require.

The below example shows how to easily add JQGrid using Require.JS.

 packages: [{
              name: 'jqGrid',
              location: 'LIB/jqgrid/js/',
              main: 'jquery.jqGrid.min'
 }],

Some more reading can be done here as well.

 

 

 

ShareTipOn – Sharing those things that can make life easier.

Advertisements