0

Problem is pretty straightforward, here is the test code I wrote for this case.

App

<aura:application >
    <aura:handler event="c:RequireJSEvent" action="{!c.initJS}"/>
    <aura:registerEvent type="c:RequireJSEvent" name="requireJSEvent"/>
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" /> 
</aura:application>

Controller

({
    doInit : function(cmp, event, helper) {
        console.log("doinit");
        if (typeof require !== "undefined") {
            var evt = $A.get("e.c:RequireJSEvent");
            evt.fire();
        } else {
            var head = document.getElementsByTagName('head')[0];
            var script = document.createElement('script');

            script.src = "/resource/RequireJS"; 
            script.type = 'text/javascript';
            script.key = "/resource/RequireJS"; 
            script.helper = this;
            script.id = "script_" + cmp.getGlobalId();
            var hlp = helper;
            script.onload = function scriptLoaded(){
                var evt = $A.get("e.c:RequireJSEvent");
                evt.fire();
            };
            head.appendChild(script);
        }
    },
    initJS : function(component, event, helper){
        require.config({
            paths: {
                "jquery": "/resource/jquery?"
            }
        });
        console.log("RequiresJS has been loaded? "+(require !== "undefined"));
        //loading libraries sequentially
        require(["jquery"], function($) {
            console.log("jQuery has been loaded? "+($ !== "undefined"));
        });//require end
    }
})

Console output with LockerService on LS bug

Console output without LockerService on LS not on

I have a feeling the access check warning might have to do something with this, but I'm not sure..

1

The access check exception is because your onload callback is not wrapped inside $A.getCallback() so when it gets called the required Lightning context does not get re-established. Access control enforcemernt is not part of LockerService though and this code should fail with or without LS activated.

Try this simople change:

script.onload = $A.getCallback(function scriptLoaded(){
   var evt = $A.get("e.c:RequireJSEvent");
   evt.fire();
});

See https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/js_cb_mod_ext_js.htm for more details.

BTW why not just use ltng:require - the native Lightning component that supports dynamic loading, once and only once semantics, is the only Salesforce Security approved mechanism for including JS/CSS, etc? ltng:require also handles both CSS and Javascript resources and already has afterScriptsLoaded event model that is aware of the Lightning component rendering lifecycle, supports $Resource, automatically sets the base URL when running in a Community, and much more.

  • Sounds a lot like your last paragraph should be more a statement of best practice than of inquiring. Is there any valid use to side loading script/css like this with LC? Is the Security seal of approval an AppEx relevant thing only or will this (using createElement for script/link) eventually be blocked by Locker Service? – drakored Jun 14 '16 at 12:49
  • Tried this change, the onload still does not get called. Tried using ltng:require as well, but it still had major issues. For example, I load jquery, then another library that requires jquery to work, and it throws an error saying $ is not defined. – Jason Lee Jun 14 '16 at 19:52
  • drakored this is already formally documented. LS will not be blocking dynamic creation of script tags now or in the future though and the security reasons for creating ltng:require go away with LS but the sequencing and timing part is still extremely valuable since no 3rd party loader is LC init/render lifecycle savvy. – Doug Chasman Jun 15 '16 at 10:52
  • Jason there are a number of variables unaccounted for - can we see the actual example using ltng:require? What version of jQuery etc are you using? Please open a support case and provide the case ID here so we can get a jump on it. There are many successful users of jQuery under LS but some older versions of various libraries have issues. – Doug Chasman Jun 15 '16 at 10:54
  • @DougChasman I've been unable to successfully include and use RequireJs using ltng:require with LS turned on. I noticed that if I modify Require to set window.require, it is then available on the window and I can reference it in other javascript files. What is the recommended way to export an API from a module that is loaded through ltng:require? – jwolf Nov 2 '16 at 19:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.