1 | 'use strict';
|
2 |
|
3 | Object.defineProperty(exports, '__esModule', { value: true });
|
4 |
|
5 | var path = require('path');
|
6 | var builtinList = require('builtin-modules');
|
7 | var deepMerge = require('deepmerge');
|
8 | var isModule = require('is-module');
|
9 | var fs = require('fs');
|
10 | var util = require('util');
|
11 | var pluginutils = require('@rollup/pluginutils');
|
12 | var resolveModule = require('resolve');
|
13 |
|
14 | function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
15 |
|
16 | var builtinList__default = _interopDefaultLegacy(builtinList);
|
17 | var deepMerge__default = _interopDefaultLegacy(deepMerge);
|
18 | var isModule__default = _interopDefaultLegacy(isModule);
|
19 | var fs__default = _interopDefaultLegacy(fs);
|
20 | var resolveModule__default = _interopDefaultLegacy(resolveModule);
|
21 |
|
22 | const exists = util.promisify(fs__default['default'].exists);
|
23 | const readFile = util.promisify(fs__default['default'].readFile);
|
24 | const realpath = util.promisify(fs__default['default'].realpath);
|
25 | const stat = util.promisify(fs__default['default'].stat);
|
26 |
|
27 | const onError = (error) => {
|
28 | if (error.code === 'ENOENT') {
|
29 | return false;
|
30 | }
|
31 | throw error;
|
32 | };
|
33 |
|
34 | const makeCache = (fn) => {
|
35 | const cache = new Map();
|
36 | const wrapped = async (param, done) => {
|
37 | if (cache.has(param) === false) {
|
38 | cache.set(
|
39 | param,
|
40 | fn(param).catch((err) => {
|
41 | cache.delete(param);
|
42 | throw err;
|
43 | })
|
44 | );
|
45 | }
|
46 |
|
47 | try {
|
48 | const result = cache.get(param);
|
49 | const value = await result;
|
50 | return done(null, value);
|
51 | } catch (error) {
|
52 | return done(error);
|
53 | }
|
54 | };
|
55 |
|
56 | wrapped.clear = () => cache.clear();
|
57 |
|
58 | return wrapped;
|
59 | };
|
60 |
|
61 | const isDirCached = makeCache(async (file) => {
|
62 | try {
|
63 | const stats = await stat(file);
|
64 | return stats.isDirectory();
|
65 | } catch (error) {
|
66 | return onError(error);
|
67 | }
|
68 | });
|
69 |
|
70 | const isFileCached = makeCache(async (file) => {
|
71 | try {
|
72 | const stats = await stat(file);
|
73 | return stats.isFile();
|
74 | } catch (error) {
|
75 | return onError(error);
|
76 | }
|
77 | });
|
78 |
|
79 | const readCachedFile = makeCache(readFile);
|
80 |
|
81 | const resolveId = util.promisify(resolveModule__default['default']);
|
82 |
|
83 |
|
84 | function getPackageName(id) {
|
85 | if (id.startsWith('.') || id.startsWith('/')) {
|
86 | return null;
|
87 | }
|
88 |
|
89 | const split = id.split('/');
|
90 |
|
91 |
|
92 |
|
93 | if (split[0][0] === '@') {
|
94 | return `${split[0]}/${split[1]}`;
|
95 | }
|
96 |
|
97 |
|
98 |
|
99 | return split[0];
|
100 | }
|
101 |
|
102 | function getMainFields(options) {
|
103 | let mainFields;
|
104 | if (options.mainFields) {
|
105 | ({ mainFields } = options);
|
106 | } else {
|
107 | mainFields = ['module', 'main'];
|
108 | }
|
109 | if (options.browser && mainFields.indexOf('browser') === -1) {
|
110 | return ['browser'].concat(mainFields);
|
111 | }
|
112 | if (!mainFields.length) {
|
113 | throw new Error('Please ensure at least one `mainFields` value is specified');
|
114 | }
|
115 | return mainFields;
|
116 | }
|
117 |
|
118 | function getPackageInfo(options) {
|
119 | const { cache, extensions, pkg, mainFields, preserveSymlinks, useBrowserOverrides } = options;
|
120 | let { pkgPath } = options;
|
121 |
|
122 | if (cache.has(pkgPath)) {
|
123 | return cache.get(pkgPath);
|
124 | }
|
125 |
|
126 |
|
127 | if (!preserveSymlinks) {
|
128 | pkgPath = fs.realpathSync(pkgPath);
|
129 | }
|
130 |
|
131 | const pkgRoot = path.dirname(pkgPath);
|
132 |
|
133 | const packageInfo = {
|
134 |
|
135 | packageJson: Object.assign({}, pkg),
|
136 |
|
137 |
|
138 | packageJsonPath: pkgPath,
|
139 |
|
140 |
|
141 | root: pkgRoot,
|
142 |
|
143 |
|
144 | resolvedMainField: 'main',
|
145 |
|
146 |
|
147 | browserMappedMain: false,
|
148 |
|
149 |
|
150 |
|
151 | resolvedEntryPoint: ''
|
152 | };
|
153 |
|
154 | let overriddenMain = false;
|
155 | for (let i = 0; i < mainFields.length; i++) {
|
156 | const field = mainFields[i];
|
157 | if (typeof pkg[field] === 'string') {
|
158 | pkg.main = pkg[field];
|
159 | packageInfo.resolvedMainField = field;
|
160 | overriddenMain = true;
|
161 | break;
|
162 | }
|
163 | }
|
164 |
|
165 | const internalPackageInfo = {
|
166 | cachedPkg: pkg,
|
167 | hasModuleSideEffects: () => null,
|
168 | hasPackageEntry: overriddenMain !== false || mainFields.indexOf('main') !== -1,
|
169 | packageBrowserField:
|
170 | useBrowserOverrides &&
|
171 | typeof pkg.browser === 'object' &&
|
172 | Object.keys(pkg.browser).reduce((browser, key) => {
|
173 | let resolved = pkg.browser[key];
|
174 | if (resolved && resolved[0] === '.') {
|
175 | resolved = path.resolve(pkgRoot, resolved);
|
176 | }
|
177 |
|
178 | browser[key] = resolved;
|
179 | if (key[0] === '.') {
|
180 | const absoluteKey = path.resolve(pkgRoot, key);
|
181 | browser[absoluteKey] = resolved;
|
182 | if (!path.extname(key)) {
|
183 | extensions.reduce((subBrowser, ext) => {
|
184 | subBrowser[absoluteKey + ext] = subBrowser[key];
|
185 | return subBrowser;
|
186 | }, browser);
|
187 | }
|
188 | }
|
189 | return browser;
|
190 | }, {}),
|
191 | packageInfo
|
192 | };
|
193 |
|
194 | const browserMap = internalPackageInfo.packageBrowserField;
|
195 | if (
|
196 | useBrowserOverrides &&
|
197 | typeof pkg.browser === 'object' &&
|
198 |
|
199 | browserMap.hasOwnProperty(pkg.main)
|
200 | ) {
|
201 | packageInfo.resolvedEntryPoint = browserMap[pkg.main];
|
202 | packageInfo.browserMappedMain = true;
|
203 | } else {
|
204 |
|
205 | packageInfo.resolvedEntryPoint = path.resolve(pkgRoot, pkg.main || 'index.js');
|
206 | packageInfo.browserMappedMain = false;
|
207 | }
|
208 |
|
209 | const packageSideEffects = pkg.sideEffects;
|
210 | if (typeof packageSideEffects === 'boolean') {
|
211 | internalPackageInfo.hasModuleSideEffects = () => packageSideEffects;
|
212 | } else if (Array.isArray(packageSideEffects)) {
|
213 | internalPackageInfo.hasModuleSideEffects = pluginutils.createFilter(packageSideEffects, null, {
|
214 | resolve: pkgRoot
|
215 | });
|
216 | }
|
217 |
|
218 | cache.set(pkgPath, internalPackageInfo);
|
219 | return internalPackageInfo;
|
220 | }
|
221 |
|
222 | function normalizeInput(input) {
|
223 | if (Array.isArray(input)) {
|
224 | return input;
|
225 | } else if (typeof input === 'object') {
|
226 | return Object.values(input);
|
227 | }
|
228 |
|
229 |
|
230 | return [input];
|
231 | }
|
232 |
|
233 |
|
234 |
|
235 | function resolveImportSpecifiers(importSpecifierList, resolveOptions) {
|
236 | let promise = Promise.resolve();
|
237 |
|
238 | for (let i = 0; i < importSpecifierList.length; i++) {
|
239 |
|
240 | promise = promise.then(async (value) => {
|
241 |
|
242 | if (value) {
|
243 | return value;
|
244 | }
|
245 |
|
246 | let result = await resolveId(importSpecifierList[i], resolveOptions);
|
247 | if (!resolveOptions.preserveSymlinks) {
|
248 | if (await exists(result)) {
|
249 | result = await realpath(result);
|
250 | }
|
251 | }
|
252 | return result;
|
253 | });
|
254 |
|
255 |
|
256 | promise = promise.catch((error) => {
|
257 | if (error.code !== 'MODULE_NOT_FOUND') {
|
258 | throw error;
|
259 | }
|
260 | });
|
261 | }
|
262 |
|
263 | return promise;
|
264 | }
|
265 |
|
266 |
|
267 |
|
268 | const builtins = new Set(builtinList__default['default']);
|
269 | const ES6_BROWSER_EMPTY = '\0node-resolve:empty.js';
|
270 | const nullFn = () => null;
|
271 | const deepFreeze = (object) => {
|
272 | Object.freeze(object);
|
273 |
|
274 | for (const value of Object.values(object)) {
|
275 | if (typeof value === 'object' && !Object.isFrozen(value)) {
|
276 | deepFreeze(value);
|
277 | }
|
278 | }
|
279 |
|
280 | return object;
|
281 | };
|
282 | const defaults = {
|
283 | customResolveOptions: {},
|
284 | dedupe: [],
|
285 |
|
286 |
|
287 | extensions: ['.mjs', '.js', '.json', '.node'],
|
288 | resolveOnly: []
|
289 | };
|
290 | const DEFAULTS = deepFreeze(deepMerge__default['default']({}, defaults));
|
291 |
|
292 | function nodeResolve(opts = {}) {
|
293 | const options = Object.assign({}, defaults, opts);
|
294 | const { customResolveOptions, extensions, jail } = options;
|
295 | const warnings = [];
|
296 | const packageInfoCache = new Map();
|
297 | const idToPackageInfo = new Map();
|
298 | const mainFields = getMainFields(options);
|
299 | const useBrowserOverrides = mainFields.indexOf('browser') !== -1;
|
300 | const isPreferBuiltinsSet = options.preferBuiltins === true || options.preferBuiltins === false;
|
301 | const preferBuiltins = isPreferBuiltinsSet ? options.preferBuiltins : true;
|
302 | const rootDir = options.rootDir || process.cwd();
|
303 | let { dedupe } = options;
|
304 | let rollupOptions;
|
305 |
|
306 | if (options.only) {
|
307 | warnings.push('node-resolve: The `only` options is deprecated, please use `resolveOnly`');
|
308 | options.resolveOnly = options.only;
|
309 | }
|
310 |
|
311 | if (typeof dedupe !== 'function') {
|
312 | dedupe = (importee) =>
|
313 | options.dedupe.includes(importee) || options.dedupe.includes(getPackageName(importee));
|
314 | }
|
315 |
|
316 | const resolveOnly = options.resolveOnly.map((pattern) => {
|
317 | if (pattern instanceof RegExp) {
|
318 | return pattern;
|
319 | }
|
320 | const normalized = pattern.replace(/[\\^$*+?.()|[\]{}]/g, '\\$&');
|
321 | return new RegExp(`^${normalized}$`);
|
322 | });
|
323 |
|
324 | const browserMapCache = new Map();
|
325 | let preserveSymlinks;
|
326 |
|
327 | return {
|
328 | name: 'node-resolve',
|
329 |
|
330 | buildStart(options) {
|
331 | rollupOptions = options;
|
332 |
|
333 | for (const warning of warnings) {
|
334 | this.warn(warning);
|
335 | }
|
336 |
|
337 | ({ preserveSymlinks } = options);
|
338 | },
|
339 |
|
340 | generateBundle() {
|
341 | readCachedFile.clear();
|
342 | isFileCached.clear();
|
343 | isDirCached.clear();
|
344 | },
|
345 |
|
346 | async resolveId(importee, importer) {
|
347 | if (importee === ES6_BROWSER_EMPTY) {
|
348 | return importee;
|
349 | }
|
350 |
|
351 | if (/\0/.test(importee)) return null;
|
352 |
|
353 | if (/\0/.test(importer)) {
|
354 | importer = undefined;
|
355 | }
|
356 |
|
357 |
|
358 | const [importPath, params] = importee.split('?');
|
359 | const importSuffix = `${params ? `?${params}` : ''}`;
|
360 | importee = importPath;
|
361 |
|
362 | const basedir = !importer || dedupe(importee) ? rootDir : path.dirname(importer);
|
363 |
|
364 |
|
365 | const browser = browserMapCache.get(importer);
|
366 | if (useBrowserOverrides && browser) {
|
367 | const resolvedImportee = path.resolve(basedir, importee);
|
368 | if (browser[importee] === false || browser[resolvedImportee] === false) {
|
369 | return ES6_BROWSER_EMPTY;
|
370 | }
|
371 | const browserImportee =
|
372 | browser[importee] ||
|
373 | browser[resolvedImportee] ||
|
374 | browser[`${resolvedImportee}.js`] ||
|
375 | browser[`${resolvedImportee}.json`];
|
376 | if (browserImportee) {
|
377 | importee = browserImportee;
|
378 | }
|
379 | }
|
380 |
|
381 | const parts = importee.split(/[/\\]/);
|
382 | let id = parts.shift();
|
383 | let isRelativeImport = false;
|
384 |
|
385 | if (id[0] === '@' && parts.length > 0) {
|
386 |
|
387 | id += `/${parts.shift()}`;
|
388 | } else if (id[0] === '.') {
|
389 |
|
390 | id = path.resolve(basedir, importee);
|
391 | isRelativeImport = true;
|
392 | }
|
393 |
|
394 | if (
|
395 | !isRelativeImport &&
|
396 | resolveOnly.length &&
|
397 | !resolveOnly.some((pattern) => pattern.test(id))
|
398 | ) {
|
399 | if (normalizeInput(rollupOptions.input).includes(importee)) {
|
400 | return null;
|
401 | }
|
402 | return false;
|
403 | }
|
404 |
|
405 | let hasModuleSideEffects = nullFn;
|
406 | let hasPackageEntry = true;
|
407 | let packageBrowserField = false;
|
408 | let packageInfo;
|
409 |
|
410 | const filter = (pkg, pkgPath) => {
|
411 | const info = getPackageInfo({
|
412 | cache: packageInfoCache,
|
413 | extensions,
|
414 | pkg,
|
415 | pkgPath,
|
416 | mainFields,
|
417 | preserveSymlinks,
|
418 | useBrowserOverrides
|
419 | });
|
420 |
|
421 | ({ packageInfo, hasModuleSideEffects, hasPackageEntry, packageBrowserField } = info);
|
422 |
|
423 | return info.cachedPkg;
|
424 | };
|
425 |
|
426 | let resolveOptions = {
|
427 | basedir,
|
428 | packageFilter: filter,
|
429 | readFile: readCachedFile,
|
430 | isFile: isFileCached,
|
431 | isDirectory: isDirCached,
|
432 | extensions
|
433 | };
|
434 |
|
435 | if (preserveSymlinks !== undefined) {
|
436 | resolveOptions.preserveSymlinks = preserveSymlinks;
|
437 | }
|
438 |
|
439 | const importSpecifierList = [];
|
440 |
|
441 | if (importer === undefined && !importee[0].match(/^\.?\.?\//)) {
|
442 |
|
443 |
|
444 |
|
445 |
|
446 |
|
447 |
|
448 | importSpecifierList.push(`./${importee}`);
|
449 | }
|
450 |
|
451 | const importeeIsBuiltin = builtins.has(importee);
|
452 |
|
453 | if (importeeIsBuiltin && (!preferBuiltins || !isPreferBuiltinsSet)) {
|
454 |
|
455 |
|
456 |
|
457 |
|
458 |
|
459 |
|
460 | importSpecifierList.push(`${importee}/`);
|
461 | }
|
462 |
|
463 |
|
464 | if (importer && importee.endsWith('.js')) {
|
465 | for (const ext of ['.ts', '.tsx']) {
|
466 | if (importer.endsWith(ext) && extensions.includes(ext)) {
|
467 | importSpecifierList.push(importee.replace(/.js$/, ext));
|
468 | }
|
469 | }
|
470 | }
|
471 |
|
472 | importSpecifierList.push(importee);
|
473 | resolveOptions = Object.assign(resolveOptions, customResolveOptions);
|
474 |
|
475 | let resolved = await resolveImportSpecifiers(importSpecifierList, resolveOptions);
|
476 | if (!resolved) {
|
477 | return null;
|
478 | }
|
479 |
|
480 | if (packageBrowserField) {
|
481 | if (Object.prototype.hasOwnProperty.call(packageBrowserField, resolved)) {
|
482 | if (!packageBrowserField[resolved]) {
|
483 | browserMapCache.set(resolved, packageBrowserField);
|
484 | return ES6_BROWSER_EMPTY;
|
485 | }
|
486 | resolved = packageBrowserField[resolved];
|
487 | }
|
488 | browserMapCache.set(resolved, packageBrowserField);
|
489 | }
|
490 |
|
491 | if (hasPackageEntry && !preserveSymlinks) {
|
492 | const fileExists = await exists(resolved);
|
493 | if (fileExists) {
|
494 | resolved = await realpath(resolved);
|
495 | }
|
496 | }
|
497 |
|
498 | idToPackageInfo.set(resolved, packageInfo);
|
499 |
|
500 | if (hasPackageEntry) {
|
501 | if (builtins.has(resolved) && preferBuiltins && isPreferBuiltinsSet) {
|
502 | return null;
|
503 | } else if (importeeIsBuiltin && preferBuiltins) {
|
504 | if (!isPreferBuiltinsSet) {
|
505 | this.warn(
|
506 | `preferring built-in module '${importee}' over local alternative at '${resolved}', pass 'preferBuiltins: false' to disable this behavior or 'preferBuiltins: true' to disable this warning`
|
507 | );
|
508 | }
|
509 | return null;
|
510 | } else if (jail && resolved.indexOf(path.normalize(jail.trim(path.sep))) !== 0) {
|
511 | return null;
|
512 | }
|
513 | }
|
514 |
|
515 | if (options.modulesOnly && (await exists(resolved))) {
|
516 | const code = await readFile(resolved, 'utf-8');
|
517 | if (isModule__default['default'](code)) {
|
518 | return {
|
519 | id: `${resolved}${importSuffix}`,
|
520 | moduleSideEffects: hasModuleSideEffects(resolved)
|
521 | };
|
522 | }
|
523 | return null;
|
524 | }
|
525 | const result = {
|
526 | id: `${resolved}${importSuffix}`,
|
527 | moduleSideEffects: hasModuleSideEffects(resolved)
|
528 | };
|
529 | return result;
|
530 | },
|
531 |
|
532 | load(importee) {
|
533 | if (importee === ES6_BROWSER_EMPTY) {
|
534 | return 'export default {};';
|
535 | }
|
536 | return null;
|
537 | },
|
538 |
|
539 | getPackageInfoForId(id) {
|
540 | return idToPackageInfo.get(id);
|
541 | }
|
542 | };
|
543 | }
|
544 |
|
545 | exports.DEFAULTS = DEFAULTS;
|
546 | exports.default = nodeResolve;
|
547 | exports.nodeResolve = nodeResolve;
|