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