Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

With requirejs is it possible to check if a module is defined without attempting to load it?

Tags:

requirejs

I want to be able to optionally define a module and then use it or not in my code. The particular situation I'm considering is loading mock/stub modules in the debug/test environment but not when I go live. Here is the example:

In the html file the js files would be optionally loaded (pseudo code):

//index.cshtml
...
<script src="/Scripts/lib/require.js"></script>
<script src="/Scripts/app/service_user.js"></script>
<script src="/Scripts/app/real_service.js"></script>
#if DEBUG
<script src="/Scripts/app/mock_service.js"></script>
#endif

In the above both real_service and mock_service must be loaded in the debug version.

Each module would be defined using requirejs, eg:

//mock_service.js
define('mock_service', [], 
    function () {
        ...
    });

//real_service.js
define('real_service', [], 
    function () {
        ...
    });

Then when using the service I'd like to check if the mock_service has been defined:

//service_user.js
define(['require', 'real_service'], 
    function (require, real_service) {
        if (require.isDefined('mock_service')) { // 'isDefined' is what I wish was available
             var mock = require('mock_service');
             mock.init(real_service);
        }

        ...
    });

So my notional 'isDefined' function would just check for a module with the given name (or names?) having been defined. Then in my code, if it is defined I can require it and use it. If not, then that is fine too.

The important thing for me is that no attempt is made to load the optional module. I could try/catch around the require statement but that would cause an attempt to load it from the server and I don't want that.

Another option would be to have a stub define that I always load and so there is always a mock to require which I can then interrogate as to whether it is the real one or not but that seems wasteful too.

Is there any one out there that is deeply in to require.js that has found that they need this functionality and have worked out a strategy for implementation?

Thank you in advance, Rob

like image 716
WooWaaBob Avatar asked Feb 13 '13 10:02

WooWaaBob


People also ask

Is RequireJS still relevant?

RequireJS has been a hugely influential and important tool in the JavaScript world. It's still used in many solid, well-written projects today.

What is a RequireJS module?

RequireJS loads each dependency as a script tag, using head. appendChild(). RequireJS waits for all dependencies to load, figures out the right order in which to call the functions that define the modules, then calls the module definition functions once the dependencies for those functions have been called.

What is the use of RequireJS?

RequireJS is a JavaScript library and file loader which manages the dependencies between JavaScript files and in modular programming. It also helps to improve the speed and quality of the code.

How do I call a function in RequireJS?

2 Answers. Show activity on this post. require(["jquery"], function ($) { function doStuff(a, b) { //does some stuff } $('#the-button'). click(function() { doStuff(4, 2); }); });


2 Answers

I was just looking for this myself, the require global has a "defined" method on it which takes a module name and returns true or false.

// returns true
require.defined("my/awesome/defined/module");

// returns false
require.defined("not/yet/loaded");
like image 92
David Wolf Avatar answered Oct 11 '22 02:10

David Wolf


Although David Wolf's answer was close to the mark it didn't fully meet my needs.

The problem is that require asynchronously resolves requirements so in the in the example I gave and using David's suggestion require.defined('mock_service') will return false because although it has been specified it has not yet been resolved.

When investigating this I did find another function specified. In the example require.specified('mock_service') will return true but then trying to get a reference using require('mock_service') fails because it hasn't yet been resolved.

That, fortunately, is easily fixed by using the callback version of require. Putting it all together we have:

if (require.specified('mock_service')) {
    require( [ 'mock_service' ], function (mock) {
         mock.init(real_service);
    });
}

@David Wolf - thanks, would not have got there without your help.

like image 47
WooWaaBob Avatar answered Oct 11 '22 01:10

WooWaaBob