@parcel/packager-js 2.6.2 → 2.8.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.
@@ -74,16 +74,14 @@ class DevPackager {
74
74
  let queue = new (_utils().PromiseQueue)({
75
75
  maxConcurrent: 32
76
76
  });
77
- this.bundle.traverse(node => {
78
- if (node.type === 'asset') {
79
- queue.add(async () => {
80
- let [code, mapBuffer] = await Promise.all([node.value.getCode(), this.bundle.env.sourceMap && node.value.getMapBuffer()]);
81
- return {
82
- code,
83
- mapBuffer
84
- };
85
- });
86
- }
77
+ this.bundle.traverseAssets(asset => {
78
+ queue.add(async () => {
79
+ let [code, mapBuffer] = await Promise.all([asset.getCode(), this.bundle.env.sourceMap && asset.getMapBuffer()]);
80
+ return {
81
+ code,
82
+ mapBuffer
83
+ };
84
+ });
87
85
  });
88
86
  let results = await queue.run();
89
87
  let assets = '';
@@ -396,7 +396,15 @@ class ScopeHoistingPackager {
396
396
  let resolved = this.bundleGraph.getResolvedAsset(dep, this.bundle);
397
397
  let skipped = this.bundleGraph.isDependencySkipped(dep);
398
398
 
399
- if (!resolved || skipped) {
399
+ if (skipped) {
400
+ continue;
401
+ }
402
+
403
+ if (!resolved) {
404
+ if (!dep.isOptional) {
405
+ this.addExternal(dep);
406
+ }
407
+
400
408
  continue;
401
409
  }
402
410
 
@@ -460,55 +468,60 @@ class ScopeHoistingPackager {
460
468
 
461
469
 
462
470
  if (d != null) {
463
- let dep = depMap.get(d);
471
+ let deps = depMap.get(d);
464
472
 
465
- if (!dep) {
473
+ if (!deps) {
466
474
  return m;
467
475
  }
468
476
 
469
- let resolved = this.bundleGraph.getResolvedAsset(dep, this.bundle);
470
- let skipped = this.bundleGraph.isDependencySkipped(dep);
471
-
472
- if (resolved && !skipped) {
473
- // Hoist variable declarations for the referenced parcelRequire dependencies
474
- // after the dependency is declared. This handles the case where the resulting asset
475
- // is wrapped, but the dependency in this asset is not marked as wrapped. This means
476
- // that it was imported/required at the top-level, so its side effects should run immediately.
477
- let [res, lines] = this.getHoistedParcelRequires(asset, dep, resolved);
478
- let map;
479
-
480
- if (this.bundle.hasAsset(resolved) && !this.seenAssets.has(resolved.id)) {
481
- // If this asset is wrapped, we need to hoist the code for the dependency
482
- // outside our parcelRequire.register wrapper. This is safe because all
483
- // assets referenced by this asset will also be wrapped. Otherwise, inline the
484
- // asset content where the import statement was.
485
- if (shouldWrap) {
486
- depContent.push(this.visitAsset(resolved));
487
- } else {
488
- let [depCode, depMap, depLines] = this.visitAsset(resolved);
489
- res = depCode + '\n' + res;
490
- lines += 1 + depLines;
491
- map = depMap;
492
- }
493
- } // Push this asset's source mappings down by the number of lines in the dependency
494
- // plus the number of hoisted parcelRequires. Then insert the source map for the dependency.
477
+ let replacement = ''; // A single `${id}:${specifier}:esm` might have been resolved to multiple assets due to
478
+ // reexports.
479
+
480
+ for (let dep of deps) {
481
+ let resolved = this.bundleGraph.getResolvedAsset(dep, this.bundle);
482
+ let skipped = this.bundleGraph.isDependencySkipped(dep);
483
+
484
+ if (resolved && !skipped) {
485
+ // Hoist variable declarations for the referenced parcelRequire dependencies
486
+ // after the dependency is declared. This handles the case where the resulting asset
487
+ // is wrapped, but the dependency in this asset is not marked as wrapped. This means
488
+ // that it was imported/required at the top-level, so its side effects should run immediately.
489
+ let [res, lines] = this.getHoistedParcelRequires(asset, dep, resolved);
490
+ let map;
491
+
492
+ if (this.bundle.hasAsset(resolved) && !this.seenAssets.has(resolved.id)) {
493
+ // If this asset is wrapped, we need to hoist the code for the dependency
494
+ // outside our parcelRequire.register wrapper. This is safe because all
495
+ // assets referenced by this asset will also be wrapped. Otherwise, inline the
496
+ // asset content where the import statement was.
497
+ if (shouldWrap) {
498
+ depContent.push(this.visitAsset(resolved));
499
+ } else {
500
+ let [depCode, depMap, depLines] = this.visitAsset(resolved);
501
+ res = depCode + '\n' + res;
502
+ lines += 1 + depLines;
503
+ map = depMap;
504
+ }
505
+ } // Push this asset's source mappings down by the number of lines in the dependency
506
+ // plus the number of hoisted parcelRequires. Then insert the source map for the dependency.
495
507
 
496
508
 
497
- if (sourceMap) {
498
- if (lines > 0) {
499
- sourceMap.offsetLines(lineCount + 1, lines);
500
- }
509
+ if (sourceMap) {
510
+ if (lines > 0) {
511
+ sourceMap.offsetLines(lineCount + 1, lines);
512
+ }
501
513
 
502
- if (map) {
503
- sourceMap.addSourceMap(map, lineCount);
514
+ if (map) {
515
+ sourceMap.addSourceMap(map, lineCount);
516
+ }
504
517
  }
505
- }
506
518
 
507
- lineCount += lines;
508
- return res;
519
+ replacement += res;
520
+ lineCount += lines;
521
+ }
509
522
  }
510
523
 
511
- return '';
524
+ return replacement;
512
525
  } // If it wasn't a dependency, then it was an inline replacement (e.g. $id$import$foo -> $id$export$foo).
513
526
 
514
527
 
@@ -563,73 +576,19 @@ ${code}
563
576
  (0, _assert().default)(typeof assetId === 'string'); // Build two maps: one of import specifiers, and one of imported symbols to replace.
564
577
  // These will be used to build a regex below.
565
578
 
566
- let depMap = new Map();
579
+ let depMap = new (_utils().DefaultMap)(() => []);
567
580
  let replacements = new Map();
568
581
 
569
582
  for (let dep of deps) {
570
- depMap.set(`${assetId}:${(0, _utils2.getSpecifier)(dep)}`, dep);
583
+ let specifierType = dep.specifierType === 'esm' ? `:${dep.specifierType}` : '';
584
+ depMap.get(`${assetId}:${(0, _utils2.getSpecifier)(dep)}${!dep.meta.placeholder ? specifierType : ''}`).push(dep);
571
585
  let asyncResolution = this.bundleGraph.resolveAsyncDependency(dep, this.bundle);
572
586
  let resolved = (asyncResolution === null || asyncResolution === void 0 ? void 0 : asyncResolution.type) === 'asset' ? // Prefer the underlying asset over a runtime to load it. It will
573
587
  // be wrapped in Promise.resolve() later.
574
588
  asyncResolution.value : this.bundleGraph.getResolvedAsset(dep, this.bundle);
575
589
 
576
590
  if (!resolved && !dep.isOptional && !this.bundleGraph.isDependencySkipped(dep)) {
577
- let external = this.addExternal(dep);
578
-
579
- for (let [imported, {
580
- local
581
- }] of dep.symbols) {
582
- // If already imported, just add the already renamed variable to the mapping.
583
- let renamed = external.get(imported);
584
-
585
- if (renamed && local !== '*') {
586
- replacements.set(local, renamed);
587
- continue;
588
- } // For CJS output, always use a property lookup so that exports remain live.
589
- // For ESM output, use named imports which are always live.
590
-
591
-
592
- if (this.bundle.env.outputFormat === 'commonjs') {
593
- renamed = external.get('*');
594
-
595
- if (!renamed) {
596
- renamed = this.getTopLevelName(`$${this.bundle.publicId}$${dep.specifier}`);
597
- external.set('*', renamed);
598
- }
599
-
600
- if (local !== '*') {
601
- let replacement;
602
-
603
- if (imported === '*') {
604
- replacement = renamed;
605
- } else if (imported === 'default') {
606
- replacement = `($parcel$interopDefault(${renamed}))`;
607
- this.usedHelpers.add('$parcel$interopDefault');
608
- } else {
609
- replacement = this.getPropertyAccess(renamed, imported);
610
- }
611
-
612
- replacements.set(local, replacement);
613
- }
614
- } else {
615
- // Rename the specifier so that multiple local imports of the same imported specifier
616
- // are deduplicated. We have to prefix the imported name with the bundle id so that
617
- // local variables do not shadow it.
618
- if (this.exportedSymbols.has(local)) {
619
- renamed = local;
620
- } else if (imported === 'default' || imported === '*') {
621
- renamed = this.getTopLevelName(`$${this.bundle.publicId}$${dep.specifier}`);
622
- } else {
623
- renamed = this.getTopLevelName(`$${this.bundle.publicId}$${imported}`);
624
- }
625
-
626
- external.set(imported, renamed);
627
-
628
- if (local !== '*') {
629
- replacements.set(local, renamed);
630
- }
631
- }
632
- }
591
+ this.addExternal(dep, replacements);
633
592
  }
634
593
 
635
594
  if (!resolved) {
@@ -671,7 +630,7 @@ ${code}
671
630
  return [depMap, replacements];
672
631
  }
673
632
 
674
- addExternal(dep) {
633
+ addExternal(dep, replacements) {
675
634
  if (this.bundle.env.outputFormat === 'global') {
676
635
  throw new (_diagnostic().default)({
677
636
  diagnostic: {
@@ -695,7 +654,60 @@ ${code}
695
654
  this.externals.set(dep.specifier, external);
696
655
  }
697
656
 
698
- return external;
657
+ for (let [imported, {
658
+ local
659
+ }] of dep.symbols) {
660
+ // If already imported, just add the already renamed variable to the mapping.
661
+ let renamed = external.get(imported);
662
+
663
+ if (renamed && local !== '*' && replacements) {
664
+ replacements.set(local, renamed);
665
+ continue;
666
+ } // For CJS output, always use a property lookup so that exports remain live.
667
+ // For ESM output, use named imports which are always live.
668
+
669
+
670
+ if (this.bundle.env.outputFormat === 'commonjs') {
671
+ renamed = external.get('*');
672
+
673
+ if (!renamed) {
674
+ renamed = this.getTopLevelName(`$${this.bundle.publicId}$${dep.specifier}`);
675
+ external.set('*', renamed);
676
+ }
677
+
678
+ if (local !== '*' && replacements) {
679
+ let replacement;
680
+
681
+ if (imported === '*') {
682
+ replacement = renamed;
683
+ } else if (imported === 'default') {
684
+ replacement = `($parcel$interopDefault(${renamed}))`;
685
+ this.usedHelpers.add('$parcel$interopDefault');
686
+ } else {
687
+ replacement = this.getPropertyAccess(renamed, imported);
688
+ }
689
+
690
+ replacements.set(local, replacement);
691
+ }
692
+ } else {
693
+ // Rename the specifier so that multiple local imports of the same imported specifier
694
+ // are deduplicated. We have to prefix the imported name with the bundle id so that
695
+ // local variables do not shadow it.
696
+ if (this.exportedSymbols.has(local)) {
697
+ renamed = local;
698
+ } else if (imported === 'default' || imported === '*') {
699
+ renamed = this.getTopLevelName(`$${this.bundle.publicId}$${dep.specifier}`);
700
+ } else {
701
+ renamed = this.getTopLevelName(`$${this.bundle.publicId}$${imported}`);
702
+ }
703
+
704
+ external.set(imported, renamed);
705
+
706
+ if (local !== '*' && replacements) {
707
+ replacements.set(local, renamed);
708
+ }
709
+ }
710
+ }
699
711
  }
700
712
 
701
713
  getSymbolResolution(parentAsset, resolved, imported, dep) {
@@ -707,8 +719,9 @@ ${code}
707
719
  symbol
708
720
  } = this.bundleGraph.getSymbolResolution(resolved, imported, this.bundle);
709
721
 
710
- if (resolvedAsset.type !== 'js') {
711
- // Graceful fallback for non-js imports
722
+ if (resolvedAsset.type !== 'js' || dep && this.bundleGraph.isDependencySkipped(dep)) {
723
+ // Graceful fallback for non-js imports or when trying to resolve a symbol
724
+ // that is actually unused but we still need a placeholder value.
712
725
  return '{}';
713
726
  }
714
727
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parcel/packager-js",
3
- "version": "2.6.2",
3
+ "version": "2.8.0",
4
4
  "license": "MIT",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -17,16 +17,16 @@
17
17
  "source": "src/index.js",
18
18
  "engines": {
19
19
  "node": ">= 12.0.0",
20
- "parcel": "^2.6.2"
20
+ "parcel": "^2.8.0"
21
21
  },
22
22
  "dependencies": {
23
- "@parcel/diagnostic": "2.6.2",
24
- "@parcel/hash": "2.6.2",
25
- "@parcel/plugin": "2.6.2",
26
- "@parcel/source-map": "^2.0.0",
27
- "@parcel/utils": "2.6.2",
23
+ "@parcel/diagnostic": "2.8.0",
24
+ "@parcel/hash": "2.8.0",
25
+ "@parcel/plugin": "2.8.0",
26
+ "@parcel/source-map": "^2.1.1",
27
+ "@parcel/utils": "2.8.0",
28
28
  "globals": "^13.2.0",
29
29
  "nullthrows": "^1.1.1"
30
30
  },
31
- "gitHead": "e10fcfc1e8b71222da90978fb87f1b68e207473e"
31
+ "gitHead": "c3bbe0a6160186f496ca2f9e9bead9376c0522f1"
32
32
  }
@@ -39,16 +39,14 @@ export class DevPackager {
39
39
  async package(): Promise<{|contents: string, map: ?SourceMap|}> {
40
40
  // Load assets
41
41
  let queue = new PromiseQueue({maxConcurrent: 32});
42
- this.bundle.traverse(node => {
43
- if (node.type === 'asset') {
44
- queue.add(async () => {
45
- let [code, mapBuffer] = await Promise.all([
46
- node.value.getCode(),
47
- this.bundle.env.sourceMap && node.value.getMapBuffer(),
48
- ]);
49
- return {code, mapBuffer};
50
- });
51
- }
42
+ this.bundle.traverseAssets(asset => {
43
+ queue.add(async () => {
44
+ let [code, mapBuffer] = await Promise.all([
45
+ asset.getCode(),
46
+ this.bundle.env.sourceMap && asset.getMapBuffer(),
47
+ ]);
48
+ return {code, mapBuffer};
49
+ });
52
50
  });
53
51
 
54
52
  let results = await queue.run();
@@ -9,6 +9,7 @@ import type {
9
9
  } from '@parcel/types';
10
10
 
11
11
  import {
12
+ DefaultMap,
12
13
  PromiseQueue,
13
14
  relativeBundlePath,
14
15
  countLines,
@@ -400,7 +401,15 @@ export class ScopeHoistingPackager {
400
401
  for (let dep of deps) {
401
402
  let resolved = this.bundleGraph.getResolvedAsset(dep, this.bundle);
402
403
  let skipped = this.bundleGraph.isDependencySkipped(dep);
403
- if (!resolved || skipped) {
404
+ if (skipped) {
405
+ continue;
406
+ }
407
+
408
+ if (!resolved) {
409
+ if (!dep.isOptional) {
410
+ this.addExternal(dep);
411
+ }
412
+
404
413
  continue;
405
414
  }
406
415
 
@@ -464,59 +473,64 @@ export class ScopeHoistingPackager {
464
473
 
465
474
  // If we matched an import, replace with the source code for the dependency.
466
475
  if (d != null) {
467
- let dep = depMap.get(d);
468
- if (!dep) {
476
+ let deps = depMap.get(d);
477
+ if (!deps) {
469
478
  return m;
470
479
  }
471
480
 
472
- let resolved = this.bundleGraph.getResolvedAsset(dep, this.bundle);
473
- let skipped = this.bundleGraph.isDependencySkipped(dep);
474
- if (resolved && !skipped) {
475
- // Hoist variable declarations for the referenced parcelRequire dependencies
476
- // after the dependency is declared. This handles the case where the resulting asset
477
- // is wrapped, but the dependency in this asset is not marked as wrapped. This means
478
- // that it was imported/required at the top-level, so its side effects should run immediately.
479
- let [res, lines] = this.getHoistedParcelRequires(
480
- asset,
481
- dep,
482
- resolved,
483
- );
484
- let map;
485
- if (
486
- this.bundle.hasAsset(resolved) &&
487
- !this.seenAssets.has(resolved.id)
488
- ) {
489
- // If this asset is wrapped, we need to hoist the code for the dependency
490
- // outside our parcelRequire.register wrapper. This is safe because all
491
- // assets referenced by this asset will also be wrapped. Otherwise, inline the
492
- // asset content where the import statement was.
493
- if (shouldWrap) {
494
- depContent.push(this.visitAsset(resolved));
495
- } else {
496
- let [depCode, depMap, depLines] = this.visitAsset(resolved);
497
- res = depCode + '\n' + res;
498
- lines += 1 + depLines;
499
- map = depMap;
481
+ let replacement = '';
482
+
483
+ // A single `${id}:${specifier}:esm` might have been resolved to multiple assets due to
484
+ // reexports.
485
+ for (let dep of deps) {
486
+ let resolved = this.bundleGraph.getResolvedAsset(dep, this.bundle);
487
+ let skipped = this.bundleGraph.isDependencySkipped(dep);
488
+ if (resolved && !skipped) {
489
+ // Hoist variable declarations for the referenced parcelRequire dependencies
490
+ // after the dependency is declared. This handles the case where the resulting asset
491
+ // is wrapped, but the dependency in this asset is not marked as wrapped. This means
492
+ // that it was imported/required at the top-level, so its side effects should run immediately.
493
+ let [res, lines] = this.getHoistedParcelRequires(
494
+ asset,
495
+ dep,
496
+ resolved,
497
+ );
498
+ let map;
499
+ if (
500
+ this.bundle.hasAsset(resolved) &&
501
+ !this.seenAssets.has(resolved.id)
502
+ ) {
503
+ // If this asset is wrapped, we need to hoist the code for the dependency
504
+ // outside our parcelRequire.register wrapper. This is safe because all
505
+ // assets referenced by this asset will also be wrapped. Otherwise, inline the
506
+ // asset content where the import statement was.
507
+ if (shouldWrap) {
508
+ depContent.push(this.visitAsset(resolved));
509
+ } else {
510
+ let [depCode, depMap, depLines] = this.visitAsset(resolved);
511
+ res = depCode + '\n' + res;
512
+ lines += 1 + depLines;
513
+ map = depMap;
514
+ }
500
515
  }
501
- }
502
516
 
503
- // Push this asset's source mappings down by the number of lines in the dependency
504
- // plus the number of hoisted parcelRequires. Then insert the source map for the dependency.
505
- if (sourceMap) {
506
- if (lines > 0) {
507
- sourceMap.offsetLines(lineCount + 1, lines);
508
- }
517
+ // Push this asset's source mappings down by the number of lines in the dependency
518
+ // plus the number of hoisted parcelRequires. Then insert the source map for the dependency.
519
+ if (sourceMap) {
520
+ if (lines > 0) {
521
+ sourceMap.offsetLines(lineCount + 1, lines);
522
+ }
509
523
 
510
- if (map) {
511
- sourceMap.addSourceMap(map, lineCount);
524
+ if (map) {
525
+ sourceMap.addSourceMap(map, lineCount);
526
+ }
512
527
  }
513
- }
514
528
 
515
- lineCount += lines;
516
- return res;
529
+ replacement += res;
530
+ lineCount += lines;
531
+ }
517
532
  }
518
-
519
- return '';
533
+ return replacement;
520
534
  }
521
535
 
522
536
  // If it wasn't a dependency, then it was an inline replacement (e.g. $id$import$foo -> $id$export$foo).
@@ -572,16 +586,24 @@ ${code}
572
586
  buildReplacements(
573
587
  asset: Asset,
574
588
  deps: Array<Dependency>,
575
- ): [Map<string, Dependency>, Map<string, string>] {
589
+ ): [Map<string, Array<Dependency>>, Map<string, string>] {
576
590
  let assetId = asset.meta.id;
577
591
  invariant(typeof assetId === 'string');
578
592
 
579
593
  // Build two maps: one of import specifiers, and one of imported symbols to replace.
580
594
  // These will be used to build a regex below.
581
- let depMap = new Map();
595
+ let depMap = new DefaultMap<string, Array<Dependency>>(() => []);
582
596
  let replacements = new Map();
583
597
  for (let dep of deps) {
584
- depMap.set(`${assetId}:${getSpecifier(dep)}`, dep);
598
+ let specifierType =
599
+ dep.specifierType === 'esm' ? `:${dep.specifierType}` : '';
600
+ depMap
601
+ .get(
602
+ `${assetId}:${getSpecifier(dep)}${
603
+ !dep.meta.placeholder ? specifierType : ''
604
+ }`,
605
+ )
606
+ .push(dep);
585
607
 
586
608
  let asyncResolution = this.bundleGraph.resolveAsyncDependency(
587
609
  dep,
@@ -598,62 +620,7 @@ ${code}
598
620
  !dep.isOptional &&
599
621
  !this.bundleGraph.isDependencySkipped(dep)
600
622
  ) {
601
- let external = this.addExternal(dep);
602
- for (let [imported, {local}] of dep.symbols) {
603
- // If already imported, just add the already renamed variable to the mapping.
604
- let renamed = external.get(imported);
605
- if (renamed && local !== '*') {
606
- replacements.set(local, renamed);
607
- continue;
608
- }
609
-
610
- // For CJS output, always use a property lookup so that exports remain live.
611
- // For ESM output, use named imports which are always live.
612
- if (this.bundle.env.outputFormat === 'commonjs') {
613
- renamed = external.get('*');
614
- if (!renamed) {
615
- renamed = this.getTopLevelName(
616
- `$${this.bundle.publicId}$${dep.specifier}`,
617
- );
618
-
619
- external.set('*', renamed);
620
- }
621
-
622
- if (local !== '*') {
623
- let replacement;
624
- if (imported === '*') {
625
- replacement = renamed;
626
- } else if (imported === 'default') {
627
- replacement = `($parcel$interopDefault(${renamed}))`;
628
- this.usedHelpers.add('$parcel$interopDefault');
629
- } else {
630
- replacement = this.getPropertyAccess(renamed, imported);
631
- }
632
-
633
- replacements.set(local, replacement);
634
- }
635
- } else {
636
- // Rename the specifier so that multiple local imports of the same imported specifier
637
- // are deduplicated. We have to prefix the imported name with the bundle id so that
638
- // local variables do not shadow it.
639
- if (this.exportedSymbols.has(local)) {
640
- renamed = local;
641
- } else if (imported === 'default' || imported === '*') {
642
- renamed = this.getTopLevelName(
643
- `$${this.bundle.publicId}$${dep.specifier}`,
644
- );
645
- } else {
646
- renamed = this.getTopLevelName(
647
- `$${this.bundle.publicId}$${imported}`,
648
- );
649
- }
650
-
651
- external.set(imported, renamed);
652
- if (local !== '*') {
653
- replacements.set(local, renamed);
654
- }
655
- }
656
- }
623
+ this.addExternal(dep, replacements);
657
624
  }
658
625
 
659
626
  if (!resolved) {
@@ -705,7 +672,7 @@ ${code}
705
672
  return [depMap, replacements];
706
673
  }
707
674
 
708
- addExternal(dep: Dependency): Map<string, string> {
675
+ addExternal(dep: Dependency, replacements?: Map<string, string>) {
709
676
  if (this.bundle.env.outputFormat === 'global') {
710
677
  throw new ThrowableDiagnostic({
711
678
  diagnostic: {
@@ -735,7 +702,61 @@ ${code}
735
702
  this.externals.set(dep.specifier, external);
736
703
  }
737
704
 
738
- return external;
705
+ for (let [imported, {local}] of dep.symbols) {
706
+ // If already imported, just add the already renamed variable to the mapping.
707
+ let renamed = external.get(imported);
708
+ if (renamed && local !== '*' && replacements) {
709
+ replacements.set(local, renamed);
710
+ continue;
711
+ }
712
+
713
+ // For CJS output, always use a property lookup so that exports remain live.
714
+ // For ESM output, use named imports which are always live.
715
+ if (this.bundle.env.outputFormat === 'commonjs') {
716
+ renamed = external.get('*');
717
+ if (!renamed) {
718
+ renamed = this.getTopLevelName(
719
+ `$${this.bundle.publicId}$${dep.specifier}`,
720
+ );
721
+
722
+ external.set('*', renamed);
723
+ }
724
+
725
+ if (local !== '*' && replacements) {
726
+ let replacement;
727
+ if (imported === '*') {
728
+ replacement = renamed;
729
+ } else if (imported === 'default') {
730
+ replacement = `($parcel$interopDefault(${renamed}))`;
731
+ this.usedHelpers.add('$parcel$interopDefault');
732
+ } else {
733
+ replacement = this.getPropertyAccess(renamed, imported);
734
+ }
735
+
736
+ replacements.set(local, replacement);
737
+ }
738
+ } else {
739
+ // Rename the specifier so that multiple local imports of the same imported specifier
740
+ // are deduplicated. We have to prefix the imported name with the bundle id so that
741
+ // local variables do not shadow it.
742
+ if (this.exportedSymbols.has(local)) {
743
+ renamed = local;
744
+ } else if (imported === 'default' || imported === '*') {
745
+ renamed = this.getTopLevelName(
746
+ `$${this.bundle.publicId}$${dep.specifier}`,
747
+ );
748
+ } else {
749
+ renamed = this.getTopLevelName(
750
+ `$${this.bundle.publicId}$${imported}`,
751
+ );
752
+ }
753
+
754
+ external.set(imported, renamed);
755
+ if (local !== '*' && replacements) {
756
+ replacements.set(local, renamed);
757
+ }
758
+ }
759
+ }
739
760
  }
740
761
 
741
762
  getSymbolResolution(
@@ -749,10 +770,16 @@ ${code}
749
770
  exportSymbol,
750
771
  symbol,
751
772
  } = this.bundleGraph.getSymbolResolution(resolved, imported, this.bundle);
752
- if (resolvedAsset.type !== 'js') {
753
- // Graceful fallback for non-js imports
773
+
774
+ if (
775
+ resolvedAsset.type !== 'js' ||
776
+ (dep && this.bundleGraph.isDependencySkipped(dep))
777
+ ) {
778
+ // Graceful fallback for non-js imports or when trying to resolve a symbol
779
+ // that is actually unused but we still need a placeholder value.
754
780
  return '{}';
755
781
  }
782
+
756
783
  let isWrapped =
757
784
  !this.bundle.hasAsset(resolvedAsset) ||
758
785
  (this.wrappedAssets.has(resolvedAsset.id) &&