Skip to content

Commit 3812c59

Browse files
committed
Add realative path example
1 parent 4b21af1 commit 3812c59

File tree

9 files changed

+597
-0
lines changed

9 files changed

+597
-0
lines changed

relative-path/almond.js

Lines changed: 255 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
1+
/**
2+
* almond 0.0.2+ Copyright (c) 2011, The Dojo Foundation All Rights Reserved.
3+
* Available via the MIT or new BSD license.
4+
* see: http://github.com/jrburke/almond for details
5+
*/
6+
/*jslint strict: false, plusplus: false */
7+
/*global setTimeout: false */
8+
9+
var requirejs, require, define;
10+
(function () {
11+
12+
var defined = {},
13+
aps = [].slice,
14+
req;
15+
16+
if (typeof define === "function") {
17+
//If a define is already in play via another AMD loader,
18+
//do not overwrite.
19+
return;
20+
}
21+
22+
/**
23+
* Given a relative module name, like ./something, normalize it to
24+
* a real name that can be mapped to a path.
25+
* @param {String} name the relative name
26+
* @param {String} baseName a real name that the name arg is relative
27+
* to.
28+
* @returns {String} normalized name
29+
*/
30+
function normalize(name, baseName) {
31+
//Adjust any relative paths.
32+
if (name && name.charAt(0) === ".") {
33+
//If have a base name, try to normalize against it,
34+
//otherwise, assume it is a top-level require that will
35+
//be relative to baseUrl in the end.
36+
if (baseName) {
37+
//Convert baseName to array, and lop off the last part,
38+
//so that . matches that "directory" and not name of the baseName's
39+
//module. For instance, baseName of "one/two/three", maps to
40+
//"one/two/three.js", but we want the directory, "one/two" for
41+
//this normalization.
42+
baseName = baseName.split("/");
43+
baseName = baseName.slice(0, baseName.length - 1);
44+
45+
name = baseName.concat(name.split("/"));
46+
47+
//start trimDots
48+
var i, part;
49+
for (i = 0; (part = name[i]); i++) {
50+
if (part === ".") {
51+
name.splice(i, 1);
52+
i -= 1;
53+
} else if (part === "..") {
54+
if (i === 1 && (name[2] === '..' || name[0] === '..')) {
55+
//End of the line. Keep at least one non-dot
56+
//path segment at the front so it can be mapped
57+
//correctly to disk. Otherwise, there is likely
58+
//no path mapping for a path starting with '..'.
59+
//This can still fail, but catches the most reasonable
60+
//uses of ..
61+
break;
62+
} else if (i > 0) {
63+
name.splice(i - 1, 2);
64+
i -= 2;
65+
}
66+
}
67+
}
68+
//end trimDots
69+
70+
name = name.join("/");
71+
}
72+
}
73+
return name;
74+
}
75+
76+
function makeRequire(relName, forceSync) {
77+
return function () {
78+
//A version of a require function that passes a moduleName
79+
//value for items that may need to
80+
//look up paths relative to the moduleName
81+
return req.apply(null, aps.call(arguments, 0).concat([relName, forceSync]));
82+
};
83+
}
84+
85+
function makeNormalize(relName) {
86+
return function (name) {
87+
return normalize(name, relName);
88+
};
89+
}
90+
91+
function makeLoad(depName) {
92+
return function (value) {
93+
defined[depName] = value;
94+
};
95+
}
96+
97+
/**
98+
* Makes a name map, normalizing the name, and using a plugin
99+
* for normalization if necessary. Grabs a ref to plugin
100+
* too, as an optimization.
101+
*/
102+
function makeMap(name, relName) {
103+
var prefix, plugin,
104+
index = name.indexOf('!');
105+
106+
if (index !== -1) {
107+
prefix = normalize(name.slice(0, index), relName);
108+
name = name.slice(index + 1);
109+
plugin = defined[prefix];
110+
111+
//Normalize according
112+
if (plugin && plugin.normalize) {
113+
name = plugin.normalize(name, makeNormalize(relName));
114+
} else {
115+
name = normalize(name, relName);
116+
}
117+
} else {
118+
name = normalize(name, relName);
119+
}
120+
121+
//Using ridiculous property names for space reasons
122+
return {
123+
f: prefix ? prefix + '!' + name : name, //fullName
124+
n: name,
125+
p: plugin
126+
};
127+
}
128+
129+
function main(name, deps, callback, relName) {
130+
var args = [],
131+
usingExports,
132+
cjsModule, depName, i, ret, map;
133+
134+
//Use name if no relName
135+
if (!relName) {
136+
relName = name;
137+
}
138+
139+
//Call the callback to define the module, if necessary.
140+
if (typeof callback === 'function') {
141+
//Pull out the defined dependencies and pass the ordered
142+
//values to the callback.
143+
if (deps) {
144+
for (i = 0; i < deps.length; i++) {
145+
map = makeMap(deps[i], relName);
146+
depName = map.f;
147+
148+
//Fast path CommonJS standard dependencies.
149+
if (depName === "require") {
150+
args[i] = makeRequire(name);
151+
} else if (depName === "exports") {
152+
//CommonJS module spec 1.1
153+
args[i] = defined[name] = {};
154+
usingExports = true;
155+
} else if (depName === "module") {
156+
//CommonJS module spec 1.1
157+
cjsModule = args[i] = {
158+
id: name,
159+
uri: '',
160+
exports: defined[name]
161+
};
162+
} else if (depName in defined) {
163+
args[i] = defined[depName];
164+
} else if (map.p) {
165+
map.p.load(map.n, makeRequire(relName, true), makeLoad(depName), {});
166+
args[i] = defined[depName];
167+
}
168+
}
169+
}
170+
171+
ret = callback.apply(defined[name], args);
172+
173+
if (name) {
174+
//If setting exports via "module" is in play,
175+
//favor that over return value and exports. After that,
176+
//favor a non-undefined return value over exports use.
177+
if (cjsModule && cjsModule.exports !== undefined) {
178+
defined[name] = cjsModule.exports;
179+
} else if (!usingExports) {
180+
//Use the return value from the function.
181+
defined[name] = ret;
182+
}
183+
}
184+
} else if (name) {
185+
//May just be an object definition for the module. Only
186+
//worry about defining if have a module name.
187+
defined[name] = callback;
188+
}
189+
}
190+
191+
requirejs = req = function (deps, callback, relName, forceSync) {
192+
if (typeof deps === "string") {
193+
194+
//Just return the module wanted. In this scenario, the
195+
//deps arg is the module name, and second arg (if passed)
196+
//is just the relName.
197+
//Normalize module name, if it contains . or ..
198+
return defined[makeMap(deps, callback).f];
199+
} else if (!deps.splice) {
200+
//deps is a config object, not an array.
201+
//Drop the config stuff on the ground.
202+
if (callback.splice) {
203+
//callback is an array, which means it is a dependency list.
204+
//Adjust args if there are dependencies
205+
deps = callback;
206+
callback = arguments[2];
207+
} else {
208+
deps = [];
209+
}
210+
}
211+
212+
//Simulate async callback;
213+
if (forceSync) {
214+
main(null, deps, callback, relName);
215+
} else {
216+
setTimeout(function () {
217+
main(null, deps, callback, relName);
218+
}, 15);
219+
}
220+
221+
return req;
222+
};
223+
224+
/**
225+
* Just drops the config on the floor, but returns req in case
226+
* the config return value is used.
227+
*/
228+
req.config = function () {
229+
return req;
230+
};
231+
232+
/**
233+
* Export require as a global, but only if it does not already exist.
234+
*/
235+
if (!require) {
236+
require = req;
237+
}
238+
239+
define = function (name, deps, callback) {
240+
241+
//This module may not have dependencies
242+
if (!deps.splice) {
243+
//deps is not an array, so probably means
244+
//an object literal for the value. Adjust args.
245+
callback = deps;
246+
deps = [];
247+
}
248+
249+
main(name, deps, callback);
250+
};
251+
252+
define.amd = {
253+
jQuery: true
254+
};
255+
}());

relative-path/bootstrap.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
require(['js/foo'], function(foo){
2+
alert(foo.name);
3+
});

0 commit comments

Comments
 (0)