Skip to content

Instantly share code, notes, and snippets.

@aaronj1335
Created May 11, 2012 15:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aaronj1335/2660344 to your computer and use it in GitHub Desktop.
Save aaronj1335/2660344 to your computer and use it in GitHub Desktop.
relative paths in AMD

Given a project with the files below and a directory structure as follows:

$ tree --charset ascii
.
|-- index.html
|-- js
|   |-- components
|   |   `-- vendor
|   |       |-- jquery-1.7.2.js
|   |       |-- jquery.js
|   |       `-- test.js
|   |-- order.js
|   `-- require.js
`-- nested
    `-- path
        `-- index.html -> ../../index.html

5 directories, 7 files

Note that the file names are below, but the directory structure is not preserved since github gist's don't allow subduers. The directory is served statically (using something like python -m SimpleHTTPServer), with the require.js config set with baseUrl: '/js' and the following URLs are visited:

http://127.0.0.1:8000/
http://127.0.0.1:8000/nested/path/

Here the page load works, but there are two gotchas:

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>RequireJS relative path</title>
</head>
<body>
<script src="/js/require.js"></script>
<script>
require.config({baseUrl: '/js'});
</script>
<script>
require(['components/vendor/test'], function() { });
</script>
</body>
</html>
<!-- same as nested/path/index.html -->
define([
'order!./jquery-1.7.2'
], function() {
return window.jQuery;
});
// note the 'define' call instead of 'require'
define([
'./jquery'
], function($) {
if (! $) {
throw Error('jQuery is not defined');
}
});
@justinbmeyer
Copy link

Since the module ID for foo/c.js is 'c', then its require call is resolved as looking like 'c/./b', which is 'b', which then just gets mapped to baseUrl + 'b.js'.

Does this mean it will load incorrectly (baseUrl/b.js is wrong)? My guess is that you meant there's a double mapping, first from b to c, then from c to the base url.

James, if I'm correct in this, why can't the global require still load relative paths? For steal, we assume paths without any prefix [/, ./, etc] are relative to the base url. Isn't requirejs the same way? For example, no matter where I am:

steal('jquery.js')

always does baseUrl/jquery.js. require(['jquery']) will always look in the baseUrl?

Thanks!

@jrburke
Copy link

jrburke commented May 11, 2012

@aaronj1335: yes sounds like you have it worked out now. Typically the entry point JS file is effectively "global" in that it is in the baseUrl, so relative paths are not needed for it, and using require() in there is fine instead of define. If you use data-main="" then the entry point script can use define().

@justinbmeyer: I should have kept going in that example, there is no double mapping. It will want to load it from baseUrl/b.js, since it resolved the relative ID relative to another ID, not a path. This is done because it would not make sense to encode path names in a built file -- those are also meant to be combined with other modules, and they expect to find modules at ID values, not path values.

Your example is correct: saying require(['jquery']) will load from baseUrl/jquery.js (unless of course there is a paths config that says otherwise). So, a global require can use './jquery' relative path, it is just relative to baseUrl.

@justinbmeyer
Copy link

justinbmeyer commented May 12, 2012 via email

@jrburke
Copy link

jrburke commented May 12, 2012

@justinbmeyer: correct. That pattern is what I am using now for this project template:
https://github.com/volojs/create-responsive-template/blob/master/www/js/app.js

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment