-
Notifications
You must be signed in to change notification settings - Fork 698
/
node.js
172 lines (148 loc) · 6.53 KB
/
node.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
//Explicity not strict since this file contains an eval call, and do not want
//to enforce strict on code evaluated that way. See
//https://github.com/requirejs/r.js/issues/774
/*jslint regexp: false, sloppy: true*/
/*global require: false, define: false, requirejsVars: false, process: false */
/**
* This adapter assumes that x.js has loaded it and set up
* some variables. This adapter just allows limited RequireJS
* usage from within the requirejs directory. The general
* node adapater is r.js.
*/
(function () {
var nodeReq = requirejsVars.nodeRequire,
req = requirejsVars.require,
def = requirejsVars.define,
fs = nodeReq('fs'),
path = nodeReq('path'),
vm = nodeReq('vm'),
//In Node 0.7+ existsSync is on fs.
exists = fs.existsSync || path.existsSync,
hasOwn = Object.prototype.hasOwnProperty;
function hasProp(obj, prop) {
return hasOwn.call(obj, prop);
}
function syncTick(fn) {
fn();
}
function makeError(message, moduleName) {
var err = new Error(message);
err.requireModules = [moduleName];
return err;
}
//Supply an implementation that allows synchronous get of a module.
req.get = function (context, moduleName, relModuleMap, localRequire) {
if (moduleName === "require" || moduleName === "exports" || moduleName === "module") {
context.onError(makeError("Explicit require of " + moduleName + " is not allowed.", moduleName));
}
var ret, oldTick,
moduleMap = context.makeModuleMap(moduleName, relModuleMap, false, true);
//Normalize module name, if it contains . or ..
moduleName = moduleMap.id;
if (hasProp(context.defined, moduleName)) {
ret = context.defined[moduleName];
} else {
if (ret === undefined) {
//Make sure nextTick for this type of call is sync-based.
oldTick = context.nextTick;
context.nextTick = syncTick;
try {
if (moduleMap.prefix) {
//A plugin, call requirejs to handle it. Now that
//nextTick is syncTick, the require will complete
//synchronously.
localRequire([moduleMap.originalName]);
//Now that plugin is loaded, can regenerate the moduleMap
//to get the final, normalized ID.
moduleMap = context.makeModuleMap(moduleMap.originalName, relModuleMap, false, true);
moduleName = moduleMap.id;
} else {
//Try to dynamically fetch it.
req.load(context, moduleName, moduleMap.url);
//Enable the module
context.enable(moduleMap, relModuleMap);
}
//Break any cycles by requiring it normally, but this will
//finish synchronously
context.require([moduleName]);
//The above calls are sync, so can do the next thing safely.
ret = context.defined[moduleName];
} finally {
context.nextTick = oldTick;
}
}
}
return ret;
};
req.nextTick = function (fn) {
process.nextTick(fn);
};
//Add wrapper around the code so that it gets the requirejs
//API instead of the Node API, and it is done lexically so
//that it survives later execution.
req.makeNodeWrapper = function (contents) {
return '(function (require, requirejs, define) { ' +
contents +
'\n}(requirejsVars.require, requirejsVars.requirejs, requirejsVars.define));';
};
req.load = function (context, moduleName, url) {
var contents, err,
config = context.config;
if (config.shim[moduleName] && (!config.suppress || !config.suppress.nodeShim)) {
console.warn('Shim config not supported in Node, may or may not work. Detected ' +
'for module: ' + moduleName);
}
if (exists(url)) {
contents = fs.readFileSync(url, 'utf8');
contents = req.makeNodeWrapper(contents);
try {
vm.runInThisContext(contents, fs.realpathSync(url));
} catch (e) {
err = new Error('Evaluating ' + url + ' as module "' +
moduleName + '" failed with error: ' + e);
err.originalError = e;
err.moduleName = moduleName;
err.requireModules = [moduleName];
err.fileName = url;
return context.onError(err);
}
} else {
def(moduleName, function () {
//Get the original name, since relative requires may be
//resolved differently in node (issue #202). Also, if relative,
//make it relative to the URL of the item requesting it
//(issue #393)
var dirName,
map = hasProp(context.registry, moduleName) &&
context.registry[moduleName].map,
parentMap = map && map.parentMap,
originalName = map && map.originalName;
if (originalName.charAt(0) === '.' && parentMap) {
dirName = parentMap.url.split('/');
dirName.pop();
originalName = dirName.join('/') + '/' + originalName;
}
try {
return (context.config.nodeRequire || req.nodeRequire)(originalName);
} catch (e) {
err = new Error('Tried loading "' + moduleName + '" at ' +
url + ' then tried node\'s require("' +
originalName + '") and it failed ' +
'with error: ' + e);
err.originalError = e;
err.moduleName = originalName;
err.requireModules = [moduleName];
throw err;
}
});
}
//Support anonymous modules.
context.completeLoad(moduleName);
};
//Override to provide the function wrapper for define/require.
req.exec = function (text) {
/*jslint evil: true */
text = req.makeNodeWrapper(text);
return eval(text);
};
}());