Redsandro
Redsandro

Reputation: 11356

RequireJS require() cannot resolve file names at the same subdirectory level

I've got a directory structure like so:

app/
├ js/
│ ├ gui/
│ │ ├ main.js
│ │ └ santa.js
│ └ app.js
└ index.html <- includes requirejs and starts js/app.js

app.js:

baseUrl: 'js' // Pseudo-code for requirejs.config() of course
require('gui/main');

So far so good. But every same-dir require() in main.js gives problems:

main.js:

require('santa')

Tries to require() app/js/santa.js which does not exist.

require('./santa')

Tries to require() app/js/santa.js which does not exist.

require('gui/santa')

Tries to require() app/js/gui/gui/santa.js which does not exist.

require('./gui/santa')

Tries to require() app/js/gui/gui/santa.js which does not exist.

wtf

The only way I seem to get my file to be included is like this:

require('js/gui/santa.js')

which kind of defeats the purpose of name resolving and the baseUrl setting.


Apart from this weirdness, I'd like to have the baseUrl changed to js/gui for any require() within main.js. The configuration is supposed to be extensible and overwritable. But when I do:

requirejs.config({
    baseUrl     : 'js/layout'
});

within main.js, the new setting seems to be ignored like politicians ignore their own promises.

Upvotes: 1

Views: 1360

Answers (1)

Chris
Chris

Reputation: 6095

Have you tried using define instead of require?

Define can be called like this:

define('folder/main',
        [ "jquery", './AnotherModule' ],
        function($, AnotherModule) {});

The first parameter is the module name - an explicit path to the module. Normally, you wouldn't include the first parameter - define() always implicitly specifies a path, and in general using an explicit path is not recommended.

Require, on the other hand, does not take a name parameter. It's not possible to do a path relative to a source file with just require()'s and no define()'s, because require does not 'create' a module or define a namespace. Anything require()'d is required relative to root.

When you include a relative dependency in define() (like './AnotherModule'), it's found relative to the module name. In the above case, ./AnotherModule would resolve to folder/AnotherModule.

In a call to require(), there is no module name. Relative dependencies are resolved to the root.


In your case, this would account for the behavior of require('santa') and require('./santa'). My only guess as to why gui is not acting in the same manner is that, since it includes a subdirectory, it's handled differently. Try using require('strange-new-directory/santa') to see if you can get some more insight on the situation.


As for baseUrl resetting, baseUrl is, I believe, a global trait and can't be reset midstream (or at least, I wouldn't recommend doing it). You should be able to get relative pathing working with the use of define. Good luck.

Upvotes: 1

Related Questions