Powerswitch
Powerswitch

Reputation: 187

load module in requirejs only in browser, not in nodejs

I wrote modules for both browser and nodejs using requirejs.

Everything works fine, but I want to include a module just for the browser, not for node as I don't need it and it would not work in node. (It's just a fancy design library for the browser).

My code looks like this:

define([
    'requirement',
    'libs/fancy'
], function(Requirement, fancy) {
    // do stuff
});

fancy is the lib that I don't want in node. So I could write a workaround like this:

if (typeof window !== 'undefined') { // cheap detection of browser/node
    define([
        'requirement',
        'libs/fancy'
    ], start);
} else {
    define([
        'requirement'
    ], start);
}

function start(Requirement, Fancy) {
    // do stuff
}

But obviously this is ugly. Does anyone know a better way to do it?

-- EDIT 1:

var requirements = ['requirement'];

if (typeof window !== 'undefined') {
    requirement.push('libs/fancy');
}

define(requirements, function(Requirement, Fancy) {
    // do stuff
}

Still not perfect

Upvotes: 1

Views: 494

Answers (1)

Louis
Louis

Reputation: 151401

I've sometimes used the second method you show of creating an array of dependencies on which I push depending on what I need.

There's another method, however, that I've used when I don't want to modify the list of dependencies. Presumably the code inside your module will have to work with an undefined value for Fancy. So you could use something like what follows. The idea is to configure RequireJS to load a module that returns an undefined value when loaded. This way you don't need to modify your dependency list. It just needs to be able to handle a case where Fancy is undefined.

var requirejs = require("requirejs");

// Create a fake module that we name immediately as "undefined".
requirejs.define("undefined", [], function () { return undefined; });

var req = requirejs.config({
    map: {
        // Make it so that all requests for `foo` load `undefined` instead.
        "*": {
            foo: "undefined"
        }
    }
});

req(["foo"], function (foo) {
    console.log(foo);
});

The example above maps foo to undefined so when console.log executes, the value on the console is undefined. In your own code you'd map libs/fancy to undefined.

A variation on this method would be to have the undefined module return an object which shows the same interface as the real library but does nothing. This would avoid having to test whether Fancy is defined or not inside your module. I'd call the fake module something else than undefined though. Maybe something like fake-fancy.

Upvotes: 1

Related Questions