1 |
|
2 | var fs = require('fs');
|
3 | var path = require('path');
|
4 |
|
5 |
|
6 | var resv = require('resolve');
|
7 |
|
8 |
|
9 |
|
10 | function nodeModulesPaths (start, cb) {
|
11 | var splitRe = process.platform === 'win32' ? /[\/\\]/ : /\/+/;
|
12 | var parts = start.split(splitRe);
|
13 |
|
14 | var dirs = [];
|
15 | for (var i = parts.length - 1; i >= 0; i--) {
|
16 | if (parts[i] === 'node_modules') continue;
|
17 | var dir = path.join(
|
18 | path.join.apply(path, parts.slice(0, i + 1)),
|
19 | 'node_modules'
|
20 | );
|
21 | if (!parts[0].match(/([A-Za-z]:)/)) {
|
22 | dir = '/' + dir;
|
23 | }
|
24 | dirs.push(dir);
|
25 | }
|
26 | return dirs;
|
27 | }
|
28 |
|
29 |
|
30 |
|
31 | function load_shims(paths, cb) {
|
32 |
|
33 |
|
34 | var shims = {};
|
35 |
|
36 | (function next() {
|
37 | var cur_path = paths.shift();
|
38 | if (!cur_path) {
|
39 | return cb(null, shims);
|
40 | }
|
41 |
|
42 | var pkg_path = path.join(cur_path, 'package.json');
|
43 |
|
44 | fs.readFile(pkg_path, 'utf8', function(err, data) {
|
45 | if (err) {
|
46 |
|
47 |
|
48 | if (err.code === 'ENOENT') {
|
49 | return next();
|
50 | }
|
51 |
|
52 | return cb(err);
|
53 | }
|
54 |
|
55 | try {
|
56 | var info = JSON.parse(data);
|
57 | }
|
58 | catch (err) {
|
59 | err.message = pkg_path + ' : ' + err.message
|
60 | return cb(err);
|
61 | }
|
62 |
|
63 |
|
64 |
|
65 | if (typeof info.browserify === 'string' && !info.browser) {
|
66 | info.browser = info.browserify;
|
67 | }
|
68 |
|
69 |
|
70 | if (!info.browser) {
|
71 | return cb(null, shims);
|
72 | }
|
73 |
|
74 |
|
75 |
|
76 | if (typeof info.browser === 'string') {
|
77 | var key = path.resolve(cur_path, info.main || 'index.js');
|
78 | shims[key] = path.resolve(cur_path, info.browser);
|
79 | return cb(null, shims);
|
80 | }
|
81 |
|
82 |
|
83 | Object.keys(info.browser).forEach(function(key) {
|
84 | if (info.browser[key] === false) {
|
85 | return shims[key] = __dirname + '/empty.js';
|
86 | }
|
87 |
|
88 | var val = info.browser[key];
|
89 |
|
90 |
|
91 |
|
92 | if (val[0] === '.') {
|
93 | val = path.resolve(cur_path, val);
|
94 | }
|
95 |
|
96 |
|
97 | if (key[0] !== '/' && key[0] !== '.') {
|
98 | return shims[key] = val;
|
99 | }
|
100 |
|
101 | var key = path.resolve(cur_path, key);
|
102 | shims[key] = val;
|
103 | });
|
104 | return cb(null, shims);
|
105 | });
|
106 | })();
|
107 | };
|
108 |
|
109 | function resolve(id, opts, cb) {
|
110 |
|
111 |
|
112 |
|
113 |
|
114 |
|
115 |
|
116 | opts = opts || {};
|
117 |
|
118 | var base = path.dirname(opts.filename);
|
119 | var paths = nodeModulesPaths(base);
|
120 |
|
121 | if (opts.paths) {
|
122 | paths.push.apply(paths, opts.paths);
|
123 | }
|
124 |
|
125 | paths = paths.map(function(p) {
|
126 | return path.dirname(p);
|
127 | });
|
128 |
|
129 |
|
130 | load_shims(paths, function(err, shims) {
|
131 | if (err) {
|
132 | return cb(err);
|
133 | }
|
134 |
|
135 | if (shims[id]) {
|
136 |
|
137 | if (shims[id][0] === '/') {
|
138 | return cb(null, shims[id], opts.package);
|
139 | }
|
140 |
|
141 |
|
142 | id = shims[id];
|
143 | }
|
144 |
|
145 | var modules = opts.modules || {};
|
146 | var shim_path = modules[id];
|
147 | if (shim_path) {
|
148 | return cb(null, shim_path);
|
149 | }
|
150 |
|
151 |
|
152 |
|
153 | var full = resv(id, {
|
154 | paths: opts.paths,
|
155 | extensions: opts.extensions,
|
156 | basedir: base,
|
157 | package: opts.package,
|
158 | packageFilter: function(info) {
|
159 | if (opts.packageFilter) info = opts.packageFilter(info);
|
160 |
|
161 |
|
162 | if (typeof info.browserify === 'string' && !info.browser) {
|
163 | info.browser = info.browserify;
|
164 | }
|
165 |
|
166 |
|
167 | if (!info.browser) {
|
168 | return info;
|
169 | }
|
170 |
|
171 |
|
172 | if (typeof info.browser === 'string') {
|
173 | info.main = info.browser;
|
174 | return info;
|
175 | }
|
176 |
|
177 | var replace_main = info.browser[info.main || './index.js'];
|
178 | info.main = replace_main || info.main;
|
179 | return info;
|
180 | }
|
181 | }, function(err, full, pkg) {
|
182 | if (err) {
|
183 | return cb(err);
|
184 | }
|
185 |
|
186 | var resolved = (shims) ? shims[full] || full : full;
|
187 | cb(null, resolved, pkg);
|
188 | });
|
189 | });
|
190 | };
|
191 |
|
192 | module.exports = resolve;
|
193 |
|