index.js 31 KB

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