UNPKG

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