1 | "use strict";
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 | exports.default = void 0;
|
7 |
|
8 | var _path = _interopRequireDefault(require("path"));
|
9 |
|
10 | var _utils = require("@parcel/utils");
|
11 |
|
12 | var _micromatch = _interopRequireDefault(require("micromatch"));
|
13 |
|
14 | var _builtins = _interopRequireDefault(require("./builtins"));
|
15 |
|
16 | var _nullthrows = _interopRequireDefault(require("nullthrows"));
|
17 |
|
18 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
19 |
|
20 | function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
|
21 |
|
22 | function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
23 |
|
24 | function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
25 |
|
26 | const EMPTY_SHIM = require.resolve('./_empty');
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 | class NodeResolver {
|
42 | constructor(opts) {
|
43 | _defineProperty(this, "options", void 0);
|
44 |
|
45 | _defineProperty(this, "extensions", void 0);
|
46 |
|
47 | _defineProperty(this, "mainFields", void 0);
|
48 |
|
49 | _defineProperty(this, "packageCache", void 0);
|
50 |
|
51 | _defineProperty(this, "rootPackage", void 0);
|
52 |
|
53 | this.extensions = opts.extensions.map(ext => ext.startsWith('.') ? ext : '.' + ext);
|
54 | this.mainFields = opts.mainFields;
|
55 | this.options = opts.options;
|
56 | this.packageCache = new Map();
|
57 | this.rootPackage = null;
|
58 | }
|
59 |
|
60 | async resolve({
|
61 | filename,
|
62 | parent,
|
63 | isURL,
|
64 | env
|
65 | }) {
|
66 |
|
67 | let extensions = this.extensions.slice();
|
68 |
|
69 | if (parent) {
|
70 |
|
71 | let parentExt = _path.default.extname(parent);
|
72 |
|
73 | extensions = [parentExt, ...extensions.filter(ext => ext !== parentExt)];
|
74 | }
|
75 |
|
76 | extensions.unshift('');
|
77 |
|
78 | let module = await this.resolveModule({
|
79 | filename,
|
80 | parent,
|
81 | isURL,
|
82 | env
|
83 | });
|
84 |
|
85 | if (!module) {
|
86 | return {
|
87 | isExcluded: true
|
88 | };
|
89 | }
|
90 |
|
91 | let resolved;
|
92 |
|
93 | if (module.moduleDir) {
|
94 | resolved = await this.loadNodeModules(module, extensions, env);
|
95 | } else if (module.filePath) {
|
96 | resolved = await this.loadRelative(module.filePath, extensions, env);
|
97 | }
|
98 |
|
99 | if (resolved) {
|
100 | return {
|
101 | filePath: resolved.path,
|
102 | sideEffects: resolved.pkg && !this.hasSideEffects(resolved.path, resolved.pkg) ? false : undefined
|
103 | };
|
104 | }
|
105 |
|
106 | return null;
|
107 | }
|
108 |
|
109 | async resolveModule({
|
110 | filename,
|
111 | parent,
|
112 | isURL,
|
113 | env
|
114 | }) {
|
115 | let dir = parent ? _path.default.dirname(parent) : this.options.inputFS.cwd();
|
116 |
|
117 | if (parent) {
|
118 | filename = await this.resolveFilename(filename, dir, isURL);
|
119 | }
|
120 |
|
121 |
|
122 | filename = await this.loadAlias(filename, dir, env);
|
123 |
|
124 | if (_path.default.isAbsolute(filename)) {
|
125 | return {
|
126 | filePath: filename
|
127 | };
|
128 | }
|
129 |
|
130 | if (!this.shouldIncludeNodeModule(env, filename)) {
|
131 | return null;
|
132 | }
|
133 |
|
134 | let builtin = this.findBuiltin(filename, env);
|
135 |
|
136 | if (builtin || builtin === null) {
|
137 | return builtin;
|
138 | }
|
139 |
|
140 |
|
141 | let resolved;
|
142 |
|
143 | try {
|
144 | resolved = await this.findNodeModulePath(filename, dir);
|
145 | } catch (err) {}
|
146 |
|
147 |
|
148 |
|
149 | if (resolved === undefined) {
|
150 | let parts = this.getModuleParts(filename);
|
151 | resolved = {
|
152 | moduleName: parts[0],
|
153 | subPath: parts[1]
|
154 | };
|
155 | }
|
156 |
|
157 | return resolved;
|
158 | }
|
159 |
|
160 | shouldIncludeNodeModule({
|
161 | includeNodeModules
|
162 | }, name) {
|
163 | if (includeNodeModules === false) {
|
164 | return false;
|
165 | }
|
166 |
|
167 | if (Array.isArray(includeNodeModules)) {
|
168 | let parts = this.getModuleParts(name);
|
169 | return includeNodeModules.includes(parts[0]);
|
170 | }
|
171 |
|
172 | if (includeNodeModules && typeof includeNodeModules === 'object') {
|
173 | let parts = this.getModuleParts(name);
|
174 | let include = includeNodeModules[parts[0]];
|
175 |
|
176 | if (include != null) {
|
177 | return !!include;
|
178 | }
|
179 | }
|
180 |
|
181 | return true;
|
182 | }
|
183 |
|
184 | async resolveFilename(filename, dir, isURL) {
|
185 | switch (filename[0]) {
|
186 | case '/':
|
187 | {
|
188 |
|
189 | return _path.default.resolve(this.options.rootDir, filename.slice(1));
|
190 | }
|
191 |
|
192 | case '~':
|
193 | {
|
194 |
|
195 |
|
196 | const insideNodeModules = dir.includes('node_modules');
|
197 |
|
198 | while (dir !== this.options.projectRoot && _path.default.basename(_path.default.dirname(dir)) !== 'node_modules' && (insideNodeModules || !(await this.options.inputFS.exists(_path.default.join(dir, 'package.json'))))) {
|
199 | dir = _path.default.dirname(dir);
|
200 |
|
201 | if (dir === _path.default.dirname(dir)) {
|
202 | dir = this.options.rootDir;
|
203 | break;
|
204 | }
|
205 | }
|
206 |
|
207 | return _path.default.join(dir, filename.slice(1));
|
208 | }
|
209 |
|
210 | case '.':
|
211 | {
|
212 |
|
213 | return _path.default.resolve(dir, filename);
|
214 | }
|
215 |
|
216 | default:
|
217 | {
|
218 | if (isURL) {
|
219 | return _path.default.resolve(dir, filename);
|
220 | }
|
221 |
|
222 |
|
223 | return filename;
|
224 | }
|
225 | }
|
226 | }
|
227 |
|
228 | async loadRelative(filename, extensions, env) {
|
229 |
|
230 | let pkg = await this.findPackage(_path.default.dirname(filename));
|
231 |
|
232 | return (await this.loadAsFile({
|
233 | file: filename,
|
234 | extensions,
|
235 | env,
|
236 | pkg
|
237 | })) || (await this.loadDirectory({
|
238 | dir: filename,
|
239 | extensions,
|
240 | env,
|
241 | pkg
|
242 | }))
|
243 | ;
|
244 | }
|
245 |
|
246 | findBuiltin(filename, env) {
|
247 | if (_builtins.default[filename]) {
|
248 | if (env.isNode()) {
|
249 | return null;
|
250 | }
|
251 |
|
252 | return {
|
253 | filePath: _builtins.default[filename]
|
254 | };
|
255 | }
|
256 | }
|
257 |
|
258 | async findNodeModulePath(filename, dir) {
|
259 | let parts = this.getModuleParts(filename);
|
260 |
|
261 | let root = _path.default.parse(dir).root;
|
262 |
|
263 | while (dir !== root) {
|
264 |
|
265 | if (_path.default.basename(dir) === 'node_modules') {
|
266 | dir = _path.default.dirname(dir);
|
267 | }
|
268 |
|
269 | try {
|
270 |
|
271 | let moduleDir = _path.default.join(dir, 'node_modules', parts[0]);
|
272 |
|
273 | let stats = await this.options.inputFS.stat(moduleDir);
|
274 |
|
275 | if (stats.isDirectory()) {
|
276 | return {
|
277 | moduleName: parts[0],
|
278 | subPath: parts[1],
|
279 | moduleDir: moduleDir,
|
280 | filePath: _path.default.join(dir, 'node_modules', filename)
|
281 | };
|
282 | }
|
283 | } catch (err) {}
|
284 |
|
285 |
|
286 |
|
287 | dir = _path.default.dirname(dir);
|
288 | }
|
289 |
|
290 | return undefined;
|
291 | }
|
292 |
|
293 | async loadNodeModules(module, extensions, env) {
|
294 | try {
|
295 |
|
296 |
|
297 | if (module.subPath && module.moduleDir) {
|
298 | let pkg = await this.readPackage(module.moduleDir);
|
299 | let res = await this.loadAsFile({
|
300 | file: (0, _nullthrows.default)(module.filePath),
|
301 | extensions,
|
302 | env,
|
303 | pkg
|
304 | });
|
305 |
|
306 | if (res) {
|
307 | return res;
|
308 | }
|
309 | }
|
310 |
|
311 |
|
312 | return await this.loadDirectory({
|
313 | dir: (0, _nullthrows.default)(module.filePath),
|
314 | extensions,
|
315 | env
|
316 | });
|
317 | } catch (e) {
|
318 | }
|
319 | }
|
320 |
|
321 | async isFile(file) {
|
322 | try {
|
323 | let stat = await this.options.inputFS.stat(file);
|
324 | return stat.isFile() || stat.isFIFO();
|
325 | } catch (err) {
|
326 | return false;
|
327 | }
|
328 | }
|
329 |
|
330 | async loadDirectory({
|
331 | dir,
|
332 | extensions,
|
333 | env,
|
334 | pkg
|
335 | }) {
|
336 | try {
|
337 | pkg = await this.readPackage(dir);
|
338 |
|
339 | let entries = this.getPackageEntries(pkg, env);
|
340 |
|
341 | for (let file of entries) {
|
342 |
|
343 | const res = (await this.loadAsFile({
|
344 | file,
|
345 | extensions,
|
346 | env,
|
347 | pkg
|
348 | })) || (await this.loadDirectory({
|
349 | dir: file,
|
350 | extensions,
|
351 | env,
|
352 | pkg
|
353 | }));
|
354 |
|
355 | if (res) {
|
356 | return res;
|
357 | }
|
358 | }
|
359 | } catch (err) {}
|
360 |
|
361 |
|
362 |
|
363 | return this.loadAsFile({
|
364 | file: _path.default.join(dir, 'index'),
|
365 | extensions,
|
366 | env,
|
367 | pkg: pkg || null
|
368 | });
|
369 | }
|
370 |
|
371 | async readPackage(dir) {
|
372 | let file = _path.default.join(dir, 'package.json');
|
373 |
|
374 | let cached = this.packageCache.get(file);
|
375 |
|
376 | if (cached) {
|
377 | return cached;
|
378 | }
|
379 |
|
380 | let json = await this.options.inputFS.readFile(file, 'utf8');
|
381 | let pkg = JSON.parse(json);
|
382 | pkg.pkgfile = file;
|
383 | pkg.pkgdir = dir;
|
384 |
|
385 |
|
386 | if (pkg.source) {
|
387 | let realpath = await this.options.inputFS.realpath(file);
|
388 |
|
389 | if (realpath === file) {
|
390 | delete pkg.source;
|
391 | }
|
392 | }
|
393 |
|
394 | this.packageCache.set(file, pkg);
|
395 | return pkg;
|
396 | }
|
397 |
|
398 | getPackageEntries(pkg, env) {
|
399 | return this.mainFields.map(field => {
|
400 | if (field === 'browser' && pkg.browser != null) {
|
401 | if (!env.isBrowser()) {
|
402 | return null;
|
403 | } else if (typeof pkg.browser === 'string') {
|
404 | return pkg.browser;
|
405 | } else if (typeof pkg.browser === 'object' && pkg.browser[pkg.name]) {
|
406 | return pkg.browser[pkg.name];
|
407 | }
|
408 | }
|
409 |
|
410 | return pkg[field];
|
411 | }).filter(entry => typeof entry === 'string').map(main => {
|
412 |
|
413 | if (!main || main === '.' || main === './') {
|
414 | main = 'index';
|
415 | }
|
416 |
|
417 | if (typeof main !== 'string') {
|
418 | throw new Error('invariant: expected string');
|
419 | }
|
420 |
|
421 | return _path.default.resolve(pkg.pkgdir, main);
|
422 | });
|
423 | }
|
424 |
|
425 | async loadAsFile({
|
426 | file,
|
427 | extensions,
|
428 | env,
|
429 | pkg
|
430 | }) {
|
431 |
|
432 | for (let f of await this.expandFile(file, extensions, env, pkg)) {
|
433 | if (await this.isFile(f)) {
|
434 | return {
|
435 | path: f,
|
436 | pkg
|
437 | };
|
438 | }
|
439 | }
|
440 | }
|
441 |
|
442 | async expandFile(file, extensions, env, pkg, expandAliases = true) {
|
443 |
|
444 | let res = [];
|
445 |
|
446 | for (let ext of extensions) {
|
447 | let f = file + ext;
|
448 |
|
449 | if (expandAliases) {
|
450 | let alias = await this.resolveAliases(file + ext, env, pkg);
|
451 |
|
452 | if (alias !== f) {
|
453 | res = res.concat((await this.expandFile(alias, extensions, env, pkg, false)));
|
454 | }
|
455 | }
|
456 |
|
457 | res.push(f);
|
458 | }
|
459 |
|
460 | return res;
|
461 | }
|
462 |
|
463 | async resolveAliases(filename, env, pkg) {
|
464 |
|
465 | return this.resolvePackageAliases((await this.resolvePackageAliases(filename, env, pkg)), env, this.rootPackage);
|
466 | }
|
467 |
|
468 | async resolvePackageAliases(filename, env, pkg) {
|
469 | if (!pkg) {
|
470 | return filename;
|
471 | }
|
472 |
|
473 |
|
474 | return (await this.getAlias(filename, pkg.pkgdir, pkg.source)) || (await this.getAlias(filename, pkg.pkgdir, pkg.alias)) || env.isBrowser() && (await this.getAlias(filename, pkg.pkgdir, pkg.browser)) || filename;
|
475 | }
|
476 |
|
477 | async getAlias(filename, dir, aliases) {
|
478 | if (!filename || !aliases || typeof aliases !== 'object') {
|
479 | return null;
|
480 | }
|
481 |
|
482 | let alias;
|
483 |
|
484 | if (_path.default.isAbsolute(filename)) {
|
485 | filename = _path.default.relative(dir, filename);
|
486 |
|
487 | if (filename[0] !== '.') {
|
488 | filename = './' + filename;
|
489 | }
|
490 |
|
491 | alias = await this.lookupAlias(aliases, filename, dir);
|
492 | } else {
|
493 |
|
494 | alias = await this.lookupAlias(aliases, filename, dir);
|
495 |
|
496 | if (alias == null) {
|
497 |
|
498 | let parts = this.getModuleParts(filename);
|
499 | alias = await this.lookupAlias(aliases, parts[0], dir);
|
500 |
|
501 | if (typeof alias === 'string') {
|
502 |
|
503 | alias = _path.default.join(alias, ...parts.slice(1));
|
504 | }
|
505 | }
|
506 | }
|
507 |
|
508 |
|
509 | if (alias === false) {
|
510 | return EMPTY_SHIM;
|
511 | }
|
512 |
|
513 | return alias;
|
514 | }
|
515 |
|
516 | lookupAlias(aliases, filename, dir) {
|
517 | if (typeof aliases !== 'object') {
|
518 | return null;
|
519 | }
|
520 |
|
521 |
|
522 | let alias = aliases[filename];
|
523 |
|
524 | if (alias == null) {
|
525 |
|
526 | for (let key in aliases) {
|
527 | let val = aliases[key];
|
528 |
|
529 | if (typeof val === 'string' && (0, _utils.isGlob)(key)) {
|
530 | let re = _micromatch.default.makeRe(key, {
|
531 | capture: true
|
532 | });
|
533 |
|
534 | if (re.test(filename)) {
|
535 | alias = filename.replace(re, val);
|
536 | break;
|
537 | }
|
538 | }
|
539 | }
|
540 | }
|
541 |
|
542 | if (typeof alias === 'string') {
|
543 | return this.resolveFilename(alias, dir);
|
544 | } else if (alias === false) {
|
545 | return false;
|
546 | }
|
547 |
|
548 | return null;
|
549 | }
|
550 |
|
551 | async findPackage(dir) {
|
552 |
|
553 | let root = _path.default.parse(dir).root;
|
554 |
|
555 | while (dir !== root && _path.default.basename(dir) !== 'node_modules') {
|
556 | try {
|
557 | return await this.readPackage(dir);
|
558 | } catch (err) {
|
559 | }
|
560 |
|
561 | dir = _path.default.dirname(dir);
|
562 | }
|
563 |
|
564 | return null;
|
565 | }
|
566 |
|
567 | async loadAlias(filename, dir, env) {
|
568 |
|
569 | if (!this.rootPackage) {
|
570 | this.rootPackage = await this.findPackage(this.options.rootDir);
|
571 | }
|
572 |
|
573 |
|
574 | let pkg = await this.findPackage(dir);
|
575 | return this.resolveAliases(filename, env, pkg);
|
576 | }
|
577 |
|
578 | getModuleParts(name) {
|
579 | let parts = _path.default.normalize(name).split(_path.default.sep);
|
580 |
|
581 | if (parts[0].charAt(0) === '@') {
|
582 |
|
583 | parts.splice(0, 2, `${parts[0]}/${parts[1]}`);
|
584 | }
|
585 |
|
586 | return parts;
|
587 | }
|
588 |
|
589 | hasSideEffects(filePath, pkg) {
|
590 | switch (typeof pkg.sideEffects) {
|
591 | case 'boolean':
|
592 | return pkg.sideEffects;
|
593 |
|
594 | case 'string':
|
595 | return _micromatch.default.isMatch(_path.default.relative(pkg.pkgdir, filePath), pkg.sideEffects, {
|
596 | matchBase: true
|
597 | });
|
598 |
|
599 | case 'object':
|
600 | return pkg.sideEffects.some(sideEffects => this.hasSideEffects(filePath, _objectSpread({}, pkg, {
|
601 | sideEffects
|
602 | })));
|
603 | }
|
604 |
|
605 | return true;
|
606 | }
|
607 |
|
608 | }
|
609 |
|
610 | exports.default = NodeResolver; |
\ | No newline at end of file |