UNPKG

19.3 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, '__esModule', { value: true });
4
5function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
6
7var path = require('path');
8var builtinList = _interopDefault(require('builtin-modules'));
9var deepFreeze = _interopDefault(require('deep-freeze'));
10var deepMerge = _interopDefault(require('deepmerge'));
11var isModule = _interopDefault(require('is-module'));
12var fs = require('fs');
13var fs__default = _interopDefault(fs);
14var util = require('util');
15var pluginutils = require('@rollup/pluginutils');
16var resolveModule = _interopDefault(require('resolve'));
17
18function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
19 try {
20 var info = gen[key](arg);
21 var value = info.value;
22 } catch (error) {
23 reject(error);
24 return;
25 }
26
27 if (info.done) {
28 resolve(value);
29 } else {
30 Promise.resolve(value).then(_next, _throw);
31 }
32}
33
34function _asyncToGenerator(fn) {
35 return function () {
36 var self = this,
37 args = arguments;
38 return new Promise(function (resolve, reject) {
39 var gen = fn.apply(self, args);
40
41 function _next(value) {
42 asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
43 }
44
45 function _throw(err) {
46 asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
47 }
48
49 _next(undefined);
50 });
51 };
52}
53
54function _unsupportedIterableToArray(o, minLen) {
55 if (!o) return;
56 if (typeof o === "string") return _arrayLikeToArray(o, minLen);
57 var n = Object.prototype.toString.call(o).slice(8, -1);
58 if (n === "Object" && o.constructor) n = o.constructor.name;
59 if (n === "Map" || n === "Set") return Array.from(n);
60 if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
61}
62
63function _arrayLikeToArray(arr, len) {
64 if (len == null || len > arr.length) len = arr.length;
65
66 for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
67
68 return arr2;
69}
70
71function _createForOfIteratorHelper(o) {
72 if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) {
73 if (Array.isArray(o) || (o = _unsupportedIterableToArray(o))) {
74 var i = 0;
75
76 var F = function () {};
77
78 return {
79 s: F,
80 n: function () {
81 if (i >= o.length) return {
82 done: true
83 };
84 return {
85 done: false,
86 value: o[i++]
87 };
88 },
89 e: function (e) {
90 throw e;
91 },
92 f: F
93 };
94 }
95
96 throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
97 }
98
99 var it,
100 normalCompletion = true,
101 didErr = false,
102 err;
103 return {
104 s: function () {
105 it = o[Symbol.iterator]();
106 },
107 n: function () {
108 var step = it.next();
109 normalCompletion = step.done;
110 return step;
111 },
112 e: function (e) {
113 didErr = true;
114 err = e;
115 },
116 f: function () {
117 try {
118 if (!normalCompletion && it.return != null) it.return();
119 } finally {
120 if (didErr) throw err;
121 }
122 }
123 };
124}
125
126const exists = util.promisify(fs__default.exists);
127const readFile = util.promisify(fs__default.readFile);
128const realpath = util.promisify(fs__default.realpath);
129const stat = util.promisify(fs__default.stat);
130
131const onError = error => {
132 if (error.code === 'ENOENT') {
133 return false;
134 }
135
136 throw error;
137};
138
139const makeCache = fn => {
140 const cache = new Map();
141
142 const wrapped = /*#__PURE__*/function () {
143 var _ref = _asyncToGenerator(function* (param, done) {
144 if (cache.has(param) === false) {
145 cache.set(param, fn(param).catch(err => {
146 cache.delete(param);
147 throw err;
148 }));
149 }
150
151 try {
152 const result = cache.get(param);
153 const value = yield result;
154 return done(null, value);
155 } catch (error) {
156 return done(error);
157 }
158 });
159
160 return function wrapped(_x, _x2) {
161 return _ref.apply(this, arguments);
162 };
163 }();
164
165 wrapped.clear = () => cache.clear();
166
167 return wrapped;
168};
169
170const isDirCached = makeCache( /*#__PURE__*/function () {
171 var _ref2 = _asyncToGenerator(function* (file) {
172 try {
173 const stats = yield stat(file);
174 return stats.isDirectory();
175 } catch (error) {
176 return onError(error);
177 }
178 });
179
180 return function (_x3) {
181 return _ref2.apply(this, arguments);
182 };
183}());
184const isFileCached = makeCache( /*#__PURE__*/function () {
185 var _ref3 = _asyncToGenerator(function* (file) {
186 try {
187 const stats = yield stat(file);
188 return stats.isFile();
189 } catch (error) {
190 return onError(error);
191 }
192 });
193
194 return function (_x4) {
195 return _ref3.apply(this, arguments);
196 };
197}());
198const readCachedFile = makeCache(readFile);
199
200const resolveId = util.promisify(resolveModule); // returns the imported package name for bare module imports
201
202function getPackageName(id) {
203 if (id.startsWith('.') || id.startsWith('/')) {
204 return null;
205 }
206
207 const split = id.split('/'); // @my-scope/my-package/foo.js -> @my-scope/my-package
208 // @my-scope/my-package -> @my-scope/my-package
209
210 if (split[0][0] === '@') {
211 return `${split[0]}/${split[1]}`;
212 } // my-package/foo.js -> my-package
213 // my-package -> my-package
214
215
216 return split[0];
217}
218function getMainFields(options) {
219 let mainFields;
220
221 if (options.mainFields) {
222 mainFields = options.mainFields;
223 } else {
224 mainFields = ['module', 'main'];
225 }
226
227 if (options.browser && mainFields.indexOf('browser') === -1) {
228 return ['browser'].concat(mainFields);
229 }
230
231 if (!mainFields.length) {
232 throw new Error('Please ensure at least one `mainFields` value is specified');
233 }
234
235 return mainFields;
236}
237function getPackageInfo(options) {
238 const cache = options.cache,
239 extensions = options.extensions,
240 pkg = options.pkg,
241 mainFields = options.mainFields,
242 preserveSymlinks = options.preserveSymlinks,
243 useBrowserOverrides = options.useBrowserOverrides;
244 let pkgPath = options.pkgPath;
245
246 if (cache.has(pkgPath)) {
247 return cache.get(pkgPath);
248 } // browserify/resolve doesn't realpath paths returned in its packageFilter callback
249
250
251 if (!preserveSymlinks) {
252 pkgPath = fs.realpathSync(pkgPath);
253 }
254
255 const pkgRoot = path.dirname(pkgPath);
256 const packageInfo = {
257 // copy as we are about to munge the `main` field of `pkg`.
258 packageJson: Object.assign({}, pkg),
259 // path to package.json file
260 packageJsonPath: pkgPath,
261 // directory containing the package.json
262 root: pkgRoot,
263 // which main field was used during resolution of this module (main, module, or browser)
264 resolvedMainField: 'main',
265 // whether the browser map was used to resolve the entry point to this module
266 browserMappedMain: false,
267 // the entry point of the module with respect to the selected main field and any
268 // relevant browser mappings.
269 resolvedEntryPoint: ''
270 };
271 let overriddenMain = false;
272
273 for (let i = 0; i < mainFields.length; i++) {
274 const field = mainFields[i];
275
276 if (typeof pkg[field] === 'string') {
277 pkg.main = pkg[field];
278 packageInfo.resolvedMainField = field;
279 overriddenMain = true;
280 break;
281 }
282 }
283
284 const internalPackageInfo = {
285 cachedPkg: pkg,
286 hasModuleSideEffects: () => null,
287 hasPackageEntry: overriddenMain !== false || mainFields.indexOf('main') !== -1,
288 packageBrowserField: useBrowserOverrides && typeof pkg.browser === 'object' && Object.keys(pkg.browser).reduce((browser, key) => {
289 let resolved = pkg.browser[key];
290
291 if (resolved && resolved[0] === '.') {
292 resolved = path.resolve(pkgRoot, resolved);
293 }
294 /* eslint-disable no-param-reassign */
295
296
297 browser[key] = resolved;
298
299 if (key[0] === '.') {
300 const absoluteKey = path.resolve(pkgRoot, key);
301 browser[absoluteKey] = resolved;
302
303 if (!path.extname(key)) {
304 extensions.reduce((subBrowser, ext) => {
305 subBrowser[absoluteKey + ext] = subBrowser[key];
306 return subBrowser;
307 }, browser);
308 }
309 }
310
311 return browser;
312 }, {}),
313 packageInfo
314 };
315 const browserMap = internalPackageInfo.packageBrowserField;
316
317 if (useBrowserOverrides && typeof pkg.browser === 'object' && // eslint-disable-next-line no-prototype-builtins
318 browserMap.hasOwnProperty(pkg.main)) {
319 packageInfo.resolvedEntryPoint = browserMap[pkg.main];
320 packageInfo.browserMappedMain = true;
321 } else {
322 // index.node is technically a valid default entrypoint as well...
323 packageInfo.resolvedEntryPoint = path.resolve(pkgRoot, pkg.main || 'index.js');
324 packageInfo.browserMappedMain = false;
325 }
326
327 const packageSideEffects = pkg.sideEffects;
328
329 if (typeof packageSideEffects === 'boolean') {
330 internalPackageInfo.hasModuleSideEffects = () => packageSideEffects;
331 } else if (Array.isArray(packageSideEffects)) {
332 internalPackageInfo.hasModuleSideEffects = pluginutils.createFilter(packageSideEffects, null, {
333 resolve: pkgRoot
334 });
335 }
336
337 cache.set(pkgPath, internalPackageInfo);
338 return internalPackageInfo;
339}
340function normalizeInput(input) {
341 if (Array.isArray(input)) {
342 return input;
343 } else if (typeof input === 'object') {
344 return Object.values(input);
345 } // otherwise it's a string
346
347
348 return [input];
349} // Resolve module specifiers in order. Promise resolves to the first module that resolves
350// successfully, or the error that resulted from the last attempted module resolution.
351
352function resolveImportSpecifiers(importSpecifierList, resolveOptions) {
353 let promise = Promise.resolve();
354
355 for (let i = 0; i < importSpecifierList.length; i++) {
356 promise = promise.then(value => {
357 // if we've already resolved to something, just return it.
358 if (value) {
359 return value;
360 }
361
362 return resolveId(importSpecifierList[i], resolveOptions).then(result => {
363 if (!resolveOptions.preserveSymlinks) {
364 result = fs.realpathSync(result);
365 }
366
367 return result;
368 });
369 });
370
371 if (i < importSpecifierList.length - 1) {
372 // swallow MODULE_NOT_FOUND errors from all but the last resolution
373 promise = promise.catch(error => {
374 if (error.code !== 'MODULE_NOT_FOUND') {
375 throw error;
376 }
377 });
378 }
379 }
380
381 return promise;
382}
383
384const builtins = new Set(builtinList);
385const ES6_BROWSER_EMPTY = '\0node-resolve:empty.js';
386
387const nullFn = () => null;
388
389const defaults = {
390 customResolveOptions: {},
391 dedupe: [],
392 // It's important that .mjs is listed before .js so that Rollup will interpret npm modules
393 // which deploy both ESM .mjs and CommonJS .js files as ESM.
394 extensions: ['.mjs', '.js', '.json', '.node'],
395 resolveOnly: []
396};
397const DEFAULTS = deepFreeze(deepMerge({}, defaults));
398function nodeResolve(opts = {}) {
399 const options = Object.assign({}, defaults, opts);
400 const customResolveOptions = options.customResolveOptions,
401 extensions = options.extensions,
402 jail = options.jail;
403 const warnings = [];
404 const packageInfoCache = new Map();
405 const idToPackageInfo = new Map();
406 const mainFields = getMainFields(options);
407 const useBrowserOverrides = mainFields.indexOf('browser') !== -1;
408 const isPreferBuiltinsSet = options.preferBuiltins === true || options.preferBuiltins === false;
409 const preferBuiltins = isPreferBuiltinsSet ? options.preferBuiltins : true;
410 const rootDir = options.rootDir || process.cwd();
411 let dedupe = options.dedupe;
412 let rollupOptions;
413
414 if (options.only) {
415 warnings.push('node-resolve: The `only` options is deprecated, please use `resolveOnly`');
416 options.resolveOnly = options.only;
417 }
418
419 if (typeof dedupe !== 'function') {
420 dedupe = importee => options.dedupe.includes(importee) || options.dedupe.includes(getPackageName(importee));
421 }
422
423 const resolveOnly = options.resolveOnly.map(pattern => {
424 if (pattern instanceof RegExp) {
425 return pattern;
426 }
427
428 const normalized = pattern.replace(/[\\^$*+?.()|[\]{}]/g, '\\$&');
429 return new RegExp(`^${normalized}$`);
430 });
431 const browserMapCache = new Map();
432 let preserveSymlinks;
433 return {
434 name: 'node-resolve',
435
436 buildStart(options) {
437 rollupOptions = options;
438
439 var _iterator = _createForOfIteratorHelper(warnings),
440 _step;
441
442 try {
443 for (_iterator.s(); !(_step = _iterator.n()).done;) {
444 const warning = _step.value;
445 this.warn(warning);
446 }
447 } catch (err) {
448 _iterator.e(err);
449 } finally {
450 _iterator.f();
451 }
452
453 preserveSymlinks = options.preserveSymlinks;
454 },
455
456 generateBundle() {
457 readCachedFile.clear();
458 isFileCached.clear();
459 isDirCached.clear();
460 },
461
462 resolveId(importee, importer) {
463 var _this = this;
464
465 return _asyncToGenerator(function* () {
466 if (importee === ES6_BROWSER_EMPTY) {
467 return importee;
468 } // ignore IDs with null character, these belong to other plugins
469
470
471 if (/\0/.test(importee)) return null;
472 const basedir = !importer || dedupe(importee) ? rootDir : path.dirname(importer); // https://github.com/defunctzombie/package-browser-field-spec
473
474 const browser = browserMapCache.get(importer);
475
476 if (useBrowserOverrides && browser) {
477 const resolvedImportee = path.resolve(basedir, importee);
478
479 if (browser[importee] === false || browser[resolvedImportee] === false) {
480 return ES6_BROWSER_EMPTY;
481 }
482
483 const browserImportee = browser[importee] || browser[resolvedImportee] || browser[`${resolvedImportee}.js`] || browser[`${resolvedImportee}.json`];
484
485 if (browserImportee) {
486 importee = browserImportee;
487 }
488 }
489
490 const parts = importee.split(/[/\\]/);
491 let id = parts.shift();
492 let isRelativeImport = false;
493
494 if (id[0] === '@' && parts.length > 0) {
495 // scoped packages
496 id += `/${parts.shift()}`;
497 } else if (id[0] === '.') {
498 // an import relative to the parent dir of the importer
499 id = path.resolve(basedir, importee);
500 isRelativeImport = true;
501 }
502
503 if (!isRelativeImport && resolveOnly.length && !resolveOnly.some(pattern => pattern.test(id))) {
504 if (normalizeInput(rollupOptions.input).includes(importee)) {
505 return null;
506 }
507
508 return false;
509 }
510
511 let hasModuleSideEffects = nullFn;
512 let hasPackageEntry = true;
513 let packageBrowserField = false;
514 let packageInfo;
515
516 const filter = (pkg, pkgPath) => {
517 const info = getPackageInfo({
518 cache: packageInfoCache,
519 extensions,
520 pkg,
521 pkgPath,
522 mainFields,
523 preserveSymlinks,
524 useBrowserOverrides
525 });
526 packageInfo = info.packageInfo;
527 hasModuleSideEffects = info.hasModuleSideEffects;
528 hasPackageEntry = info.hasPackageEntry;
529 packageBrowserField = info.packageBrowserField;
530 return info.cachedPkg;
531 };
532
533 let resolveOptions = {
534 basedir,
535 packageFilter: filter,
536 readFile: readCachedFile,
537 isFile: isFileCached,
538 isDirectory: isDirCached,
539 extensions
540 };
541
542 if (preserveSymlinks !== undefined) {
543 resolveOptions.preserveSymlinks = preserveSymlinks;
544 }
545
546 const importSpecifierList = [];
547
548 if (importer === undefined && !importee[0].match(/^\.?\.?\//)) {
549 // For module graph roots (i.e. when importer is undefined), we
550 // need to handle 'path fragments` like `foo/bar` that are commonly
551 // found in rollup config files. If importee doesn't look like a
552 // relative or absolute path, we make it relative and attempt to
553 // resolve it. If we don't find anything, we try resolving it as we
554 // got it.
555 importSpecifierList.push(`./${importee}`);
556 }
557
558 const importeeIsBuiltin = builtins.has(importee);
559
560 if (importeeIsBuiltin && (!preferBuiltins || !isPreferBuiltinsSet)) {
561 // The `resolve` library will not resolve packages with the same
562 // name as a node built-in module. If we're resolving something
563 // that's a builtin, and we don't prefer to find built-ins, we
564 // first try to look up a local module with that name. If we don't
565 // find anything, we resolve the builtin which just returns back
566 // the built-in's name.
567 importSpecifierList.push(`${importee}/`);
568 }
569
570 importSpecifierList.push(importee);
571 resolveOptions = Object.assign(resolveOptions, customResolveOptions);
572
573 try {
574 let resolved = yield resolveImportSpecifiers(importSpecifierList, resolveOptions);
575
576 if (resolved && packageBrowserField) {
577 if (Object.prototype.hasOwnProperty.call(packageBrowserField, resolved)) {
578 if (!packageBrowserField[resolved]) {
579 browserMapCache.set(resolved, packageBrowserField);
580 return ES6_BROWSER_EMPTY;
581 }
582
583 resolved = packageBrowserField[resolved];
584 }
585
586 browserMapCache.set(resolved, packageBrowserField);
587 }
588
589 if (hasPackageEntry && !preserveSymlinks && resolved) {
590 const fileExists = yield exists(resolved);
591
592 if (fileExists) {
593 resolved = yield realpath(resolved);
594 }
595 }
596
597 idToPackageInfo.set(resolved, packageInfo);
598
599 if (hasPackageEntry) {
600 if (builtins.has(resolved) && preferBuiltins && isPreferBuiltinsSet) {
601 return null;
602 } else if (importeeIsBuiltin && preferBuiltins) {
603 if (!isPreferBuiltinsSet) {
604 _this.warn(`preferring built-in module '${importee}' over local alternative at '${resolved}', pass 'preferBuiltins: false' to disable this behavior or 'preferBuiltins: true' to disable this warning`);
605 }
606
607 return null;
608 } else if (jail && resolved.indexOf(path.normalize(jail.trim(path.sep))) !== 0) {
609 return null;
610 }
611 }
612
613 if (resolved && options.modulesOnly) {
614 const code = yield readFile(resolved, 'utf-8');
615
616 if (isModule(code)) {
617 return {
618 id: resolved,
619 moduleSideEffects: hasModuleSideEffects(resolved)
620 };
621 }
622
623 return null;
624 }
625
626 const result = {
627 id: resolved,
628 moduleSideEffects: hasModuleSideEffects(resolved)
629 };
630 return result;
631 } catch (error) {
632 return null;
633 }
634 })();
635 },
636
637 load(importee) {
638 if (importee === ES6_BROWSER_EMPTY) {
639 return 'export default {};';
640 }
641
642 return null;
643 },
644
645 getPackageInfoForId(id) {
646 return idToPackageInfo.get(id);
647 }
648
649 };
650}
651
652exports.DEFAULTS = DEFAULTS;
653exports.default = nodeResolve;
654exports.nodeResolve = nodeResolve;