UNPKG

36.7 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, '__esModule', { value: true });
4
5var path = require('path');
6var isBuiltinModule = require('is-builtin-module');
7var deepMerge = require('deepmerge');
8var isModule = require('is-module');
9var fs = require('fs');
10var util = require('util');
11var url = require('url');
12var resolve = require('resolve');
13var pluginutils = require('@rollup/pluginutils');
14
15var version = "15.0.1";
16var peerDependencies = {
17 rollup: "^2.78.0||^3.0.0"
18};
19
20util.promisify(fs.access);
21const readFile$1 = util.promisify(fs.readFile);
22const realpath = util.promisify(fs.realpath);
23const stat = util.promisify(fs.stat);
24
25async function fileExists(filePath) {
26 try {
27 const res = await stat(filePath);
28 return res.isFile();
29 } catch {
30 return false;
31 }
32}
33
34async function resolveSymlink(path) {
35 return (await fileExists(path)) ? realpath(path) : path;
36}
37
38const onError = (error) => {
39 if (error.code === 'ENOENT') {
40 return false;
41 }
42 throw error;
43};
44
45const makeCache = (fn) => {
46 const cache = new Map();
47 const wrapped = async (param, done) => {
48 if (cache.has(param) === false) {
49 cache.set(
50 param,
51 fn(param).catch((err) => {
52 cache.delete(param);
53 throw err;
54 })
55 );
56 }
57
58 try {
59 const result = cache.get(param);
60 const value = await result;
61 return done(null, value);
62 } catch (error) {
63 return done(error);
64 }
65 };
66
67 wrapped.clear = () => cache.clear();
68
69 return wrapped;
70};
71
72const isDirCached = makeCache(async (file) => {
73 try {
74 const stats = await stat(file);
75 return stats.isDirectory();
76 } catch (error) {
77 return onError(error);
78 }
79});
80
81const isFileCached = makeCache(async (file) => {
82 try {
83 const stats = await stat(file);
84 return stats.isFile();
85 } catch (error) {
86 return onError(error);
87 }
88});
89
90const readCachedFile = makeCache(readFile$1);
91
92function handleDeprecatedOptions(opts) {
93 const warnings = [];
94
95 if (opts.customResolveOptions) {
96 const { customResolveOptions } = opts;
97 if (customResolveOptions.moduleDirectory) {
98 // eslint-disable-next-line no-param-reassign
99 opts.moduleDirectories = Array.isArray(customResolveOptions.moduleDirectory)
100 ? customResolveOptions.moduleDirectory
101 : [customResolveOptions.moduleDirectory];
102
103 warnings.push(
104 'node-resolve: The `customResolveOptions.moduleDirectory` option has been deprecated. Use `moduleDirectories`, which must be an array.'
105 );
106 }
107
108 if (customResolveOptions.preserveSymlinks) {
109 throw new Error(
110 'node-resolve: `customResolveOptions.preserveSymlinks` is no longer an option. We now always use the rollup `preserveSymlinks` option.'
111 );
112 }
113
114 [
115 'basedir',
116 'package',
117 'extensions',
118 'includeCoreModules',
119 'readFile',
120 'isFile',
121 'isDirectory',
122 'realpath',
123 'packageFilter',
124 'pathFilter',
125 'paths',
126 'packageIterator'
127 ].forEach((resolveOption) => {
128 if (customResolveOptions[resolveOption]) {
129 throw new Error(
130 `node-resolve: \`customResolveOptions.${resolveOption}\` is no longer an option. If you need this, please open an issue.`
131 );
132 }
133 });
134 }
135
136 return { warnings };
137}
138
139// returns the imported package name for bare module imports
140function getPackageName(id) {
141 if (id.startsWith('.') || id.startsWith('/')) {
142 return null;
143 }
144
145 const split = id.split('/');
146
147 // @my-scope/my-package/foo.js -> @my-scope/my-package
148 // @my-scope/my-package -> @my-scope/my-package
149 if (split[0][0] === '@') {
150 return `${split[0]}/${split[1]}`;
151 }
152
153 // my-package/foo.js -> my-package
154 // my-package -> my-package
155 return split[0];
156}
157
158function getMainFields(options) {
159 let mainFields;
160 if (options.mainFields) {
161 ({ mainFields } = options);
162 } else {
163 mainFields = ['module', 'main'];
164 }
165 if (options.browser && mainFields.indexOf('browser') === -1) {
166 return ['browser'].concat(mainFields);
167 }
168 if (!mainFields.length) {
169 throw new Error('Please ensure at least one `mainFields` value is specified');
170 }
171 return mainFields;
172}
173
174function getPackageInfo(options) {
175 const {
176 cache,
177 extensions,
178 pkg,
179 mainFields,
180 preserveSymlinks,
181 useBrowserOverrides,
182 rootDir,
183 ignoreSideEffectsForRoot
184 } = options;
185 let { pkgPath } = options;
186
187 if (cache.has(pkgPath)) {
188 return cache.get(pkgPath);
189 }
190
191 // browserify/resolve doesn't realpath paths returned in its packageFilter callback
192 if (!preserveSymlinks) {
193 pkgPath = fs.realpathSync(pkgPath);
194 }
195
196 const pkgRoot = path.dirname(pkgPath);
197
198 const packageInfo = {
199 // copy as we are about to munge the `main` field of `pkg`.
200 packageJson: { ...pkg },
201
202 // path to package.json file
203 packageJsonPath: pkgPath,
204
205 // directory containing the package.json
206 root: pkgRoot,
207
208 // which main field was used during resolution of this module (main, module, or browser)
209 resolvedMainField: 'main',
210
211 // whether the browser map was used to resolve the entry point to this module
212 browserMappedMain: false,
213
214 // the entry point of the module with respect to the selected main field and any
215 // relevant browser mappings.
216 resolvedEntryPoint: ''
217 };
218
219 let overriddenMain = false;
220 for (let i = 0; i < mainFields.length; i++) {
221 const field = mainFields[i];
222 if (typeof pkg[field] === 'string') {
223 pkg.main = pkg[field];
224 packageInfo.resolvedMainField = field;
225 overriddenMain = true;
226 break;
227 }
228 }
229
230 const internalPackageInfo = {
231 cachedPkg: pkg,
232 hasModuleSideEffects: () => null,
233 hasPackageEntry: overriddenMain !== false || mainFields.indexOf('main') !== -1,
234 packageBrowserField:
235 useBrowserOverrides &&
236 typeof pkg.browser === 'object' &&
237 Object.keys(pkg.browser).reduce((browser, key) => {
238 let resolved = pkg.browser[key];
239 if (resolved && resolved[0] === '.') {
240 resolved = path.resolve(pkgRoot, resolved);
241 }
242 /* eslint-disable no-param-reassign */
243 browser[key] = resolved;
244 if (key[0] === '.') {
245 const absoluteKey = path.resolve(pkgRoot, key);
246 browser[absoluteKey] = resolved;
247 if (!path.extname(key)) {
248 extensions.reduce((subBrowser, ext) => {
249 subBrowser[absoluteKey + ext] = subBrowser[key];
250 return subBrowser;
251 }, browser);
252 }
253 }
254 return browser;
255 }, {}),
256 packageInfo
257 };
258
259 const browserMap = internalPackageInfo.packageBrowserField;
260 if (
261 useBrowserOverrides &&
262 typeof pkg.browser === 'object' &&
263 // eslint-disable-next-line no-prototype-builtins
264 browserMap.hasOwnProperty(pkg.main)
265 ) {
266 packageInfo.resolvedEntryPoint = browserMap[pkg.main];
267 packageInfo.browserMappedMain = true;
268 } else {
269 // index.node is technically a valid default entrypoint as well...
270 packageInfo.resolvedEntryPoint = path.resolve(pkgRoot, pkg.main || 'index.js');
271 packageInfo.browserMappedMain = false;
272 }
273
274 if (!ignoreSideEffectsForRoot || rootDir !== pkgRoot) {
275 const packageSideEffects = pkg.sideEffects;
276 if (typeof packageSideEffects === 'boolean') {
277 internalPackageInfo.hasModuleSideEffects = () => packageSideEffects;
278 } else if (Array.isArray(packageSideEffects)) {
279 const finalPackageSideEffects = packageSideEffects.map((sideEffect) => {
280 /*
281 * The array accepts simple glob patterns to the relevant files... Patterns like .css, which do not include a /, will be treated like **\/.css.
282 * https://webpack.js.org/guides/tree-shaking/
283 */
284 if (sideEffect.includes('/')) {
285 return sideEffect;
286 }
287 return `**/${sideEffect}`;
288 });
289 internalPackageInfo.hasModuleSideEffects = pluginutils.createFilter(finalPackageSideEffects, null, {
290 resolve: pkgRoot
291 });
292 }
293 }
294
295 cache.set(pkgPath, internalPackageInfo);
296 return internalPackageInfo;
297}
298
299function normalizeInput(input) {
300 if (Array.isArray(input)) {
301 return input;
302 } else if (typeof input === 'object') {
303 return Object.values(input);
304 }
305
306 // otherwise it's a string
307 return [input];
308}
309
310/* eslint-disable no-await-in-loop */
311
312function isModuleDir(current, moduleDirs) {
313 return moduleDirs.some((dir) => current.endsWith(dir));
314}
315
316async function findPackageJson(base, moduleDirs) {
317 const { root } = path.parse(base);
318 let current = base;
319
320 while (current !== root && !isModuleDir(current, moduleDirs)) {
321 const pkgJsonPath = path.join(current, 'package.json');
322 if (await fileExists(pkgJsonPath)) {
323 const pkgJsonString = fs.readFileSync(pkgJsonPath, 'utf-8');
324 return { pkgJson: JSON.parse(pkgJsonString), pkgPath: current, pkgJsonPath };
325 }
326 current = path.resolve(current, '..');
327 }
328 return null;
329}
330
331function isUrl(str) {
332 try {
333 return !!new URL(str);
334 } catch (_) {
335 return false;
336 }
337}
338
339function isConditions(exports) {
340 return typeof exports === 'object' && Object.keys(exports).every((k) => !k.startsWith('.'));
341}
342
343function isMappings(exports) {
344 return typeof exports === 'object' && !isConditions(exports);
345}
346
347function isMixedExports(exports) {
348 const keys = Object.keys(exports);
349 return keys.some((k) => k.startsWith('.')) && keys.some((k) => !k.startsWith('.'));
350}
351
352function createBaseErrorMsg(importSpecifier, importer) {
353 return `Could not resolve import "${importSpecifier}" in ${importer}`;
354}
355
356function createErrorMsg(context, reason, internal) {
357 const { importSpecifier, importer, pkgJsonPath } = context;
358 const base = createBaseErrorMsg(importSpecifier, importer);
359 const field = internal ? 'imports' : 'exports';
360 return `${base} using ${field} defined in ${pkgJsonPath}.${reason ? ` ${reason}` : ''}`;
361}
362
363class ResolveError extends Error {}
364
365class InvalidConfigurationError extends ResolveError {
366 constructor(context, reason) {
367 super(createErrorMsg(context, `Invalid "exports" field. ${reason}`));
368 }
369}
370
371class InvalidModuleSpecifierError extends ResolveError {
372 constructor(context, internal, reason) {
373 super(createErrorMsg(context, reason, internal));
374 }
375}
376
377class InvalidPackageTargetError extends ResolveError {
378 constructor(context, reason) {
379 super(createErrorMsg(context, reason));
380 }
381}
382
383/* eslint-disable no-await-in-loop, no-undefined */
384
385function includesInvalidSegments(pathSegments, moduleDirs) {
386 return pathSegments
387 .split('/')
388 .slice(1)
389 .some((t) => ['.', '..', ...moduleDirs].includes(t));
390}
391
392async function resolvePackageTarget(context, { target, subpath, pattern, internal }) {
393 if (typeof target === 'string') {
394 if (!pattern && subpath.length > 0 && !target.endsWith('/')) {
395 throw new InvalidModuleSpecifierError(context);
396 }
397
398 if (!target.startsWith('./')) {
399 if (internal && !['/', '../'].some((p) => target.startsWith(p)) && !isUrl(target)) {
400 // this is a bare package import, remap it and resolve it using regular node resolve
401 if (pattern) {
402 const result = await context.resolveId(
403 target.replace(/\*/g, subpath),
404 context.pkgURL.href
405 );
406 return result ? url.pathToFileURL(result.location).href : null;
407 }
408
409 const result = await context.resolveId(`${target}${subpath}`, context.pkgURL.href);
410 return result ? url.pathToFileURL(result.location).href : null;
411 }
412 throw new InvalidPackageTargetError(context, `Invalid mapping: "${target}".`);
413 }
414
415 if (includesInvalidSegments(target, context.moduleDirs)) {
416 throw new InvalidPackageTargetError(context, `Invalid mapping: "${target}".`);
417 }
418
419 const resolvedTarget = new URL(target, context.pkgURL);
420 if (!resolvedTarget.href.startsWith(context.pkgURL.href)) {
421 throw new InvalidPackageTargetError(
422 context,
423 `Resolved to ${resolvedTarget.href} which is outside package ${context.pkgURL.href}`
424 );
425 }
426
427 if (includesInvalidSegments(subpath, context.moduleDirs)) {
428 throw new InvalidModuleSpecifierError(context);
429 }
430
431 if (pattern) {
432 return resolvedTarget.href.replace(/\*/g, subpath);
433 }
434 return new URL(subpath, resolvedTarget).href;
435 }
436
437 if (Array.isArray(target)) {
438 let lastError;
439 for (const item of target) {
440 try {
441 const resolved = await resolvePackageTarget(context, {
442 target: item,
443 subpath,
444 pattern,
445 internal
446 });
447
448 // return if defined or null, but not undefined
449 if (resolved !== undefined) {
450 return resolved;
451 }
452 } catch (error) {
453 if (!(error instanceof InvalidPackageTargetError)) {
454 throw error;
455 } else {
456 lastError = error;
457 }
458 }
459 }
460
461 if (lastError) {
462 throw lastError;
463 }
464 return null;
465 }
466
467 if (target && typeof target === 'object') {
468 for (const [key, value] of Object.entries(target)) {
469 if (key === 'default' || context.conditions.includes(key)) {
470 const resolved = await resolvePackageTarget(context, {
471 target: value,
472 subpath,
473 pattern,
474 internal
475 });
476
477 // return if defined or null, but not undefined
478 if (resolved !== undefined) {
479 return resolved;
480 }
481 }
482 }
483 return undefined;
484 }
485
486 if (target === null) {
487 return null;
488 }
489
490 throw new InvalidPackageTargetError(context, `Invalid exports field.`);
491}
492
493/* eslint-disable no-await-in-loop */
494
495async function resolvePackageImportsExports(context, { matchKey, matchObj, internal }) {
496 if (!matchKey.endsWith('*') && matchKey in matchObj) {
497 const target = matchObj[matchKey];
498 const resolved = await resolvePackageTarget(context, { target, subpath: '', internal });
499 return resolved;
500 }
501
502 const expansionKeys = Object.keys(matchObj)
503 .filter((k) => k.endsWith('/') || k.endsWith('*'))
504 .sort((a, b) => b.length - a.length);
505
506 for (const expansionKey of expansionKeys) {
507 const prefix = expansionKey.substring(0, expansionKey.length - 1);
508
509 if (expansionKey.endsWith('*') && matchKey.startsWith(prefix)) {
510 const target = matchObj[expansionKey];
511 const subpath = matchKey.substring(expansionKey.length - 1);
512 const resolved = await resolvePackageTarget(context, {
513 target,
514 subpath,
515 pattern: true,
516 internal
517 });
518 return resolved;
519 }
520
521 if (matchKey.startsWith(expansionKey)) {
522 const target = matchObj[expansionKey];
523 const subpath = matchKey.substring(expansionKey.length);
524
525 const resolved = await resolvePackageTarget(context, { target, subpath, internal });
526 return resolved;
527 }
528 }
529
530 throw new InvalidModuleSpecifierError(context, internal);
531}
532
533async function resolvePackageExports(context, subpath, exports) {
534 if (isMixedExports(exports)) {
535 throw new InvalidConfigurationError(
536 context,
537 'All keys must either start with ./, or without one.'
538 );
539 }
540
541 if (subpath === '.') {
542 let mainExport;
543 // If exports is a String or Array, or an Object containing no keys starting with ".", then
544 if (typeof exports === 'string' || Array.isArray(exports) || isConditions(exports)) {
545 mainExport = exports;
546 } else if (isMappings(exports)) {
547 mainExport = exports['.'];
548 }
549
550 if (mainExport) {
551 const resolved = await resolvePackageTarget(context, { target: mainExport, subpath: '' });
552 if (resolved) {
553 return resolved;
554 }
555 }
556 } else if (isMappings(exports)) {
557 const resolvedMatch = await resolvePackageImportsExports(context, {
558 matchKey: subpath,
559 matchObj: exports
560 });
561
562 if (resolvedMatch) {
563 return resolvedMatch;
564 }
565 }
566
567 throw new InvalidModuleSpecifierError(context);
568}
569
570async function resolvePackageImports({
571 importSpecifier,
572 importer,
573 moduleDirs,
574 conditions,
575 resolveId
576}) {
577 const result = await findPackageJson(importer, moduleDirs);
578 if (!result) {
579 throw new Error(createBaseErrorMsg('. Could not find a parent package.json.'));
580 }
581
582 const { pkgPath, pkgJsonPath, pkgJson } = result;
583 const pkgURL = url.pathToFileURL(`${pkgPath}/`);
584 const context = {
585 importer,
586 importSpecifier,
587 moduleDirs,
588 pkgURL,
589 pkgJsonPath,
590 conditions,
591 resolveId
592 };
593
594 const { imports } = pkgJson;
595 if (!imports) {
596 throw new InvalidModuleSpecifierError(context, true);
597 }
598
599 if (importSpecifier === '#' || importSpecifier.startsWith('#/')) {
600 throw new InvalidModuleSpecifierError(context, true, 'Invalid import specifier.');
601 }
602
603 return resolvePackageImportsExports(context, {
604 matchKey: importSpecifier,
605 matchObj: imports,
606 internal: true
607 });
608}
609
610const resolveImportPath = util.promisify(resolve);
611const readFile = util.promisify(fs.readFile);
612
613async function getPackageJson(importer, pkgName, resolveOptions, moduleDirectories) {
614 if (importer) {
615 const selfPackageJsonResult = await findPackageJson(importer, moduleDirectories);
616 if (selfPackageJsonResult && selfPackageJsonResult.pkgJson.name === pkgName) {
617 // the referenced package name is the current package
618 return selfPackageJsonResult;
619 }
620 }
621
622 try {
623 const pkgJsonPath = await resolveImportPath(`${pkgName}/package.json`, resolveOptions);
624 const pkgJson = JSON.parse(await readFile(pkgJsonPath, 'utf-8'));
625 return { pkgJsonPath, pkgJson, pkgPath: path.dirname(pkgJsonPath) };
626 } catch (_) {
627 return null;
628 }
629}
630
631async function resolveIdClassic({
632 importSpecifier,
633 packageInfoCache,
634 extensions,
635 mainFields,
636 preserveSymlinks,
637 useBrowserOverrides,
638 baseDir,
639 moduleDirectories,
640 modulePaths,
641 rootDir,
642 ignoreSideEffectsForRoot
643}) {
644 let hasModuleSideEffects = () => null;
645 let hasPackageEntry = true;
646 let packageBrowserField = false;
647 let packageInfo;
648
649 const filter = (pkg, pkgPath) => {
650 const info = getPackageInfo({
651 cache: packageInfoCache,
652 extensions,
653 pkg,
654 pkgPath,
655 mainFields,
656 preserveSymlinks,
657 useBrowserOverrides,
658 rootDir,
659 ignoreSideEffectsForRoot
660 });
661
662 ({ packageInfo, hasModuleSideEffects, hasPackageEntry, packageBrowserField } = info);
663
664 return info.cachedPkg;
665 };
666
667 const resolveOptions = {
668 basedir: baseDir,
669 readFile: readCachedFile,
670 isFile: isFileCached,
671 isDirectory: isDirCached,
672 extensions,
673 includeCoreModules: false,
674 moduleDirectory: moduleDirectories,
675 paths: modulePaths,
676 preserveSymlinks,
677 packageFilter: filter
678 };
679
680 let location;
681 try {
682 location = await resolveImportPath(importSpecifier, resolveOptions);
683 } catch (error) {
684 if (error.code !== 'MODULE_NOT_FOUND') {
685 throw error;
686 }
687 return null;
688 }
689
690 return {
691 location: preserveSymlinks ? location : await resolveSymlink(location),
692 hasModuleSideEffects,
693 hasPackageEntry,
694 packageBrowserField,
695 packageInfo
696 };
697}
698
699async function resolveWithExportMap({
700 importer,
701 importSpecifier,
702 exportConditions,
703 packageInfoCache,
704 extensions,
705 mainFields,
706 preserveSymlinks,
707 useBrowserOverrides,
708 baseDir,
709 moduleDirectories,
710 modulePaths,
711 rootDir,
712 ignoreSideEffectsForRoot
713}) {
714 if (importSpecifier.startsWith('#')) {
715 // this is a package internal import, resolve using package imports field
716 const resolveResult = await resolvePackageImports({
717 importSpecifier,
718 importer,
719 moduleDirs: moduleDirectories,
720 conditions: exportConditions,
721 resolveId(id /* , parent*/) {
722 return resolveIdClassic({
723 importSpecifier: id,
724 packageInfoCache,
725 extensions,
726 mainFields,
727 preserveSymlinks,
728 useBrowserOverrides,
729 baseDir,
730 moduleDirectories,
731 modulePaths
732 });
733 }
734 });
735
736 const location = url.fileURLToPath(resolveResult);
737 return {
738 location: preserveSymlinks ? location : await resolveSymlink(location),
739 hasModuleSideEffects: () => null,
740 hasPackageEntry: true,
741 packageBrowserField: false,
742 // eslint-disable-next-line no-undefined
743 packageInfo: undefined
744 };
745 }
746
747 const pkgName = getPackageName(importSpecifier);
748 if (pkgName) {
749 // it's a bare import, find the package.json and resolve using package exports if available
750 let hasModuleSideEffects = () => null;
751 let hasPackageEntry = true;
752 let packageBrowserField = false;
753 let packageInfo;
754
755 const filter = (pkg, pkgPath) => {
756 const info = getPackageInfo({
757 cache: packageInfoCache,
758 extensions,
759 pkg,
760 pkgPath,
761 mainFields,
762 preserveSymlinks,
763 useBrowserOverrides,
764 rootDir,
765 ignoreSideEffectsForRoot
766 });
767
768 ({ packageInfo, hasModuleSideEffects, hasPackageEntry, packageBrowserField } = info);
769
770 return info.cachedPkg;
771 };
772
773 const resolveOptions = {
774 basedir: baseDir,
775 readFile: readCachedFile,
776 isFile: isFileCached,
777 isDirectory: isDirCached,
778 extensions,
779 includeCoreModules: false,
780 moduleDirectory: moduleDirectories,
781 paths: modulePaths,
782 preserveSymlinks,
783 packageFilter: filter
784 };
785
786 const result = await getPackageJson(importer, pkgName, resolveOptions, moduleDirectories);
787
788 if (result && result.pkgJson.exports) {
789 const { pkgJson, pkgJsonPath } = result;
790 const subpath =
791 pkgName === importSpecifier ? '.' : `.${importSpecifier.substring(pkgName.length)}`;
792 const pkgDr = pkgJsonPath.replace('package.json', '');
793 const pkgURL = url.pathToFileURL(pkgDr);
794
795 const context = {
796 importer,
797 importSpecifier,
798 moduleDirs: moduleDirectories,
799 pkgURL,
800 pkgJsonPath,
801 conditions: exportConditions
802 };
803 const resolvedPackageExport = await resolvePackageExports(context, subpath, pkgJson.exports);
804 const location = url.fileURLToPath(resolvedPackageExport);
805 if (location) {
806 return {
807 location: preserveSymlinks ? location : await resolveSymlink(location),
808 hasModuleSideEffects,
809 hasPackageEntry,
810 packageBrowserField,
811 packageInfo
812 };
813 }
814 }
815 }
816
817 return null;
818}
819
820async function resolveWithClassic({
821 importer,
822 importSpecifierList,
823 exportConditions,
824 warn,
825 packageInfoCache,
826 extensions,
827 mainFields,
828 preserveSymlinks,
829 useBrowserOverrides,
830 baseDir,
831 moduleDirectories,
832 modulePaths,
833 rootDir,
834 ignoreSideEffectsForRoot
835}) {
836 for (let i = 0; i < importSpecifierList.length; i++) {
837 // eslint-disable-next-line no-await-in-loop
838 const result = await resolveIdClassic({
839 importer,
840 importSpecifier: importSpecifierList[i],
841 exportConditions,
842 warn,
843 packageInfoCache,
844 extensions,
845 mainFields,
846 preserveSymlinks,
847 useBrowserOverrides,
848 baseDir,
849 moduleDirectories,
850 modulePaths,
851 rootDir,
852 ignoreSideEffectsForRoot
853 });
854
855 if (result) {
856 return result;
857 }
858 }
859
860 return null;
861}
862
863// Resolves to the module if found or `null`.
864// The first import specificer will first be attempted with the exports algorithm.
865// If this is unsuccesful because export maps are not being used, then all of `importSpecifierList`
866// will be tried with the classic resolution algorithm
867async function resolveImportSpecifiers({
868 importer,
869 importSpecifierList,
870 exportConditions,
871 warn,
872 packageInfoCache,
873 extensions,
874 mainFields,
875 preserveSymlinks,
876 useBrowserOverrides,
877 baseDir,
878 moduleDirectories,
879 modulePaths,
880 rootDir,
881 ignoreSideEffectsForRoot
882}) {
883 try {
884 const exportMapRes = await resolveWithExportMap({
885 importer,
886 importSpecifier: importSpecifierList[0],
887 exportConditions,
888 packageInfoCache,
889 extensions,
890 mainFields,
891 preserveSymlinks,
892 useBrowserOverrides,
893 baseDir,
894 moduleDirectories,
895 modulePaths,
896 rootDir,
897 ignoreSideEffectsForRoot
898 });
899 if (exportMapRes) return exportMapRes;
900 } catch (error) {
901 if (error instanceof ResolveError) {
902 warn(error);
903 return null;
904 }
905 throw error;
906 }
907
908 // package has no imports or exports, use classic node resolve
909 return resolveWithClassic({
910 importer,
911 importSpecifierList,
912 exportConditions,
913 warn,
914 packageInfoCache,
915 extensions,
916 mainFields,
917 preserveSymlinks,
918 useBrowserOverrides,
919 baseDir,
920 moduleDirectories,
921 modulePaths,
922 rootDir,
923 ignoreSideEffectsForRoot
924 });
925}
926
927const versionRegexp = /\^(\d+\.\d+\.\d+)/g;
928
929function validateVersion(actualVersion, peerDependencyVersion) {
930 let minMajor = Infinity;
931 let minMinor = Infinity;
932 let minPatch = Infinity;
933 let foundVersion;
934 // eslint-disable-next-line no-cond-assign
935 while ((foundVersion = versionRegexp.exec(peerDependencyVersion))) {
936 const [foundMajor, foundMinor, foundPatch] = foundVersion[1].split('.').map(Number);
937 if (foundMajor < minMajor) {
938 minMajor = foundMajor;
939 minMinor = foundMinor;
940 minPatch = foundPatch;
941 }
942 }
943 if (!actualVersion) {
944 throw new Error(
945 `Insufficient Rollup version: "@rollup/plugin-node-resolve" requires at least rollup@${minMajor}.${minMinor}.${minPatch}.`
946 );
947 }
948 const [major, minor, patch] = actualVersion.split('.').map(Number);
949 if (
950 major < minMajor ||
951 (major === minMajor && (minor < minMinor || (minor === minMinor && patch < minPatch)))
952 ) {
953 throw new Error(
954 `Insufficient rollup version: "@rollup/plugin-node-resolve" requires at least rollup@${minMajor}.${minMinor}.${minPatch} but found rollup@${actualVersion}.`
955 );
956 }
957}
958
959/* eslint-disable no-param-reassign, no-shadow, no-undefined */
960
961const ES6_BROWSER_EMPTY = '\0node-resolve:empty.js';
962const deepFreeze = (object) => {
963 Object.freeze(object);
964
965 for (const value of Object.values(object)) {
966 if (typeof value === 'object' && !Object.isFrozen(value)) {
967 deepFreeze(value);
968 }
969 }
970
971 return object;
972};
973
974const baseConditions = ['default', 'module'];
975const baseConditionsEsm = [...baseConditions, 'import'];
976const baseConditionsCjs = [...baseConditions, 'require'];
977const defaults = {
978 dedupe: [],
979 // It's important that .mjs is listed before .js so that Rollup will interpret npm modules
980 // which deploy both ESM .mjs and CommonJS .js files as ESM.
981 extensions: ['.mjs', '.js', '.json', '.node'],
982 resolveOnly: [],
983 moduleDirectories: ['node_modules'],
984 ignoreSideEffectsForRoot: false
985};
986const DEFAULTS = deepFreeze(deepMerge({}, defaults));
987
988function nodeResolve(opts = {}) {
989 const { warnings } = handleDeprecatedOptions(opts);
990
991 const options = { ...defaults, ...opts };
992 const { extensions, jail, moduleDirectories, modulePaths, ignoreSideEffectsForRoot } = options;
993 const conditionsEsm = [...baseConditionsEsm, ...(options.exportConditions || [])];
994 const conditionsCjs = [...baseConditionsCjs, ...(options.exportConditions || [])];
995 const packageInfoCache = new Map();
996 const idToPackageInfo = new Map();
997 const mainFields = getMainFields(options);
998 const useBrowserOverrides = mainFields.indexOf('browser') !== -1;
999 const isPreferBuiltinsSet = options.preferBuiltins === true || options.preferBuiltins === false;
1000 const preferBuiltins = isPreferBuiltinsSet ? options.preferBuiltins : true;
1001 const rootDir = path.resolve(options.rootDir || process.cwd());
1002 let { dedupe } = options;
1003 let rollupOptions;
1004
1005 if (moduleDirectories.some((name) => name.includes('/'))) {
1006 throw new Error(
1007 '`moduleDirectories` option must only contain directory names. If you want to load modules from somewhere not supported by the default module resolution algorithm, see `modulePaths`.'
1008 );
1009 }
1010
1011 if (typeof dedupe !== 'function') {
1012 dedupe = (importee) =>
1013 options.dedupe.includes(importee) || options.dedupe.includes(getPackageName(importee));
1014 }
1015
1016 // creates a function from the patterns to test if a particular module should be bundled.
1017 const allowPatterns = (patterns) => {
1018 const regexPatterns = patterns.map((pattern) => {
1019 if (pattern instanceof RegExp) {
1020 return pattern;
1021 }
1022 const normalized = pattern.replace(/[\\^$*+?.()|[\]{}]/g, '\\$&');
1023 return new RegExp(`^${normalized}$`);
1024 });
1025 return (id) => !regexPatterns.length || regexPatterns.some((pattern) => pattern.test(id));
1026 };
1027
1028 const resolveOnly =
1029 typeof options.resolveOnly === 'function'
1030 ? options.resolveOnly
1031 : allowPatterns(options.resolveOnly);
1032
1033 const browserMapCache = new Map();
1034 let preserveSymlinks;
1035
1036 const resolveLikeNode = async (context, importee, importer, custom) => {
1037 // strip query params from import
1038 const [importPath, params] = importee.split('?');
1039 const importSuffix = `${params ? `?${params}` : ''}`;
1040 importee = importPath;
1041
1042 const baseDir = !importer || dedupe(importee) ? rootDir : path.dirname(importer);
1043
1044 // https://github.com/defunctzombie/package-browser-field-spec
1045 const browser = browserMapCache.get(importer);
1046 if (useBrowserOverrides && browser) {
1047 const resolvedImportee = path.resolve(baseDir, importee);
1048 if (browser[importee] === false || browser[resolvedImportee] === false) {
1049 return { id: ES6_BROWSER_EMPTY };
1050 }
1051 const browserImportee =
1052 (importee[0] !== '.' && browser[importee]) ||
1053 browser[resolvedImportee] ||
1054 browser[`${resolvedImportee}.js`] ||
1055 browser[`${resolvedImportee}.json`];
1056 if (browserImportee) {
1057 importee = browserImportee;
1058 }
1059 }
1060
1061 const parts = importee.split(/[/\\]/);
1062 let id = parts.shift();
1063 let isRelativeImport = false;
1064
1065 if (id[0] === '@' && parts.length > 0) {
1066 // scoped packages
1067 id += `/${parts.shift()}`;
1068 } else if (id[0] === '.') {
1069 // an import relative to the parent dir of the importer
1070 id = path.resolve(baseDir, importee);
1071 isRelativeImport = true;
1072 }
1073
1074 // if it's not a relative import, and it's not requested, reject it.
1075 if (!isRelativeImport && !resolveOnly(id)) {
1076 if (normalizeInput(rollupOptions.input).includes(importee)) {
1077 return null;
1078 }
1079 return false;
1080 }
1081
1082 const importSpecifierList = [importee];
1083
1084 if (importer === undefined && !importee[0].match(/^\.?\.?\//)) {
1085 // For module graph roots (i.e. when importer is undefined), we
1086 // need to handle 'path fragments` like `foo/bar` that are commonly
1087 // found in rollup config files. If importee doesn't look like a
1088 // relative or absolute path, we make it relative and attempt to
1089 // resolve it.
1090 importSpecifierList.push(`./${importee}`);
1091 }
1092
1093 // TypeScript files may import '.js' to refer to either '.ts' or '.tsx'
1094 if (importer && importee.endsWith('.js')) {
1095 for (const ext of ['.ts', '.tsx']) {
1096 if (importer.endsWith(ext) && extensions.includes(ext)) {
1097 importSpecifierList.push(importee.replace(/.js$/, ext));
1098 }
1099 }
1100 }
1101
1102 const warn = (...args) => context.warn(...args);
1103 const isRequire = custom && custom['node-resolve'] && custom['node-resolve'].isRequire;
1104 const exportConditions = isRequire ? conditionsCjs : conditionsEsm;
1105
1106 if (useBrowserOverrides && !exportConditions.includes('browser'))
1107 exportConditions.push('browser');
1108
1109 const resolvedWithoutBuiltins = await resolveImportSpecifiers({
1110 importer,
1111 importSpecifierList,
1112 exportConditions,
1113 warn,
1114 packageInfoCache,
1115 extensions,
1116 mainFields,
1117 preserveSymlinks,
1118 useBrowserOverrides,
1119 baseDir,
1120 moduleDirectories,
1121 modulePaths,
1122 rootDir,
1123 ignoreSideEffectsForRoot
1124 });
1125
1126 const importeeIsBuiltin = isBuiltinModule(importee);
1127 const resolved =
1128 importeeIsBuiltin && preferBuiltins
1129 ? {
1130 packageInfo: undefined,
1131 hasModuleSideEffects: () => null,
1132 hasPackageEntry: true,
1133 packageBrowserField: false
1134 }
1135 : resolvedWithoutBuiltins;
1136 if (!resolved) {
1137 return null;
1138 }
1139
1140 const { packageInfo, hasModuleSideEffects, hasPackageEntry, packageBrowserField } = resolved;
1141 let { location } = resolved;
1142 if (packageBrowserField) {
1143 if (Object.prototype.hasOwnProperty.call(packageBrowserField, location)) {
1144 if (!packageBrowserField[location]) {
1145 browserMapCache.set(location, packageBrowserField);
1146 return { id: ES6_BROWSER_EMPTY };
1147 }
1148 location = packageBrowserField[location];
1149 }
1150 browserMapCache.set(location, packageBrowserField);
1151 }
1152
1153 if (hasPackageEntry && !preserveSymlinks) {
1154 const exists = await fileExists(location);
1155 if (exists) {
1156 location = await realpath(location);
1157 }
1158 }
1159
1160 idToPackageInfo.set(location, packageInfo);
1161
1162 if (hasPackageEntry) {
1163 if (importeeIsBuiltin && preferBuiltins) {
1164 if (!isPreferBuiltinsSet && resolvedWithoutBuiltins && resolved !== importee) {
1165 context.warn(
1166 `preferring built-in module '${importee}' over local alternative at '${resolvedWithoutBuiltins.location}', pass 'preferBuiltins: false' to disable this behavior or 'preferBuiltins: true' to disable this warning`
1167 );
1168 }
1169 return false;
1170 } else if (jail && location.indexOf(path.normalize(jail.trim(path.sep))) !== 0) {
1171 return null;
1172 }
1173 }
1174
1175 if (options.modulesOnly && (await fileExists(location))) {
1176 const code = await readFile$1(location, 'utf-8');
1177 if (isModule(code)) {
1178 return {
1179 id: `${location}${importSuffix}`,
1180 moduleSideEffects: hasModuleSideEffects(location)
1181 };
1182 }
1183 return null;
1184 }
1185 return {
1186 id: `${location}${importSuffix}`,
1187 moduleSideEffects: hasModuleSideEffects(location)
1188 };
1189 };
1190
1191 return {
1192 name: 'node-resolve',
1193
1194 version,
1195
1196 buildStart(buildOptions) {
1197 validateVersion(this.meta.rollupVersion, peerDependencies.rollup);
1198 rollupOptions = buildOptions;
1199
1200 for (const warning of warnings) {
1201 this.warn(warning);
1202 }
1203
1204 ({ preserveSymlinks } = buildOptions);
1205 },
1206
1207 generateBundle() {
1208 readCachedFile.clear();
1209 isFileCached.clear();
1210 isDirCached.clear();
1211 },
1212
1213 resolveId: {
1214 order: 'post',
1215 async handler(importee, importer, resolveOptions) {
1216 if (importee === ES6_BROWSER_EMPTY) {
1217 return importee;
1218 }
1219 // ignore IDs with null character, these belong to other plugins
1220 if (/\0/.test(importee)) return null;
1221
1222 const { custom = {} } = resolveOptions;
1223 const { 'node-resolve': { resolved: alreadyResolved } = {} } = custom;
1224 if (alreadyResolved) {
1225 return alreadyResolved;
1226 }
1227
1228 if (/\0/.test(importer)) {
1229 importer = undefined;
1230 }
1231
1232 const resolved = await resolveLikeNode(this, importee, importer, custom);
1233 if (resolved) {
1234 // This way, plugins may attach additional meta information to the
1235 // resolved id or make it external. We do not skip node-resolve here
1236 // because another plugin might again use `this.resolve` in its
1237 // `resolveId` hook, in which case we want to add the correct
1238 // `moduleSideEffects` information.
1239 const resolvedResolved = await this.resolve(resolved.id, importer, {
1240 ...resolveOptions,
1241 custom: { ...custom, 'node-resolve': { ...custom['node-resolve'], resolved } }
1242 });
1243 if (resolvedResolved) {
1244 // Handle plugins that manually make the result external
1245 if (resolvedResolved.external) {
1246 return false;
1247 }
1248 // Allow other plugins to take over resolution. Rollup core will not
1249 // change the id if it corresponds to an existing file
1250 if (resolvedResolved.id !== resolved.id) {
1251 return resolvedResolved;
1252 }
1253 // Pass on meta information added by other plugins
1254 return { ...resolved, meta: resolvedResolved.meta };
1255 }
1256 }
1257 return resolved;
1258 }
1259 },
1260
1261 load(importee) {
1262 if (importee === ES6_BROWSER_EMPTY) {
1263 return 'export default {};';
1264 }
1265 return null;
1266 },
1267
1268 getPackageInfoForId(id) {
1269 return idToPackageInfo.get(id);
1270 }
1271 };
1272}
1273
1274exports.DEFAULTS = DEFAULTS;
1275exports.default = nodeResolve;
1276exports.nodeResolve = nodeResolve;
1277module.exports = Object.assign(exports.default, exports);
1278//# sourceMappingURL=index.js.map