@rollup/plugin-commonjs 16.0.0 → 17.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -4,23 +4,87 @@ var path = require('path');
4
4
  var pluginutils = require('@rollup/pluginutils');
5
5
  var getCommonDir = require('commondir');
6
6
  var fs = require('fs');
7
+ var glob = require('glob');
7
8
  var estreeWalker = require('estree-walker');
8
9
  var MagicString = require('magic-string');
9
- var resolve = require('resolve');
10
10
  var isReference = require('is-reference');
11
- var glob = require('glob');
11
+ var resolve = require('resolve');
12
12
 
13
13
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
14
14
 
15
15
  var getCommonDir__default = /*#__PURE__*/_interopDefaultLegacy(getCommonDir);
16
+ var glob__default = /*#__PURE__*/_interopDefaultLegacy(glob);
16
17
  var MagicString__default = /*#__PURE__*/_interopDefaultLegacy(MagicString);
17
18
  var isReference__default = /*#__PURE__*/_interopDefaultLegacy(isReference);
18
- var glob__default = /*#__PURE__*/_interopDefaultLegacy(glob);
19
19
 
20
20
  var peerDependencies = {
21
21
  rollup: "^2.30.0"
22
22
  };
23
23
 
24
+ function tryParse(parse, code, id) {
25
+ try {
26
+ return parse(code, { allowReturnOutsideFunction: true });
27
+ } catch (err) {
28
+ err.message += ` in ${id}`;
29
+ throw err;
30
+ }
31
+ }
32
+
33
+ const firstpassGlobal = /\b(?:require|module|exports|global)\b/;
34
+
35
+ const firstpassNoGlobal = /\b(?:require|module|exports)\b/;
36
+
37
+ function hasCjsKeywords(code, ignoreGlobal) {
38
+ const firstpass = ignoreGlobal ? firstpassNoGlobal : firstpassGlobal;
39
+ return firstpass.test(code);
40
+ }
41
+
42
+ /* eslint-disable no-underscore-dangle */
43
+
44
+ function analyzeTopLevelStatements(parse, code, id) {
45
+ const ast = tryParse(parse, code, id);
46
+
47
+ let isEsModule = false;
48
+ let hasDefaultExport = false;
49
+ let hasNamedExports = false;
50
+
51
+ for (const node of ast.body) {
52
+ switch (node.type) {
53
+ case 'ExportDefaultDeclaration':
54
+ isEsModule = true;
55
+ hasDefaultExport = true;
56
+ break;
57
+ case 'ExportNamedDeclaration':
58
+ isEsModule = true;
59
+ if (node.declaration) {
60
+ hasNamedExports = true;
61
+ } else {
62
+ for (const specifier of node.specifiers) {
63
+ if (specifier.exported.name === 'default') {
64
+ hasDefaultExport = true;
65
+ } else {
66
+ hasNamedExports = true;
67
+ }
68
+ }
69
+ }
70
+ break;
71
+ case 'ExportAllDeclaration':
72
+ isEsModule = true;
73
+ if (node.exported && node.exported.name === 'default') {
74
+ hasDefaultExport = true;
75
+ } else {
76
+ hasNamedExports = true;
77
+ }
78
+ break;
79
+ case 'ImportDeclaration':
80
+ isEsModule = true;
81
+ break;
82
+ }
83
+ }
84
+
85
+ return { isEsModule, hasDefaultExport, hasNamedExports, ast };
86
+ }
87
+
24
88
  const isWrappedId = (id, suffix) => id.endsWith(suffix);
25
89
  const wrapId = (id, suffix) => `\0${id}${suffix}`;
26
90
  const unwrapId = (wrappedId, suffix) => wrappedId.slice(1, -suffix.length);
@@ -29,12 +93,6 @@ const PROXY_SUFFIX = '?commonjs-proxy';
29
93
  const REQUIRE_SUFFIX = '?commonjs-require';
30
94
  const EXTERNAL_SUFFIX = '?commonjs-external';
31
95
 
32
- const VIRTUAL_PATH_BASE = '/$$rollup_base$$';
33
- const getVirtualPathForDynamicRequirePath = (path, commonDir) => {
34
- if (path.startsWith(commonDir)) return VIRTUAL_PATH_BASE + path.slice(commonDir.length);
35
- return path;
36
- };
37
-
38
96
  const DYNAMIC_REGISTER_PREFIX = '\0commonjs-dynamic-register:';
39
97
  const DYNAMIC_JSON_PREFIX = '\0commonjs-dynamic-json:';
40
98
  const DYNAMIC_PACKAGES_ID = '\0commonjs-dynamic-packages';
@@ -46,11 +104,6 @@ const HELPERS_ID = '\0commonjsHelpers.js';
46
104
  // This will no longer be necessary once Rollup switches to ES6 output, likely
47
105
  // in Rollup 3
48
106
 
49
- // The "hasOwnProperty" call in "getDefaultExportFromCjs" is technically not
50
- // needed, but for consumers that use Rollup's old interop pattern, it will fix
51
- // rollup/rollup-plugin-commonjs#224
52
- // We should remove it once Rollup core and this plugin are updated to not use
53
- // this pattern any more
54
107
  const HELPERS = `
55
108
  export var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
56
109
 
@@ -58,16 +111,6 @@ export function getDefaultExportFromCjs (x) {
58
111
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
59
112
  }
60
113
 
61
- export function createCommonjsModule(fn, basedir, module) {
62
- return module = {
63
- path: basedir,
64
- exports: {},
65
- require: function (path, base) {
66
- return commonjsRequire(path, (base === undefined || base === null) ? module.path : base);
67
- }
68
- }, fn(module, module.exports), module.exports;
69
- }
70
-
71
114
  export function getDefaultExportFromNamespaceIfPresent (n) {
72
115
  return n && Object.prototype.hasOwnProperty.call(n, 'default') ? n['default'] : n;
73
116
  }
@@ -93,12 +136,27 @@ export function getAugmentedNamespace(n) {
93
136
  `;
94
137
 
95
138
  const HELPER_NON_DYNAMIC = `
96
- export function commonjsRequire () {
97
- throw new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs');
139
+ export function createCommonjsModule(fn) {
140
+ var module = { exports: {} }
141
+ return fn(module, module.exports), module.exports;
142
+ }
143
+
144
+ export function commonjsRequire (target) {
145
+ throw new Error('Could not dynamically require "' + target + '". Please configure the dynamicRequireTargets option of @rollup/plugin-commonjs appropriately for this require call to behave properly.');
98
146
  }
99
147
  `;
100
148
 
101
149
  const HELPERS_DYNAMIC = `
150
+ export function createCommonjsModule(fn, basedir, module) {
151
+ return module = {
152
+ path: basedir,
153
+ exports: {},
154
+ require: function (path, base) {
155
+ return commonjsRequire(path, (base === undefined || base === null) ? module.path : base);
156
+ }
157
+ }, fn(module, module.exports), module.exports;
158
+ }
159
+
102
160
  export function commonjsRegister (path, loader) {
103
161
  DYNAMIC_REQUIRE_LOADERS[path] = loader;
104
162
  }
@@ -241,67 +299,22 @@ function getHelpersModule(isDynamicRequireModulesEnabled) {
241
299
  return `${HELPERS}${isDynamicRequireModulesEnabled ? HELPERS_DYNAMIC : HELPER_NON_DYNAMIC}`;
242
300
  }
243
301
 
244
- /* eslint-disable no-undefined */
245
-
246
- const operators = {
247
- '==': (x) => equals(x.left, x.right, false),
248
-
249
- '!=': (x) => not(operators['=='](x)),
250
-
251
- '===': (x) => equals(x.left, x.right, true),
252
-
253
- '!==': (x) => not(operators['==='](x)),
254
-
255
- '!': (x) => isFalsy(x.argument),
256
-
257
- '&&': (x) => isTruthy(x.left) && isTruthy(x.right),
258
-
259
- '||': (x) => isTruthy(x.left) || isTruthy(x.right)
260
- };
261
-
262
- function flatten(node) {
263
- const parts = [];
302
+ /* eslint-disable import/prefer-default-export */
264
303
 
265
- while (node.type === 'MemberExpression') {
266
- if (node.computed) return null;
304
+ function deconflict(scope, globals, identifier) {
305
+ let i = 1;
306
+ let deconflicted = pluginutils.makeLegalIdentifier(identifier);
267
307
 
268
- parts.unshift(node.property.name);
269
- // eslint-disable-next-line no-param-reassign
270
- node = node.object;
308
+ while (scope.contains(deconflicted) || globals.has(deconflicted)) {
309
+ deconflicted = pluginutils.makeLegalIdentifier(`${identifier}_${i}`);
310
+ i += 1;
271
311
  }
312
+ // eslint-disable-next-line no-param-reassign
313
+ scope.declarations[deconflicted] = true;
272
314
 
273
- if (node.type !== 'Identifier') return null;
274
-
275
- const { name } = node;
276
- parts.unshift(name);
277
-
278
- return { name, keypath: parts.join('.') };
279
- }
280
-
281
- function isTruthy(node) {
282
- if (node.type === 'Literal') return !!node.value;
283
- if (node.type === 'ParenthesizedExpression') return isTruthy(node.expression);
284
- if (node.operator in operators) return operators[node.operator](node);
285
- return undefined;
286
- }
287
-
288
- function isFalsy(node) {
289
- return not(isTruthy(node));
290
- }
291
-
292
- function not(value) {
293
- return value === undefined ? value : !value;
294
- }
295
-
296
- function equals(a, b, strict) {
297
- if (a.type !== b.type) return undefined;
298
- // eslint-disable-next-line eqeqeq
299
- if (a.type === 'Literal') return strict ? a.value === b.value : a.value == b.value;
300
- return undefined;
315
+ return deconflicted;
301
316
  }
302
317
 
303
- /* eslint-disable import/prefer-default-export */
304
-
305
318
  function getName(id) {
306
319
  const name = pluginutils.makeLegalIdentifier(path.basename(id, path.extname(id)));
307
320
  if (name !== 'index') {
@@ -311,780 +324,101 @@ function getName(id) {
311
324
  return pluginutils.makeLegalIdentifier(segments[segments.length - 1]);
312
325
  }
313
326
 
314
- /* eslint-disable no-param-reassign, no-shadow, no-underscore-dangle, no-continue */
315
-
316
- const reserved = 'process location abstract arguments boolean break byte case catch char class const continue debugger default delete do double else enum eval export extends false final finally float for from function goto if implements import in instanceof int interface let long native new null package private protected public return short static super switch synchronized this throw throws transient true try typeof var void volatile while with yield'.split(
317
- ' '
318
- );
319
- const blacklist = { __esModule: true };
320
- reserved.forEach((word) => (blacklist[word] = true));
327
+ function normalizePathSlashes(path) {
328
+ return path.replace(/\\/g, '/');
329
+ }
321
330
 
322
- const exportsPattern = /^(?:module\.)?exports(?:\.([a-zA-Z_$][a-zA-Z_$0-9]*))?$/;
331
+ const VIRTUAL_PATH_BASE = '/$$rollup_base$$';
332
+ const getVirtualPathForDynamicRequirePath = (path, commonDir) => {
333
+ const normalizedPath = normalizePathSlashes(path);
334
+ return normalizedPath.startsWith(commonDir)
335
+ ? VIRTUAL_PATH_BASE + normalizedPath.slice(commonDir.length)
336
+ : normalizedPath;
337
+ };
323
338
 
324
- const firstpassGlobal = /\b(?:require|module|exports|global)\b/;
325
- const firstpassNoGlobal = /\b(?:require|module|exports)\b/;
326
- const functionType = /^(?:FunctionDeclaration|FunctionExpression|ArrowFunctionExpression)$/;
339
+ function getDynamicPackagesModule(dynamicRequireModuleDirPaths, commonDir) {
340
+ let code = `const commonjsRegister = require('${HELPERS_ID}?commonjsRegister');`;
341
+ for (const dir of dynamicRequireModuleDirPaths) {
342
+ let entryPoint = 'index.js';
327
343
 
328
- function deconflict(scope, globals, identifier) {
329
- let i = 1;
330
- let deconflicted = pluginutils.makeLegalIdentifier(identifier);
344
+ try {
345
+ if (fs.existsSync(path.join(dir, 'package.json'))) {
346
+ entryPoint =
347
+ JSON.parse(fs.readFileSync(path.join(dir, 'package.json'), { encoding: 'utf8' })).main ||
348
+ entryPoint;
349
+ }
350
+ } catch (ignored) {
351
+ // ignored
352
+ }
331
353
 
332
- while (scope.contains(deconflicted) || globals.has(deconflicted) || deconflicted in blacklist) {
333
- deconflicted = `${identifier}_${i}`;
334
- i += 1;
354
+ code += `\ncommonjsRegister(${JSON.stringify(
355
+ getVirtualPathForDynamicRequirePath(dir, commonDir)
356
+ )}, function (module, exports) {
357
+ module.exports = require(${JSON.stringify(normalizePathSlashes(path.join(dir, entryPoint)))});
358
+ });`;
335
359
  }
336
- scope.declarations[deconflicted] = true;
337
-
338
- return deconflicted;
360
+ return code;
339
361
  }
340
362
 
341
- function tryParse(parse, code, id) {
342
- try {
343
- return parse(code, { allowReturnOutsideFunction: true });
344
- } catch (err) {
345
- err.message += ` in ${id}`;
346
- throw err;
363
+ function getDynamicPackagesEntryIntro(
364
+ dynamicRequireModuleDirPaths,
365
+ dynamicRequireModuleSet
366
+ ) {
367
+ let dynamicImports = Array.from(
368
+ dynamicRequireModuleSet,
369
+ (dynamicId) => `require(${JSON.stringify(DYNAMIC_REGISTER_PREFIX + dynamicId)});`
370
+ ).join('\n');
371
+
372
+ if (dynamicRequireModuleDirPaths.length) {
373
+ dynamicImports += `require(${JSON.stringify(DYNAMIC_REGISTER_PREFIX + DYNAMIC_PACKAGES_ID)});`;
347
374
  }
348
- }
349
375
 
350
- function normalizePathSlashes(path) {
351
- return path.replace(/\\/g, '/');
376
+ return dynamicImports;
352
377
  }
353
378
 
354
- function hasCjsKeywords(code, ignoreGlobal) {
355
- const firstpass = ignoreGlobal ? firstpassNoGlobal : firstpassGlobal;
356
- return firstpass.test(code);
379
+ function isModuleRegistrationProxy(id, dynamicRequireModuleSet) {
380
+ const normalizedPath = normalizePathSlashes(id);
381
+ return dynamicRequireModuleSet.has(normalizedPath) && !normalizedPath.endsWith('.json');
357
382
  }
358
383
 
359
- function checkEsModule(parse, code, id) {
360
- const ast = tryParse(parse, code, id);
361
-
362
- let isEsModule = false;
363
- let hasDefaultExport = false;
364
- let hasNamedExports = false;
365
- for (const node of ast.body) {
366
- if (node.type === 'ExportDefaultDeclaration') {
367
- isEsModule = true;
368
- hasDefaultExport = true;
369
- } else if (node.type === 'ExportNamedDeclaration') {
370
- isEsModule = true;
371
- if (node.declaration) {
372
- hasNamedExports = true;
373
- } else {
374
- for (const specifier of node.specifiers) {
375
- if (specifier.exported.name === 'default') {
376
- hasDefaultExport = true;
377
- } else {
378
- hasNamedExports = true;
379
- }
380
- }
381
- }
382
- } else if (node.type === 'ExportAllDeclaration') {
383
- isEsModule = true;
384
- if (node.exported && node.exported.name === 'default') {
385
- hasDefaultExport = true;
386
- } else {
387
- hasNamedExports = true;
388
- }
389
- } else if (node.type === 'ImportDeclaration') {
390
- isEsModule = true;
384
+ function getDynamicRequirePaths(patterns) {
385
+ const dynamicRequireModuleSet = new Set();
386
+ for (const pattern of !patterns || Array.isArray(patterns) ? patterns || [] : [patterns]) {
387
+ const isNegated = pattern.startsWith('!');
388
+ const modifySet = Set.prototype[isNegated ? 'delete' : 'add'].bind(dynamicRequireModuleSet);
389
+ for (const path$1 of glob__default['default'].sync(isNegated ? pattern.substr(1) : pattern)) {
390
+ modifySet(normalizePathSlashes(path.resolve(path$1)));
391
391
  }
392
392
  }
393
-
394
- return { isEsModule, hasDefaultExport, hasNamedExports, ast };
393
+ const dynamicRequireModuleDirPaths = Array.from(dynamicRequireModuleSet.values()).filter(
394
+ (path) => {
395
+ try {
396
+ if (fs.statSync(path).isDirectory()) return true;
397
+ } catch (ignored) {
398
+ // Nothing to do here
399
+ }
400
+ return false;
401
+ }
402
+ );
403
+ return { dynamicRequireModuleSet, dynamicRequireModuleDirPaths };
395
404
  }
396
405
 
397
- function getDefinePropertyCallName(node, targetName) {
398
- if (node.type !== 'CallExpression') return;
399
-
400
- const {
401
- callee: { object, property }
402
- } = node;
403
-
404
- if (!object || object.type !== 'Identifier' || object.name !== 'Object') return;
406
+ const isCjsPromises = new Map();
405
407
 
406
- if (!property || property.type !== 'Identifier' || property.name !== 'defineProperty') return;
408
+ function getIsCjsPromise(id) {
409
+ let isCjsPromise = isCjsPromises.get(id);
410
+ if (isCjsPromise) return isCjsPromise.promise;
407
411
 
408
- if (node.arguments.length !== 3) return;
412
+ const promise = new Promise((resolve) => {
413
+ isCjsPromise = {
414
+ resolve,
415
+ promise: null
416
+ };
417
+ isCjsPromises.set(id, isCjsPromise);
418
+ });
419
+ isCjsPromise.promise = promise;
409
420
 
410
- const [target, val] = node.arguments;
411
- if (target.type !== 'Identifier' || target.name !== targetName) return;
412
- // eslint-disable-next-line consistent-return
413
- return val.value;
414
- }
415
-
416
- function transformCommonjs(
417
- parse,
418
- code,
419
- id,
420
- isEsModule,
421
- ignoreGlobal,
422
- ignoreRequire,
423
- sourceMap,
424
- isDynamicRequireModulesEnabled,
425
- dynamicRequireModuleSet,
426
- disableWrap,
427
- commonDir,
428
- astCache
429
- ) {
430
- const ast = astCache || tryParse(parse, code, id);
431
-
432
- const magicString = new MagicString__default['default'](code);
433
-
434
- const required = {};
435
- // Because objects have no guaranteed ordering, yet we need it,
436
- // we need to keep track of the order in a array
437
- const requiredSources = [];
438
- const dynamicRegisterSources = [];
439
-
440
- let uid = 0;
441
-
442
- let scope = pluginutils.attachScopes(ast, 'scope');
443
- const uses = { module: false, exports: false, global: false, require: false };
444
-
445
- let lexicalDepth = 0;
446
- let programDepth = 0;
447
-
448
- const globals = new Set();
449
-
450
- // TODO technically wrong since globals isn't populated yet, but ¯\_(ツ)_/¯
451
- const HELPERS_NAME = deconflict(scope, globals, 'commonjsHelpers');
452
-
453
- const namedExports = {};
454
-
455
- // TODO handle transpiled modules
456
- let shouldWrap = /__esModule/.test(code);
457
- let usesCommonjsHelpers = false;
458
-
459
- function isRequireStatement(node) {
460
- if (!node) return false;
461
- if (node.type !== 'CallExpression') return false;
462
-
463
- // Weird case of `require()` or `module.require()` without arguments
464
- if (node.arguments.length === 0) return false;
465
-
466
- return isRequireIdentifier(node.callee);
467
- }
468
-
469
- function isRequireIdentifier(node) {
470
- if (!node) return false;
471
-
472
- if (node.type === 'Identifier' && node.name === 'require' /* `require` */) {
473
- // `require` is hidden by a variable in local scope
474
- if (scope.contains('require')) return false;
475
-
476
- return true;
477
- } else if (node.type === 'MemberExpression' /* `[something].[something]` */) {
478
- // `module.[something]`
479
- if (node.object.type !== 'Identifier' || node.object.name !== 'module') return false;
480
-
481
- // `module` is hidden by a variable in local scope
482
- if (scope.contains('module')) return false;
483
-
484
- // `module.require(...)`
485
- if (node.property.type !== 'Identifier' || node.property.name !== 'require') return false;
486
-
487
- return true;
488
- }
489
-
490
- return false;
491
- }
492
-
493
- function hasDynamicArguments(node) {
494
- return (
495
- node.arguments.length > 1 ||
496
- (node.arguments[0].type !== 'Literal' &&
497
- (node.arguments[0].type !== 'TemplateLiteral' || node.arguments[0].expressions.length > 0))
498
- );
499
- }
500
-
501
- function isStaticRequireStatement(node) {
502
- if (!isRequireStatement(node)) return false;
503
- return !hasDynamicArguments(node);
504
- }
505
-
506
- function isNodeRequireStatement(parent) {
507
- const reservedMethod = ['resolve', 'cache', 'main'];
508
- return !!(parent && parent.property && reservedMethod.indexOf(parent.property.name) > -1);
509
- }
510
-
511
- function isIgnoredRequireStatement(requiredNode) {
512
- return ignoreRequire(requiredNode.arguments[0].value);
513
- }
514
-
515
- function getRequireStringArg(node) {
516
- return node.arguments[0].type === 'Literal'
517
- ? node.arguments[0].value
518
- : node.arguments[0].quasis[0].value.cooked;
519
- }
520
-
521
- function getRequired(node, name) {
522
- let sourceId = getRequireStringArg(node);
523
- const isDynamicRegister = sourceId.startsWith(DYNAMIC_REGISTER_PREFIX);
524
- if (isDynamicRegister) {
525
- sourceId = sourceId.substr(DYNAMIC_REGISTER_PREFIX.length);
526
- }
527
-
528
- const existing = required[sourceId];
529
- if (!existing) {
530
- const isDynamic = hasDynamicModuleForPath(sourceId);
531
-
532
- if (!name) {
533
- do {
534
- name = `require$$${uid}`;
535
- uid += 1;
536
- } while (scope.contains(name));
537
- }
538
-
539
- if (isDynamicRegister) {
540
- if (sourceId.endsWith('.json')) {
541
- sourceId = DYNAMIC_JSON_PREFIX + sourceId;
542
- }
543
- dynamicRegisterSources.push(sourceId);
544
- }
545
-
546
- if (!isDynamic || sourceId.endsWith('.json')) {
547
- requiredSources.push(sourceId);
548
- }
549
-
550
- required[sourceId] = { source: sourceId, name, importsDefault: false, isDynamic };
551
- }
552
-
553
- return required[sourceId];
554
- }
555
-
556
- function hasDynamicModuleForPath(source) {
557
- if (!/^(?:\.{0,2}[/\\]|[A-Za-z]:[/\\])/.test(source)) {
558
- try {
559
- const resolvedPath = normalizePathSlashes(
560
- resolve.sync(source, { basedir: path.dirname(id) })
561
- );
562
- if (dynamicRequireModuleSet.has(resolvedPath)) {
563
- return true;
564
- }
565
- } catch (ex) {
566
- // Probably a node.js internal module
567
- return false;
568
- }
569
-
570
- return false;
571
- }
572
-
573
- for (const attemptExt of ['', '.js', '.json']) {
574
- const resolvedPath = normalizePathSlashes(path.resolve(path.dirname(id), source + attemptExt));
575
- if (dynamicRequireModuleSet.has(resolvedPath)) {
576
- return true;
577
- }
578
- }
579
-
580
- return false;
581
- }
582
-
583
- function shouldUseSimulatedRequire(required) {
584
- return (
585
- hasDynamicModuleForPath(required.source) &&
586
- // We only do `commonjsRequire` for json if it's the `commonjsRegister` call.
587
- (required.source.startsWith(DYNAMIC_REGISTER_PREFIX) || !required.source.endsWith('.json'))
588
- );
589
- }
590
-
591
- // do a first pass, see which names are assigned to. This is necessary to prevent
592
- // illegally replacing `var foo = require('foo')` with `import foo from 'foo'`,
593
- // where `foo` is later reassigned. (This happens in the wild. CommonJS, sigh)
594
- const assignedTo = new Set();
595
- estreeWalker.walk(ast, {
596
- enter(node) {
597
- if (node.type !== 'AssignmentExpression') return;
598
- if (node.left.type === 'MemberExpression') return;
599
-
600
- pluginutils.extractAssignedNames(node.left).forEach((name) => {
601
- assignedTo.add(name);
602
- });
603
- }
604
- });
605
-
606
- estreeWalker.walk(ast, {
607
- enter(node, parent) {
608
- if (sourceMap) {
609
- magicString.addSourcemapLocation(node.start);
610
- magicString.addSourcemapLocation(node.end);
611
- }
612
-
613
- // skip dead branches
614
- if (parent && (parent.type === 'IfStatement' || parent.type === 'ConditionalExpression')) {
615
- if (node === parent.consequent && isFalsy(parent.test)) {
616
- this.skip();
617
- return;
618
- }
619
- if (node === parent.alternate && isTruthy(parent.test)) {
620
- this.skip();
621
- return;
622
- }
623
- }
624
-
625
- if (node._skip) {
626
- this.skip();
627
- return;
628
- }
629
-
630
- programDepth += 1;
631
-
632
- if (node.scope) ({ scope } = node);
633
- if (functionType.test(node.type)) lexicalDepth += 1;
634
-
635
- // if toplevel return, we need to wrap it
636
- if (node.type === 'ReturnStatement' && lexicalDepth === 0) {
637
- shouldWrap = true;
638
- }
639
-
640
- // rewrite `this` as `commonjsHelpers.commonjsGlobal`
641
- if (node.type === 'ThisExpression' && lexicalDepth === 0) {
642
- uses.global = true;
643
- if (!ignoreGlobal) {
644
- magicString.overwrite(node.start, node.end, `${HELPERS_NAME}.commonjsGlobal`, {
645
- storeName: true
646
- });
647
- usesCommonjsHelpers = true;
648
- }
649
- return;
650
- }
651
-
652
- // rewrite `typeof module`, `typeof module.exports` and `typeof exports` (https://github.com/rollup/rollup-plugin-commonjs/issues/151)
653
- if (node.type === 'UnaryExpression' && node.operator === 'typeof') {
654
- const flattened = flatten(node.argument);
655
- if (!flattened) return;
656
-
657
- if (scope.contains(flattened.name)) return;
658
-
659
- if (
660
- flattened.keypath === 'module.exports' ||
661
- flattened.keypath === 'module' ||
662
- flattened.keypath === 'exports'
663
- ) {
664
- magicString.overwrite(node.start, node.end, `'object'`, { storeName: false });
665
- }
666
- }
667
-
668
- // rewrite `require` (if not already handled) `global` and `define`, and handle free references to
669
- // `module` and `exports` as these mean we need to wrap the module in commonjsHelpers.createCommonjsModule
670
- if (node.type === 'Identifier') {
671
- if (isReference__default['default'](node, parent) && !scope.contains(node.name)) {
672
- if (node.name in uses) {
673
- if (isRequireIdentifier(node)) {
674
- if (isNodeRequireStatement(parent)) {
675
- return;
676
- }
677
-
678
- if (!isDynamicRequireModulesEnabled && isStaticRequireStatement(parent)) {
679
- return;
680
- }
681
-
682
- if (isDynamicRequireModulesEnabled && isRequireStatement(parent)) {
683
- magicString.appendLeft(
684
- parent.end - 1,
685
- `,${JSON.stringify(
686
- path.dirname(id) === '.'
687
- ? null /* default behavior */
688
- : getVirtualPathForDynamicRequirePath(
689
- normalizePathSlashes(path.dirname(id)),
690
- commonDir
691
- )
692
- )}`
693
- );
694
- }
695
-
696
- magicString.overwrite(node.start, node.end, `${HELPERS_NAME}.commonjsRequire`, {
697
- storeName: true
698
- });
699
- usesCommonjsHelpers = true;
700
- }
701
-
702
- uses[node.name] = true;
703
- if (node.name === 'global' && !ignoreGlobal) {
704
- magicString.overwrite(node.start, node.end, `${HELPERS_NAME}.commonjsGlobal`, {
705
- storeName: true
706
- });
707
- usesCommonjsHelpers = true;
708
- }
709
-
710
- // if module or exports are used outside the context of an assignment
711
- // expression, we need to wrap the module
712
- if (node.name === 'module' || node.name === 'exports') {
713
- shouldWrap = true;
714
- }
715
- }
716
-
717
- if (node.name === 'define') {
718
- magicString.overwrite(node.start, node.end, 'undefined', { storeName: true });
719
- }
720
-
721
- globals.add(node.name);
722
- }
723
-
724
- return;
725
- }
726
-
727
- // Is this an assignment to exports or module.exports?
728
- if (node.type === 'AssignmentExpression') {
729
- if (node.left.type !== 'MemberExpression') return;
730
-
731
- const flattened = flatten(node.left);
732
- if (!flattened) return;
733
-
734
- if (scope.contains(flattened.name)) return;
735
-
736
- const match = exportsPattern.exec(flattened.keypath);
737
- if (!match || flattened.keypath === 'exports') return;
738
-
739
- uses[flattened.name] = true;
740
-
741
- // we're dealing with `module.exports = ...` or `[module.]exports.foo = ...` –
742
- // if this isn't top-level, we'll need to wrap the module
743
- if (programDepth > 3) shouldWrap = true;
744
-
745
- node.left._skip = true;
746
-
747
- if (flattened.keypath === 'module.exports' && node.right.type === 'ObjectExpression') {
748
- node.right.properties.forEach((prop) => {
749
- if (prop.computed || !('key' in prop) || prop.key.type !== 'Identifier') return;
750
- const { name } = prop.key;
751
- if (name === pluginutils.makeLegalIdentifier(name)) namedExports[name] = true;
752
- });
753
- return;
754
- }
755
-
756
- if (match[1]) namedExports[match[1]] = true;
757
- return;
758
- }
759
-
760
- const name = getDefinePropertyCallName(node, 'exports');
761
- if (name && name === pluginutils.makeLegalIdentifier(name)) namedExports[name] = true;
762
-
763
- // if this is `var x = require('x')`, we can do `import x from 'x'`
764
- if (
765
- node.type === 'VariableDeclarator' &&
766
- node.id.type === 'Identifier' &&
767
- isStaticRequireStatement(node.init) &&
768
- !isIgnoredRequireStatement(node.init)
769
- ) {
770
- // for now, only do this for top-level requires. maybe fix this in future
771
- if (scope.parent) return;
772
-
773
- // edge case — CJS allows you to assign to imports. ES doesn't
774
- if (assignedTo.has(node.id.name)) return;
775
-
776
- const required = getRequired(node.init, node.id.name);
777
- required.importsDefault = true;
778
-
779
- if (required.name === node.id.name && !required.isDynamic) {
780
- node._shouldRemove = true;
781
- }
782
- }
783
-
784
- if (!isStaticRequireStatement(node) || isIgnoredRequireStatement(node)) {
785
- return;
786
- }
787
-
788
- const required = getRequired(node);
789
-
790
- if (parent.type === 'ExpressionStatement') {
791
- // is a bare import, e.g. `require('foo');`
792
- magicString.remove(parent.start, parent.end);
793
- } else {
794
- required.importsDefault = true;
795
-
796
- if (shouldUseSimulatedRequire(required)) {
797
- magicString.overwrite(
798
- node.start,
799
- node.end,
800
- `${HELPERS_NAME}.commonjsRequire(${JSON.stringify(
801
- getVirtualPathForDynamicRequirePath(normalizePathSlashes(required.source), commonDir)
802
- )}, ${JSON.stringify(
803
- path.dirname(id) === '.'
804
- ? null /* default behavior */
805
- : getVirtualPathForDynamicRequirePath(normalizePathSlashes(path.dirname(id)), commonDir)
806
- )})`
807
- );
808
- usesCommonjsHelpers = true;
809
- } else {
810
- magicString.overwrite(node.start, node.end, required.name);
811
- }
812
- }
813
-
814
- node.callee._skip = true;
815
- },
816
-
817
- leave(node) {
818
- programDepth -= 1;
819
- if (node.scope) scope = scope.parent;
820
- if (functionType.test(node.type)) lexicalDepth -= 1;
821
-
822
- if (node.type === 'VariableDeclaration') {
823
- let keepDeclaration = false;
824
- let c = node.declarations[0].start;
825
-
826
- for (let i = 0; i < node.declarations.length; i += 1) {
827
- const declarator = node.declarations[i];
828
-
829
- if (declarator._shouldRemove) {
830
- magicString.remove(c, declarator.end);
831
- } else {
832
- if (!keepDeclaration) {
833
- magicString.remove(c, declarator.start);
834
- keepDeclaration = true;
835
- }
836
-
837
- c = declarator.end;
838
- }
839
- }
840
-
841
- if (!keepDeclaration) {
842
- magicString.remove(node.start, node.end);
843
- }
844
- }
845
- }
846
- });
847
-
848
- // If `isEsModule` is on, it means it has ES6 import/export statements,
849
- // which just can't be wrapped in a function.
850
- shouldWrap = shouldWrap && !disableWrap && !isEsModule;
851
-
852
- usesCommonjsHelpers = usesCommonjsHelpers || shouldWrap;
853
-
854
- if (
855
- !requiredSources.length &&
856
- !dynamicRegisterSources.length &&
857
- !uses.module &&
858
- !uses.exports &&
859
- !uses.require &&
860
- !usesCommonjsHelpers &&
861
- (ignoreGlobal || !uses.global)
862
- ) {
863
- return { meta: { commonjs: { isCommonJS: false } } };
864
- }
865
-
866
- const importBlock = `${(usesCommonjsHelpers
867
- ? [`import * as ${HELPERS_NAME} from '${HELPERS_ID}';`]
868
- : []
869
- )
870
- .concat(
871
- // dynamic registers first, as the may be required in the other modules
872
- dynamicRegisterSources.map((source) => `import '${source}';`),
873
-
874
- // now the actual modules so that they are analyzed before creating the proxies;
875
- // no need to do this for virtual modules as we never proxy them
876
- requiredSources
877
- .filter((source) => !source.startsWith('\0'))
878
- .map((source) => `import '${wrapId(source, REQUIRE_SUFFIX)}';`),
879
-
880
- // now the proxy modules
881
- requiredSources.map((source) => {
882
- const { name, importsDefault } = required[source];
883
- return `import ${importsDefault ? `${name} from ` : ``}'${
884
- source.startsWith('\0') ? source : wrapId(source, PROXY_SUFFIX)
885
- }';`;
886
- })
887
- )
888
- .join('\n')}\n\n`;
889
-
890
- const namedExportDeclarations = [];
891
- let wrapperStart = '';
892
- let wrapperEnd = '';
893
-
894
- const moduleName = deconflict(scope, globals, getName(id));
895
- if (!isEsModule) {
896
- const exportModuleExports = {
897
- str: `export { ${moduleName} as __moduleExports };`,
898
- name: '__moduleExports'
899
- };
900
-
901
- namedExportDeclarations.push(exportModuleExports);
902
- }
903
-
904
- const defaultExportPropertyAssignments = [];
905
- let hasDefaultExport = false;
906
-
907
- if (shouldWrap) {
908
- const args = `module${uses.exports ? ', exports' : ''}`;
909
-
910
- wrapperStart = `var ${moduleName} = ${HELPERS_NAME}.createCommonjsModule(function (${args}) {\n`;
911
-
912
- wrapperEnd = `\n}`;
913
- if (isDynamicRequireModulesEnabled) {
914
- wrapperEnd += `, ${JSON.stringify(
915
- getVirtualPathForDynamicRequirePath(normalizePathSlashes(path.dirname(id)), commonDir)
916
- )}`;
917
- }
918
-
919
- wrapperEnd += `);`;
920
- } else {
921
- const names = [];
922
-
923
- for (const node of ast.body) {
924
- if (node.type === 'ExpressionStatement' && node.expression.type === 'AssignmentExpression') {
925
- const { left } = node.expression;
926
- const flattened = flatten(left);
927
-
928
- if (!flattened) {
929
- continue;
930
- }
931
-
932
- const match = exportsPattern.exec(flattened.keypath);
933
- if (!match) {
934
- continue;
935
- }
936
-
937
- if (flattened.keypath === 'module.exports') {
938
- hasDefaultExport = true;
939
- magicString.overwrite(left.start, left.end, `var ${moduleName}`);
940
- } else {
941
- const [, name] = match;
942
- const deconflicted = deconflict(scope, globals, name);
943
-
944
- names.push({ name, deconflicted });
945
-
946
- magicString.overwrite(node.start, left.end, `var ${deconflicted}`);
947
-
948
- const declaration =
949
- name === deconflicted
950
- ? `export { ${name} };`
951
- : `export { ${deconflicted} as ${name} };`;
952
-
953
- if (name !== 'default') {
954
- namedExportDeclarations.push({
955
- str: declaration,
956
- name
957
- });
958
- }
959
-
960
- defaultExportPropertyAssignments.push(`${moduleName}.${name} = ${deconflicted};`);
961
- }
962
- }
963
- }
964
-
965
- if (!(isEsModule || hasDefaultExport)) {
966
- wrapperEnd = `\n\nvar ${moduleName} = {\n${names
967
- .map(({ name, deconflicted }) => `\t${name}: ${deconflicted}`)
968
- .join(',\n')}\n};`;
969
- }
970
- }
971
-
972
- magicString
973
- .trim()
974
- .prepend(importBlock + wrapperStart)
975
- .trim()
976
- .append(wrapperEnd);
977
-
978
- const defaultExport =
979
- code.indexOf('__esModule') >= 0
980
- ? `export default /*@__PURE__*/${HELPERS_NAME}.getDefaultExportFromCjs(${moduleName});`
981
- : `export default ${moduleName};`;
982
-
983
- const named = namedExportDeclarations
984
- .filter((x) => x.name !== 'default' || !hasDefaultExport)
985
- .map((x) => x.str);
986
-
987
- magicString.append(
988
- `\n\n${(isEsModule ? [] : [defaultExport])
989
- .concat(named)
990
- .concat(hasDefaultExport ? defaultExportPropertyAssignments : [])
991
- .join('\n')}`
992
- );
993
-
994
- code = magicString.toString();
995
- const map = sourceMap ? magicString.generateMap() : null;
996
-
997
- return {
998
- code,
999
- map,
1000
- syntheticNamedExports: isEsModule ? false : '__moduleExports',
1001
- meta: { commonjs: { isCommonJS: !isEsModule } }
1002
- };
1003
- }
1004
-
1005
- function getDynamicPackagesModule(dynamicRequireModuleDirPaths, commonDir) {
1006
- let code = `const commonjsRegister = require('${HELPERS_ID}?commonjsRegister');`;
1007
- for (const dir of dynamicRequireModuleDirPaths) {
1008
- let entryPoint = 'index.js';
1009
-
1010
- try {
1011
- if (fs.existsSync(path.join(dir, 'package.json'))) {
1012
- entryPoint =
1013
- JSON.parse(fs.readFileSync(path.join(dir, 'package.json'), { encoding: 'utf8' })).main ||
1014
- entryPoint;
1015
- }
1016
- } catch (ignored) {
1017
- // ignored
1018
- }
1019
-
1020
- code += `\ncommonjsRegister(${JSON.stringify(
1021
- getVirtualPathForDynamicRequirePath(dir, commonDir)
1022
- )}, function (module, exports) {
1023
- module.exports = require(${JSON.stringify(normalizePathSlashes(path.join(dir, entryPoint)))});
1024
- });`;
1025
- }
1026
- return code;
1027
- }
1028
-
1029
- function getDynamicPackagesEntryIntro(
1030
- dynamicRequireModuleDirPaths,
1031
- dynamicRequireModuleSet
1032
- ) {
1033
- let dynamicImports = Array.from(
1034
- dynamicRequireModuleSet,
1035
- (dynamicId) => `require(${JSON.stringify(DYNAMIC_REGISTER_PREFIX + dynamicId)});`
1036
- ).join('\n');
1037
-
1038
- if (dynamicRequireModuleDirPaths.length) {
1039
- dynamicImports += `require(${JSON.stringify(DYNAMIC_REGISTER_PREFIX + DYNAMIC_PACKAGES_ID)});`;
1040
- }
1041
-
1042
- return dynamicImports;
1043
- }
1044
-
1045
- function isModuleRegistrationProxy(id, dynamicRequireModuleSet) {
1046
- const normalizedPath = normalizePathSlashes(id);
1047
- return dynamicRequireModuleSet.has(normalizedPath) && !normalizedPath.endsWith('.json');
1048
- }
1049
-
1050
- function getDynamicRequirePaths(patterns) {
1051
- const dynamicRequireModuleSet = new Set();
1052
- for (const pattern of !patterns || Array.isArray(patterns) ? patterns || [] : [patterns]) {
1053
- const isNegated = pattern.startsWith('!');
1054
- const modifySet = Set.prototype[isNegated ? 'delete' : 'add'].bind(dynamicRequireModuleSet);
1055
- for (const path$1 of glob__default['default'].sync(isNegated ? pattern.substr(1) : pattern)) {
1056
- modifySet(normalizePathSlashes(path.resolve(path$1)));
1057
- }
1058
- }
1059
- const dynamicRequireModuleDirPaths = Array.from(dynamicRequireModuleSet.values()).filter(
1060
- (path) => {
1061
- try {
1062
- if (fs.statSync(path).isDirectory()) return true;
1063
- } catch (ignored) {
1064
- // Nothing to do here
1065
- }
1066
- return false;
1067
- }
1068
- );
1069
- return { dynamicRequireModuleSet, dynamicRequireModuleDirPaths };
1070
- }
1071
-
1072
- const isCjsPromises = new Map();
1073
-
1074
- function getIsCjsPromise(id) {
1075
- let isCjsPromise = isCjsPromises.get(id);
1076
- if (isCjsPromise) return isCjsPromise.promise;
1077
-
1078
- const promise = new Promise((resolve) => {
1079
- isCjsPromise = {
1080
- resolve,
1081
- promise: null
1082
- };
1083
- isCjsPromises.set(id, isCjsPromise);
1084
- });
1085
- isCjsPromise.promise = promise;
1086
-
1087
- return promise;
421
+ return promise;
1088
422
  }
1089
423
 
1090
424
  function setIsCjsPromise(id, resolution) {
@@ -1164,78 +498,916 @@ async function getStaticRequireProxy(
1164
498
  return `export {default} from ${JSON.stringify(id)};`;
1165
499
  }
1166
500
 
1167
- /* eslint-disable no-param-reassign, no-undefined */
501
+ /* eslint-disable no-param-reassign, no-undefined */
502
+
503
+ function getCandidatesForExtension(resolved, extension) {
504
+ return [resolved + extension, `${resolved}${path.sep}index${extension}`];
505
+ }
506
+
507
+ function getCandidates(resolved, extensions) {
508
+ return extensions.reduce(
509
+ (paths, extension) => paths.concat(getCandidatesForExtension(resolved, extension)),
510
+ [resolved]
511
+ );
512
+ }
513
+
514
+ function getResolveId(extensions) {
515
+ function resolveExtensions(importee, importer) {
516
+ // not our problem
517
+ if (importee[0] !== '.' || !importer) return undefined;
518
+
519
+ const resolved = path.resolve(path.dirname(importer), importee);
520
+ const candidates = getCandidates(resolved, extensions);
521
+
522
+ for (let i = 0; i < candidates.length; i += 1) {
523
+ try {
524
+ const stats = fs.statSync(candidates[i]);
525
+ if (stats.isFile()) return { id: candidates[i] };
526
+ } catch (err) {
527
+ /* noop */
528
+ }
529
+ }
530
+
531
+ return undefined;
532
+ }
533
+
534
+ return function resolveId(importee, importer) {
535
+ // Proxies are only importing resolved ids, no need to resolve again
536
+ if (importer && isWrappedId(importer, PROXY_SUFFIX)) {
537
+ return importee;
538
+ }
539
+
540
+ const isProxyModule = isWrappedId(importee, PROXY_SUFFIX);
541
+ const isRequiredModule = isWrappedId(importee, REQUIRE_SUFFIX);
542
+ if (isProxyModule) {
543
+ importee = unwrapId(importee, PROXY_SUFFIX);
544
+ } else if (isRequiredModule) {
545
+ importee = unwrapId(importee, REQUIRE_SUFFIX);
546
+ }
547
+ if (importee.startsWith('\0')) {
548
+ if (
549
+ importee.startsWith(HELPERS_ID) ||
550
+ importee === DYNAMIC_PACKAGES_ID ||
551
+ importee.startsWith(DYNAMIC_JSON_PREFIX)
552
+ ) {
553
+ return importee;
554
+ }
555
+ return null;
556
+ }
557
+
558
+ return this.resolve(importee, importer, {
559
+ skipSelf: true,
560
+ custom: { 'node-resolve': { isRequire: isProxyModule || isRequiredModule } }
561
+ }).then((resolved) => {
562
+ if (!resolved) {
563
+ resolved = resolveExtensions(importee, importer);
564
+ }
565
+ if (resolved && isProxyModule) {
566
+ resolved.id = wrapId(resolved.id, resolved.external ? EXTERNAL_SUFFIX : PROXY_SUFFIX);
567
+ resolved.external = false;
568
+ } else if (!resolved && (isProxyModule || isRequiredModule)) {
569
+ return { id: wrapId(importee, EXTERNAL_SUFFIX), external: false };
570
+ }
571
+ return resolved;
572
+ });
573
+ };
574
+ }
575
+
576
+ function validateRollupVersion(rollupVersion, peerDependencyVersion) {
577
+ const [major, minor] = rollupVersion.split('.').map(Number);
578
+ const versionRegexp = /\^(\d+\.\d+)\.\d+/g;
579
+ let minMajor = Infinity;
580
+ let minMinor = Infinity;
581
+ let foundVersion;
582
+ // eslint-disable-next-line no-cond-assign
583
+ while ((foundVersion = versionRegexp.exec(peerDependencyVersion))) {
584
+ const [foundMajor, foundMinor] = foundVersion[1].split('.').map(Number);
585
+ if (foundMajor < minMajor) {
586
+ minMajor = foundMajor;
587
+ minMinor = foundMinor;
588
+ }
589
+ }
590
+ if (major < minMajor || (major === minMajor && minor < minMinor)) {
591
+ throw new Error(
592
+ `Insufficient Rollup version: "@rollup/plugin-commonjs" requires at least rollup@${minMajor}.${minMinor} but found rollup@${rollupVersion}.`
593
+ );
594
+ }
595
+ }
596
+
597
+ const operators = {
598
+ '==': (x) => equals(x.left, x.right, false),
599
+
600
+ '!=': (x) => not(operators['=='](x)),
601
+
602
+ '===': (x) => equals(x.left, x.right, true),
603
+
604
+ '!==': (x) => not(operators['==='](x)),
605
+
606
+ '!': (x) => isFalsy(x.argument),
607
+
608
+ '&&': (x) => isTruthy(x.left) && isTruthy(x.right),
609
+
610
+ '||': (x) => isTruthy(x.left) || isTruthy(x.right)
611
+ };
612
+
613
+ function not(value) {
614
+ return value === null ? value : !value;
615
+ }
616
+
617
+ function equals(a, b, strict) {
618
+ if (a.type !== b.type) return null;
619
+ // eslint-disable-next-line eqeqeq
620
+ if (a.type === 'Literal') return strict ? a.value === b.value : a.value == b.value;
621
+ return null;
622
+ }
623
+
624
+ function isTruthy(node) {
625
+ if (!node) return false;
626
+ if (node.type === 'Literal') return !!node.value;
627
+ if (node.type === 'ParenthesizedExpression') return isTruthy(node.expression);
628
+ if (node.operator in operators) return operators[node.operator](node);
629
+ return null;
630
+ }
631
+
632
+ function isFalsy(node) {
633
+ return not(isTruthy(node));
634
+ }
635
+
636
+ function getKeypath(node) {
637
+ const parts = [];
638
+
639
+ while (node.type === 'MemberExpression') {
640
+ if (node.computed) return null;
641
+
642
+ parts.unshift(node.property.name);
643
+ // eslint-disable-next-line no-param-reassign
644
+ node = node.object;
645
+ }
646
+
647
+ if (node.type !== 'Identifier') return null;
648
+
649
+ const { name } = node;
650
+ parts.unshift(name);
651
+
652
+ return { name, keypath: parts.join('.') };
653
+ }
654
+
655
+ const KEY_COMPILED_ESM = '__esModule';
656
+
657
+ function isDefineCompiledEsm(node) {
658
+ const definedProperty =
659
+ getDefinePropertyCallName(node, 'exports') || getDefinePropertyCallName(node, 'module.exports');
660
+ if (definedProperty && definedProperty.key === KEY_COMPILED_ESM) {
661
+ return isTruthy(definedProperty.value);
662
+ }
663
+ return false;
664
+ }
665
+
666
+ function getDefinePropertyCallName(node, targetName) {
667
+ const targetNames = targetName.split('.');
668
+
669
+ const {
670
+ callee: { object, property }
671
+ } = node;
672
+ if (!object || object.type !== 'Identifier' || object.name !== 'Object') return;
673
+ if (!property || property.type !== 'Identifier' || property.name !== 'defineProperty') return;
674
+ if (node.arguments.length !== 3) return;
675
+
676
+ const [target, key, value] = node.arguments;
677
+ if (targetNames.length === 1) {
678
+ if (target.type !== 'Identifier' || target.name !== targetNames[0]) {
679
+ return;
680
+ }
681
+ }
682
+
683
+ if (targetNames.length === 2) {
684
+ if (
685
+ target.type !== 'MemberExpression' ||
686
+ target.object.name !== targetNames[0] ||
687
+ target.property.name !== targetNames[1]
688
+ ) {
689
+ return;
690
+ }
691
+ }
692
+
693
+ if (value.type !== 'ObjectExpression' || !value.properties) return;
694
+
695
+ const valueProperty = value.properties.find((p) => p.key && p.key.name === 'value');
696
+ if (!valueProperty || !valueProperty.value) return;
697
+
698
+ // eslint-disable-next-line consistent-return
699
+ return { key: key.value, value: valueProperty.value };
700
+ }
701
+
702
+ function isLocallyShadowed(name, scope) {
703
+ while (scope.parent) {
704
+ if (scope.declarations[name]) {
705
+ return true;
706
+ }
707
+ // eslint-disable-next-line no-param-reassign
708
+ scope = scope.parent;
709
+ }
710
+ return false;
711
+ }
712
+
713
+ function wrapCode(magicString, uses, moduleName, HELPERS_NAME, virtualDynamicRequirePath) {
714
+ const args = `module${uses.exports ? ', exports' : ''}`;
715
+
716
+ magicString
717
+ .trim()
718
+ .prepend(`var ${moduleName} = ${HELPERS_NAME}.createCommonjsModule(function (${args}) {\n`)
719
+ .append(
720
+ `\n}${virtualDynamicRequirePath ? `, ${JSON.stringify(virtualDynamicRequirePath)}` : ''});`
721
+ );
722
+ }
723
+
724
+ function rewriteExportsAndGetExportsBlock(
725
+ magicString,
726
+ moduleName,
727
+ wrapped,
728
+ topLevelModuleExportsAssignments,
729
+ topLevelExportsAssignmentsByName,
730
+ defineCompiledEsmExpressions,
731
+ deconflict,
732
+ isRestorableCompiledEsm,
733
+ code,
734
+ uses,
735
+ HELPERS_NAME
736
+ ) {
737
+ const namedExportDeclarations = [`export { ${moduleName} as __moduleExports };`];
738
+ const moduleExportsPropertyAssignments = [];
739
+ let deconflictedDefaultExportName;
740
+
741
+ if (!wrapped) {
742
+ let hasModuleExportsAssignment = false;
743
+ const namedExportProperties = [];
744
+
745
+ // Collect and rewrite module.exports assignments
746
+ for (const { left } of topLevelModuleExportsAssignments) {
747
+ hasModuleExportsAssignment = true;
748
+ magicString.overwrite(left.start, left.end, `var ${moduleName}`);
749
+ }
750
+
751
+ // Collect and rewrite named exports
752
+ for (const [exportName, node] of topLevelExportsAssignmentsByName) {
753
+ const deconflicted = deconflict(exportName);
754
+ magicString.overwrite(node.start, node.left.end, `var ${deconflicted}`);
755
+
756
+ if (exportName === 'default') {
757
+ deconflictedDefaultExportName = deconflicted;
758
+ } else {
759
+ namedExportDeclarations.push(
760
+ exportName === deconflicted
761
+ ? `export { ${exportName} };`
762
+ : `export { ${deconflicted} as ${exportName} };`
763
+ );
764
+ }
765
+
766
+ if (hasModuleExportsAssignment) {
767
+ moduleExportsPropertyAssignments.push(`${moduleName}.${exportName} = ${deconflicted};`);
768
+ } else {
769
+ namedExportProperties.push(`\t${exportName}: ${deconflicted}`);
770
+ }
771
+ }
772
+
773
+ // Regenerate CommonJS namespace
774
+ if (!hasModuleExportsAssignment) {
775
+ const moduleExports = `{\n${namedExportProperties.join(',\n')}\n}`;
776
+ magicString
777
+ .trim()
778
+ .append(
779
+ `\n\nvar ${moduleName} = ${
780
+ isRestorableCompiledEsm
781
+ ? `/*#__PURE__*/Object.defineProperty(${moduleExports}, '__esModule', {value: true})`
782
+ : moduleExports
783
+ };`
784
+ );
785
+ }
786
+ }
787
+
788
+ // Generate default export
789
+ const defaultExport = [];
790
+ if (isRestorableCompiledEsm) {
791
+ defaultExport.push(`export default ${deconflictedDefaultExportName || moduleName};`);
792
+ } else if (
793
+ (wrapped || deconflictedDefaultExportName) &&
794
+ (defineCompiledEsmExpressions.length > 0 || code.indexOf('__esModule') >= 0)
795
+ ) {
796
+ // eslint-disable-next-line no-param-reassign
797
+ uses.commonjsHelpers = true;
798
+ defaultExport.push(
799
+ `export default /*@__PURE__*/${HELPERS_NAME}.getDefaultExportFromCjs(${moduleName});`
800
+ );
801
+ } else {
802
+ defaultExport.push(`export default ${moduleName};`);
803
+ }
804
+
805
+ return `\n\n${defaultExport
806
+ .concat(namedExportDeclarations)
807
+ .concat(moduleExportsPropertyAssignments)
808
+ .join('\n')}`;
809
+ }
810
+
811
+ function isRequireStatement(node, scope) {
812
+ if (!node) return false;
813
+ if (node.type !== 'CallExpression') return false;
1168
814
 
1169
- function getCandidatesForExtension(resolved, extension) {
1170
- return [resolved + extension, `${resolved}${path.sep}index${extension}`];
815
+ // Weird case of `require()` or `module.require()` without arguments
816
+ if (node.arguments.length === 0) return false;
817
+
818
+ return isRequire(node.callee, scope);
1171
819
  }
1172
820
 
1173
- function getCandidates(resolved, extensions) {
1174
- return extensions.reduce(
1175
- (paths, extension) => paths.concat(getCandidatesForExtension(resolved, extension)),
1176
- [resolved]
821
+ function isRequire(node, scope) {
822
+ return (
823
+ (node.type === 'Identifier' && node.name === 'require' && !scope.contains('require')) ||
824
+ (node.type === 'MemberExpression' && isModuleRequire(node, scope))
1177
825
  );
1178
826
  }
1179
827
 
1180
- function getResolveId(extensions) {
1181
- function resolveExtensions(importee, importer) {
1182
- // not our problem
1183
- if (importee[0] !== '.' || !importer) return undefined;
828
+ function isModuleRequire({ object, property }, scope) {
829
+ return (
830
+ object.type === 'Identifier' &&
831
+ object.name === 'module' &&
832
+ property.type === 'Identifier' &&
833
+ property.name === 'require' &&
834
+ !scope.contains('module')
835
+ );
836
+ }
1184
837
 
1185
- const resolved = path.resolve(path.dirname(importer), importee);
1186
- const candidates = getCandidates(resolved, extensions);
838
+ function isStaticRequireStatement(node, scope) {
839
+ if (!isRequireStatement(node, scope)) return false;
840
+ return !hasDynamicArguments(node);
841
+ }
1187
842
 
1188
- for (let i = 0; i < candidates.length; i += 1) {
1189
- try {
1190
- const stats = fs.statSync(candidates[i]);
1191
- if (stats.isFile()) return { id: candidates[i] };
1192
- } catch (err) {
1193
- /* noop */
843
+ function hasDynamicArguments(node) {
844
+ return (
845
+ node.arguments.length > 1 ||
846
+ (node.arguments[0].type !== 'Literal' &&
847
+ (node.arguments[0].type !== 'TemplateLiteral' || node.arguments[0].expressions.length > 0))
848
+ );
849
+ }
850
+
851
+ const reservedMethod = { resolve: true, cache: true, main: true };
852
+
853
+ function isNodeRequirePropertyAccess(parent) {
854
+ return parent && parent.property && reservedMethod[parent.property.name];
855
+ }
856
+
857
+ function isIgnoredRequireStatement(requiredNode, ignoreRequire) {
858
+ return ignoreRequire(requiredNode.arguments[0].value);
859
+ }
860
+
861
+ function getRequireStringArg(node) {
862
+ return node.arguments[0].type === 'Literal'
863
+ ? node.arguments[0].value
864
+ : node.arguments[0].quasis[0].value.cooked;
865
+ }
866
+
867
+ function hasDynamicModuleForPath(source, id, dynamicRequireModuleSet) {
868
+ if (!/^(?:\.{0,2}[/\\]|[A-Za-z]:[/\\])/.test(source)) {
869
+ try {
870
+ const resolvedPath = normalizePathSlashes(resolve.sync(source, { basedir: path.dirname(id) }));
871
+ if (dynamicRequireModuleSet.has(resolvedPath)) {
872
+ return true;
1194
873
  }
874
+ } catch (ex) {
875
+ // Probably a node.js internal module
876
+ return false;
1195
877
  }
1196
878
 
1197
- return undefined;
879
+ return false;
1198
880
  }
1199
881
 
1200
- return function resolveId(importee, importer) {
1201
- // Proxies are only importing resolved ids, no need to resolve again
1202
- if (importer && isWrappedId(importer, PROXY_SUFFIX)) {
1203
- return importee;
882
+ for (const attemptExt of ['', '.js', '.json']) {
883
+ const resolvedPath = normalizePathSlashes(path.resolve(path.dirname(id), source + attemptExt));
884
+ if (dynamicRequireModuleSet.has(resolvedPath)) {
885
+ return true;
1204
886
  }
887
+ }
1205
888
 
1206
- const isProxyModule = isWrappedId(importee, PROXY_SUFFIX);
1207
- const isRequiredModule = isWrappedId(importee, REQUIRE_SUFFIX);
1208
- if (isProxyModule) {
1209
- importee = unwrapId(importee, PROXY_SUFFIX);
1210
- } else if (isRequiredModule) {
1211
- importee = unwrapId(importee, REQUIRE_SUFFIX);
889
+ return false;
890
+ }
891
+
892
+ function getRequireHandlers() {
893
+ const requiredSources = [];
894
+ const requiredBySource = Object.create(null);
895
+ const requiredByNode = new Map();
896
+ const requireExpressionsWithUsedReturnValue = [];
897
+
898
+ function addRequireStatement(sourceId, node, scope, usesReturnValue) {
899
+ const required = getRequired(sourceId);
900
+ requiredByNode.set(node, { scope, required });
901
+ if (usesReturnValue) {
902
+ required.nodesUsingRequired.push(node);
903
+ requireExpressionsWithUsedReturnValue.push(node);
1212
904
  }
1213
- if (importee.startsWith('\0')) {
905
+ }
906
+
907
+ function getRequired(sourceId) {
908
+ if (!requiredBySource[sourceId]) {
909
+ requiredSources.push(sourceId);
910
+
911
+ requiredBySource[sourceId] = {
912
+ source: sourceId,
913
+ name: null,
914
+ nodesUsingRequired: []
915
+ };
916
+ }
917
+
918
+ return requiredBySource[sourceId];
919
+ }
920
+
921
+ function rewriteRequireExpressionsAndGetImportBlock(
922
+ magicString,
923
+ topLevelDeclarations,
924
+ topLevelRequireDeclarators,
925
+ reassignedNames,
926
+ helpersNameIfUsed,
927
+ dynamicRegisterSources
928
+ ) {
929
+ const removedDeclarators = getDeclaratorsReplacedByImportsAndSetImportNames(
930
+ topLevelRequireDeclarators,
931
+ requiredByNode,
932
+ reassignedNames
933
+ );
934
+ setRemainingImportNamesAndRewriteRequires(
935
+ requireExpressionsWithUsedReturnValue,
936
+ requiredByNode,
937
+ magicString
938
+ );
939
+ removeDeclaratorsFromDeclarations(topLevelDeclarations, removedDeclarators, magicString);
940
+ const importBlock = `${(helpersNameIfUsed
941
+ ? [`import * as ${helpersNameIfUsed} from '${HELPERS_ID}';`]
942
+ : []
943
+ )
944
+ .concat(
945
+ // dynamic registers first, as the may be required in the other modules
946
+ [...dynamicRegisterSources].map((source) => `import '${wrapId(source, REQUIRE_SUFFIX)}';`),
947
+
948
+ // now the actual modules so that they are analyzed before creating the proxies;
949
+ // no need to do this for virtual modules as we never proxy them
950
+ requiredSources
951
+ .filter((source) => !source.startsWith('\0'))
952
+ .map((source) => `import '${wrapId(source, REQUIRE_SUFFIX)}';`),
953
+
954
+ // now the proxy modules
955
+ requiredSources.map((source) => {
956
+ const { name, nodesUsingRequired } = requiredBySource[source];
957
+ return `import ${nodesUsingRequired.length ? `${name} from ` : ``}'${
958
+ source.startsWith('\0') ? source : wrapId(source, PROXY_SUFFIX)
959
+ }';`;
960
+ })
961
+ )
962
+ .join('\n')}`;
963
+ return importBlock ? `${importBlock}\n\n` : '';
964
+ }
965
+
966
+ return {
967
+ addRequireStatement,
968
+ requiredSources,
969
+ rewriteRequireExpressionsAndGetImportBlock
970
+ };
971
+ }
972
+
973
+ function getDeclaratorsReplacedByImportsAndSetImportNames(
974
+ topLevelRequireDeclarators,
975
+ requiredByNode,
976
+ reassignedNames
977
+ ) {
978
+ const removedDeclarators = new Set();
979
+ for (const declarator of topLevelRequireDeclarators) {
980
+ const { required } = requiredByNode.get(declarator.init);
981
+ if (!required.name) {
982
+ const potentialName = declarator.id.name;
1214
983
  if (
1215
- importee.startsWith(HELPERS_ID) ||
1216
- importee === DYNAMIC_PACKAGES_ID ||
1217
- importee.startsWith(DYNAMIC_JSON_PREFIX)
984
+ !reassignedNames.has(potentialName) &&
985
+ !required.nodesUsingRequired.some((node) =>
986
+ isLocallyShadowed(potentialName, requiredByNode.get(node).scope)
987
+ )
1218
988
  ) {
1219
- return importee;
989
+ required.name = potentialName;
990
+ removedDeclarators.add(declarator);
1220
991
  }
1221
- return null;
1222
992
  }
993
+ }
994
+ return removedDeclarators;
995
+ }
996
+
997
+ function setRemainingImportNamesAndRewriteRequires(
998
+ requireExpressionsWithUsedReturnValue,
999
+ requiredByNode,
1000
+ magicString
1001
+ ) {
1002
+ let uid = 0;
1003
+ for (const requireExpression of requireExpressionsWithUsedReturnValue) {
1004
+ const { required } = requiredByNode.get(requireExpression);
1005
+ if (!required.name) {
1006
+ let potentialName;
1007
+ const isUsedName = (node) => requiredByNode.get(node).scope.contains(potentialName);
1008
+ do {
1009
+ potentialName = `require$$${uid}`;
1010
+ uid += 1;
1011
+ } while (required.nodesUsingRequired.some(isUsedName));
1012
+ required.name = potentialName;
1013
+ }
1014
+ magicString.overwrite(requireExpression.start, requireExpression.end, required.name);
1015
+ }
1016
+ }
1223
1017
 
1224
- return this.resolve(importee, importer, {
1225
- skipSelf: true,
1226
- custom: { 'node-resolve': { isRequire: isProxyModule || isRequiredModule } }
1227
- }).then((resolved) => {
1228
- if (!resolved) {
1229
- resolved = resolveExtensions(importee, importer);
1018
+ function removeDeclaratorsFromDeclarations(topLevelDeclarations, removedDeclarators, magicString) {
1019
+ for (const declaration of topLevelDeclarations) {
1020
+ let keepDeclaration = false;
1021
+ let [{ start }] = declaration.declarations;
1022
+ for (const declarator of declaration.declarations) {
1023
+ if (removedDeclarators.has(declarator)) {
1024
+ magicString.remove(start, declarator.end);
1025
+ } else if (!keepDeclaration) {
1026
+ magicString.remove(start, declarator.start);
1027
+ keepDeclaration = true;
1230
1028
  }
1231
- if (resolved && isProxyModule) {
1232
- resolved.id = wrapId(resolved.id, resolved.external ? EXTERNAL_SUFFIX : PROXY_SUFFIX);
1233
- resolved.external = false;
1234
- } else if (!resolved && (isProxyModule || isRequiredModule)) {
1235
- return { id: wrapId(importee, EXTERNAL_SUFFIX), external: false };
1029
+ start = declarator.end;
1030
+ }
1031
+ if (!keepDeclaration) {
1032
+ magicString.remove(declaration.start, declaration.end);
1033
+ }
1034
+ }
1035
+ }
1036
+
1037
+ /* eslint-disable no-param-reassign, no-shadow, no-underscore-dangle, no-continue */
1038
+
1039
+ const exportsPattern = /^(?:module\.)?exports(?:\.([a-zA-Z_$][a-zA-Z_$0-9]*))?$/;
1040
+
1041
+ const functionType = /^(?:FunctionDeclaration|FunctionExpression|ArrowFunctionExpression)$/;
1042
+
1043
+ function transformCommonjs(
1044
+ parse,
1045
+ code,
1046
+ id,
1047
+ isEsModule,
1048
+ ignoreGlobal,
1049
+ ignoreRequire,
1050
+ sourceMap,
1051
+ isDynamicRequireModulesEnabled,
1052
+ dynamicRequireModuleSet,
1053
+ disableWrap,
1054
+ commonDir,
1055
+ astCache
1056
+ ) {
1057
+ const ast = astCache || tryParse(parse, code, id);
1058
+ const magicString = new MagicString__default['default'](code);
1059
+ const uses = {
1060
+ module: false,
1061
+ exports: false,
1062
+ global: false,
1063
+ require: false,
1064
+ commonjsHelpers: false
1065
+ };
1066
+ const virtualDynamicRequirePath =
1067
+ isDynamicRequireModulesEnabled && getVirtualPathForDynamicRequirePath(path.dirname(id), commonDir);
1068
+ let scope = pluginutils.attachScopes(ast, 'scope');
1069
+ let lexicalDepth = 0;
1070
+ let programDepth = 0;
1071
+ let shouldWrap = false;
1072
+ const defineCompiledEsmExpressions = [];
1073
+
1074
+ const globals = new Set();
1075
+
1076
+ // TODO technically wrong since globals isn't populated yet, but ¯\_(ツ)_/¯
1077
+ const HELPERS_NAME = deconflict(scope, globals, 'commonjsHelpers');
1078
+ const namedExports = {};
1079
+ const dynamicRegisterSources = new Set();
1080
+
1081
+ const {
1082
+ addRequireStatement,
1083
+ requiredSources,
1084
+ rewriteRequireExpressionsAndGetImportBlock
1085
+ } = getRequireHandlers();
1086
+
1087
+ // See which names are assigned to. This is necessary to prevent
1088
+ // illegally replacing `var foo = require('foo')` with `import foo from 'foo'`,
1089
+ // where `foo` is later reassigned. (This happens in the wild. CommonJS, sigh)
1090
+ const reassignedNames = new Set();
1091
+ const topLevelDeclarations = [];
1092
+ const topLevelRequireDeclarators = new Set();
1093
+ const skippedNodes = new Set();
1094
+ const topLevelModuleExportsAssignments = [];
1095
+ const topLevelExportsAssignmentsByName = new Map();
1096
+
1097
+ estreeWalker.walk(ast, {
1098
+ enter(node, parent) {
1099
+ if (skippedNodes.has(node)) {
1100
+ this.skip();
1101
+ return;
1236
1102
  }
1237
- return resolved;
1238
- });
1103
+
1104
+ programDepth += 1;
1105
+ if (node.scope) ({ scope } = node);
1106
+ if (functionType.test(node.type)) lexicalDepth += 1;
1107
+ if (sourceMap) {
1108
+ magicString.addSourcemapLocation(node.start);
1109
+ magicString.addSourcemapLocation(node.end);
1110
+ }
1111
+
1112
+ // eslint-disable-next-line default-case
1113
+ switch (node.type) {
1114
+ case 'AssignmentExpression':
1115
+ if (node.left.type === 'MemberExpression') {
1116
+ const flattened = getKeypath(node.left);
1117
+ if (!flattened || scope.contains(flattened.name)) return;
1118
+
1119
+ const exportsPatternMatch = exportsPattern.exec(flattened.keypath);
1120
+ if (!exportsPatternMatch || flattened.keypath === 'exports') return;
1121
+
1122
+ const [, exportName] = exportsPatternMatch;
1123
+ uses[flattened.name] = true;
1124
+
1125
+ // we're dealing with `module.exports = ...` or `[module.]exports.foo = ...` –
1126
+ if (programDepth > 3) {
1127
+ shouldWrap = true;
1128
+ } else if (exportName === KEY_COMPILED_ESM) {
1129
+ defineCompiledEsmExpressions.push(parent);
1130
+ } else if (flattened.keypath === 'module.exports') {
1131
+ topLevelModuleExportsAssignments.push(node);
1132
+ } else if (!topLevelExportsAssignmentsByName.has(exportName)) {
1133
+ topLevelExportsAssignmentsByName.set(exportName, node);
1134
+ } else {
1135
+ shouldWrap = true;
1136
+ }
1137
+
1138
+ skippedNodes.add(node.left);
1139
+
1140
+ if (flattened.keypath === 'module.exports' && node.right.type === 'ObjectExpression') {
1141
+ node.right.properties.forEach((prop) => {
1142
+ if (prop.computed || !('key' in prop) || prop.key.type !== 'Identifier') return;
1143
+ const { name } = prop.key;
1144
+ if (name === pluginutils.makeLegalIdentifier(name)) namedExports[name] = true;
1145
+ });
1146
+ return;
1147
+ }
1148
+
1149
+ if (exportsPatternMatch[1]) namedExports[exportsPatternMatch[1]] = true;
1150
+ } else {
1151
+ for (const name of pluginutils.extractAssignedNames(node.left)) {
1152
+ reassignedNames.add(name);
1153
+ }
1154
+ }
1155
+ return;
1156
+ case 'CallExpression': {
1157
+ if (isDefineCompiledEsm(node)) {
1158
+ if (programDepth === 3 && parent.type === 'ExpressionStatement') {
1159
+ // skip special handling for [module.]exports until we know we render this
1160
+ skippedNodes.add(node.arguments[0]);
1161
+ defineCompiledEsmExpressions.push(parent);
1162
+ } else {
1163
+ shouldWrap = true;
1164
+ }
1165
+ return;
1166
+ }
1167
+ if (!isStaticRequireStatement(node, scope)) return;
1168
+ if (!isDynamicRequireModulesEnabled) {
1169
+ skippedNodes.add(node.callee);
1170
+ }
1171
+ if (!isIgnoredRequireStatement(node, ignoreRequire)) {
1172
+ skippedNodes.add(node.callee);
1173
+ const usesReturnValue = parent.type !== 'ExpressionStatement';
1174
+
1175
+ let sourceId = getRequireStringArg(node);
1176
+ const isDynamicRegister = sourceId.startsWith(DYNAMIC_REGISTER_PREFIX);
1177
+ if (isDynamicRegister) {
1178
+ sourceId = sourceId.substr(DYNAMIC_REGISTER_PREFIX.length);
1179
+ if (sourceId.endsWith('.json')) {
1180
+ sourceId = DYNAMIC_JSON_PREFIX + sourceId;
1181
+ }
1182
+ dynamicRegisterSources.add(sourceId);
1183
+ } else {
1184
+ if (
1185
+ !sourceId.endsWith('.json') &&
1186
+ hasDynamicModuleForPath(sourceId, id, dynamicRequireModuleSet)
1187
+ ) {
1188
+ magicString.overwrite(
1189
+ node.start,
1190
+ node.end,
1191
+ `${HELPERS_NAME}.commonjsRequire(${JSON.stringify(
1192
+ getVirtualPathForDynamicRequirePath(sourceId, commonDir)
1193
+ )}, ${JSON.stringify(
1194
+ path.dirname(id) === '.' ? null /* default behavior */ : virtualDynamicRequirePath
1195
+ )})`
1196
+ );
1197
+ uses.commonjsHelpers = true;
1198
+ return;
1199
+ }
1200
+ addRequireStatement(sourceId, node, scope, usesReturnValue);
1201
+ }
1202
+
1203
+ if (usesReturnValue) {
1204
+ if (
1205
+ parent.type === 'VariableDeclarator' &&
1206
+ !scope.parent &&
1207
+ parent.id.type === 'Identifier'
1208
+ ) {
1209
+ // This will allow us to reuse this variable name as the imported variable if it is not reassigned
1210
+ // and does not conflict with variables in other places where this is imported
1211
+ topLevelRequireDeclarators.add(parent);
1212
+ }
1213
+ } else {
1214
+ // This is a bare import, e.g. `require('foo');`
1215
+ magicString.remove(parent.start, parent.end);
1216
+ }
1217
+ }
1218
+ return;
1219
+ }
1220
+ case 'ConditionalExpression':
1221
+ case 'IfStatement':
1222
+ // skip dead branches
1223
+ if (isFalsy(node.test)) {
1224
+ skippedNodes.add(node.consequent);
1225
+ } else if (node.alternate && isTruthy(node.test)) {
1226
+ skippedNodes.add(node.alternate);
1227
+ }
1228
+ return;
1229
+ case 'Identifier': {
1230
+ const { name } = node;
1231
+ if (!(isReference__default['default'](node, parent) && !scope.contains(name))) return;
1232
+ switch (name) {
1233
+ case 'require':
1234
+ if (isNodeRequirePropertyAccess(parent)) return;
1235
+
1236
+ if (isDynamicRequireModulesEnabled && isRequireStatement(parent, scope)) {
1237
+ magicString.appendLeft(
1238
+ parent.end - 1,
1239
+ `,${JSON.stringify(
1240
+ path.dirname(id) === '.' ? null /* default behavior */ : virtualDynamicRequirePath
1241
+ )}`
1242
+ );
1243
+ }
1244
+
1245
+ magicString.overwrite(node.start, node.end, `${HELPERS_NAME}.commonjsRequire`, {
1246
+ storeName: true
1247
+ });
1248
+ uses.commonjsHelpers = true;
1249
+ return;
1250
+ case 'module':
1251
+ case 'exports':
1252
+ shouldWrap = true;
1253
+ uses[name] = true;
1254
+ return;
1255
+ case 'global':
1256
+ uses.global = true;
1257
+ if (!ignoreGlobal) {
1258
+ magicString.overwrite(node.start, node.end, `${HELPERS_NAME}.commonjsGlobal`, {
1259
+ storeName: true
1260
+ });
1261
+ uses.commonjsHelpers = true;
1262
+ }
1263
+ return;
1264
+ case 'define':
1265
+ magicString.overwrite(node.start, node.end, 'undefined', { storeName: true });
1266
+ return;
1267
+ default:
1268
+ globals.add(name);
1269
+ return;
1270
+ }
1271
+ }
1272
+ case 'MemberExpression':
1273
+ if (!isDynamicRequireModulesEnabled && isModuleRequire(node, scope)) {
1274
+ magicString.overwrite(node.start, node.end, `${HELPERS_NAME}.commonjsRequire`, {
1275
+ storeName: true
1276
+ });
1277
+ uses.commonjsHelpers = true;
1278
+ skippedNodes.add(node.object);
1279
+ skippedNodes.add(node.property);
1280
+ }
1281
+ return;
1282
+ case 'ReturnStatement':
1283
+ // if top-level return, we need to wrap it
1284
+ if (lexicalDepth === 0) {
1285
+ shouldWrap = true;
1286
+ }
1287
+ return;
1288
+ case 'ThisExpression':
1289
+ // rewrite top-level `this` as `commonjsHelpers.commonjsGlobal`
1290
+ if (lexicalDepth === 0) {
1291
+ uses.global = true;
1292
+ if (!ignoreGlobal) {
1293
+ magicString.overwrite(node.start, node.end, `${HELPERS_NAME}.commonjsGlobal`, {
1294
+ storeName: true
1295
+ });
1296
+ uses.commonjsHelpers = true;
1297
+ }
1298
+ }
1299
+ return;
1300
+ case 'UnaryExpression':
1301
+ // rewrite `typeof module`, `typeof module.exports` and `typeof exports` (https://github.com/rollup/rollup-plugin-commonjs/issues/151)
1302
+ if (node.operator === 'typeof') {
1303
+ const flattened = getKeypath(node.argument);
1304
+ if (!flattened) return;
1305
+
1306
+ if (scope.contains(flattened.name)) return;
1307
+
1308
+ if (
1309
+ flattened.keypath === 'module.exports' ||
1310
+ flattened.keypath === 'module' ||
1311
+ flattened.keypath === 'exports'
1312
+ ) {
1313
+ magicString.overwrite(node.start, node.end, `'object'`, { storeName: false });
1314
+ }
1315
+ }
1316
+ return;
1317
+ case 'VariableDeclaration':
1318
+ if (!scope.parent) {
1319
+ topLevelDeclarations.push(node);
1320
+ }
1321
+ }
1322
+ },
1323
+
1324
+ leave(node) {
1325
+ programDepth -= 1;
1326
+ if (node.scope) scope = scope.parent;
1327
+ if (functionType.test(node.type)) lexicalDepth -= 1;
1328
+ }
1329
+ });
1330
+
1331
+ let isRestorableCompiledEsm = false;
1332
+ if (defineCompiledEsmExpressions.length > 0) {
1333
+ if (!shouldWrap && defineCompiledEsmExpressions.length === 1) {
1334
+ isRestorableCompiledEsm = true;
1335
+ magicString.remove(
1336
+ defineCompiledEsmExpressions[0].start,
1337
+ defineCompiledEsmExpressions[0].end
1338
+ );
1339
+ } else {
1340
+ shouldWrap = true;
1341
+ uses.exports = true;
1342
+ }
1343
+ }
1344
+
1345
+ // We cannot wrap ES/mixed modules
1346
+ shouldWrap = shouldWrap && !disableWrap && !isEsModule;
1347
+ uses.commonjsHelpers = uses.commonjsHelpers || shouldWrap;
1348
+
1349
+ if (
1350
+ !(
1351
+ requiredSources.length ||
1352
+ dynamicRegisterSources.size ||
1353
+ uses.module ||
1354
+ uses.exports ||
1355
+ uses.require ||
1356
+ uses.commonjsHelpers
1357
+ ) &&
1358
+ (ignoreGlobal || !uses.global)
1359
+ ) {
1360
+ return { meta: { commonjs: { isCommonJS: false } } };
1361
+ }
1362
+
1363
+ const moduleName = deconflict(scope, globals, getName(id));
1364
+
1365
+ let leadingComment = '';
1366
+ if (code.startsWith('/*')) {
1367
+ const commentEnd = code.indexOf('*/', 2) + 2;
1368
+ leadingComment = `${code.slice(0, commentEnd)}\n`;
1369
+ magicString.remove(0, commentEnd).trim();
1370
+ }
1371
+
1372
+ const exportBlock = isEsModule
1373
+ ? ''
1374
+ : rewriteExportsAndGetExportsBlock(
1375
+ magicString,
1376
+ moduleName,
1377
+ shouldWrap,
1378
+ topLevelModuleExportsAssignments,
1379
+ topLevelExportsAssignmentsByName,
1380
+ defineCompiledEsmExpressions,
1381
+ (name) => deconflict(scope, globals, name),
1382
+ isRestorableCompiledEsm,
1383
+ code,
1384
+ uses,
1385
+ HELPERS_NAME
1386
+ );
1387
+
1388
+ const importBlock = rewriteRequireExpressionsAndGetImportBlock(
1389
+ magicString,
1390
+ topLevelDeclarations,
1391
+ topLevelRequireDeclarators,
1392
+ reassignedNames,
1393
+ uses.commonjsHelpers && HELPERS_NAME,
1394
+ dynamicRegisterSources
1395
+ );
1396
+
1397
+ if (shouldWrap) {
1398
+ wrapCode(magicString, uses, moduleName, HELPERS_NAME, virtualDynamicRequirePath);
1399
+ }
1400
+
1401
+ magicString
1402
+ .trim()
1403
+ .prepend(leadingComment + importBlock)
1404
+ .append(exportBlock);
1405
+
1406
+ return {
1407
+ code: magicString.toString(),
1408
+ map: sourceMap ? magicString.generateMap() : null,
1409
+ syntheticNamedExports: isEsModule ? false : '__moduleExports',
1410
+ meta: { commonjs: { isCommonJS: !isEsModule } }
1239
1411
  };
1240
1412
  }
1241
1413
 
@@ -1287,7 +1459,7 @@ function commonjs(options = {}) {
1287
1459
  getDynamicPackagesEntryIntro(dynamicRequireModuleDirPaths, dynamicRequireModuleSet) + code;
1288
1460
  }
1289
1461
 
1290
- const { isEsModule, hasDefaultExport, hasNamedExports, ast } = checkEsModule(
1462
+ const { isEsModule, hasDefaultExport, hasNamedExports, ast } = analyzeTopLevelStatements(
1291
1463
  this.parse,
1292
1464
  code,
1293
1465
  id
@@ -1329,20 +1501,12 @@ function commonjs(options = {}) {
1329
1501
  name: 'commonjs',
1330
1502
 
1331
1503
  buildStart() {
1504
+ validateRollupVersion(this.meta.rollupVersion, peerDependencies.rollup);
1332
1505
  if (options.namedExports != null) {
1333
1506
  this.warn(
1334
1507
  'The namedExports option from "@rollup/plugin-commonjs" is deprecated. Named exports are now handled automatically.'
1335
1508
  );
1336
1509
  }
1337
-
1338
- const [major, minor] = this.meta.rollupVersion.split('.').map(Number);
1339
- const minVersion = peerDependencies.rollup.slice(2);
1340
- const [minMajor, minMinor] = minVersion.split('.').map(Number);
1341
- if (major < minMajor || (major === minMajor && minor < minMinor)) {
1342
- this.error(
1343
- `Insufficient Rollup version: "@rollup/plugin-commonjs" requires at least rollup@${minVersion} but found rollup@${this.meta.rollupVersion}.`
1344
- );
1345
- }
1346
1510
  },
1347
1511
 
1348
1512
  resolveId,