@embroider/core 3.4.4 → 3.4.6-unstable.8c7b24d

Sign up to get free protection for your applications and to get access to all the features.
@@ -15,58 +15,47 @@ const path_1 = require("path");
15
15
  const shared_internals_2 = require("@embroider/shared-internals");
16
16
  const debug_1 = __importDefault(require("debug"));
17
17
  const assert_never_1 = __importDefault(require("assert-never"));
18
- const resolve_1 = __importDefault(require("resolve"));
18
+ const reverse_exports_1 = __importDefault(require("@embroider/reverse-exports"));
19
19
  const virtual_content_1 = require("./virtual-content");
20
20
  const typescript_memoize_1 = require("typescript-memoize");
21
21
  const describe_exports_1 = require("./describe-exports");
22
22
  const fs_1 = require("fs");
23
+ const node_resolve_1 = require("./node-resolve");
23
24
  const debug = (0, debug_1.default)('embroider:resolver');
25
+ // Using a formatter makes this work lazy so nothing happens when we aren't
26
+ // logging. It is unfortunate that formatters are a globally mutable config and
27
+ // you can only use single character names, but oh well.
28
+ debug_1.default.formatters.p = (s) => {
29
+ let cwd = process.cwd();
30
+ if (s.startsWith(cwd)) {
31
+ return s.slice(cwd.length + 1);
32
+ }
33
+ return s;
34
+ };
24
35
  function logTransition(reason, before, after = before) {
25
36
  if (after.isVirtual) {
26
- debug(`virtualized %s in %s because %s`, before.specifier, before.fromFile, reason);
37
+ debug(`[%s:virtualized] %s because %s\n in %p`, before.debugType, before.specifier, reason, before.fromFile);
27
38
  }
28
39
  else if (before.specifier !== after.specifier) {
29
40
  if (before.fromFile !== after.fromFile) {
30
- debug(`aliased and rehomed: %s to %s, from %s to %s because %s`, before.specifier, after.specifier, before.fromFile, after.fromFile, reason);
41
+ debug(`[%s:aliased and rehomed] %s to %s\n because %s\n from %p\n to %p`, before.debugType, before.specifier, after.specifier, reason, before.fromFile, after.fromFile);
31
42
  }
32
43
  else {
33
- debug(`aliased: %s to %s in %s because`, before.specifier, after.specifier, before.fromFile, reason);
44
+ debug(`[%s:aliased] %s to %s\n because %s`, before.debugType, before.specifier, after.specifier, reason);
34
45
  }
35
46
  }
36
47
  else if (before.fromFile !== after.fromFile) {
37
- debug(`rehomed: %s from %s to %s because`, before.specifier, before.fromFile, after.fromFile, reason);
48
+ debug(`[%s:rehomed] %s, because %s\n from %p\n to %p`, before.debugType, before.specifier, reason, before.fromFile, after.fromFile);
49
+ }
50
+ else if (after.isNotFound) {
51
+ debug(`[%s:not-found] %s because %s\n in %p`, before.debugType, before.specifier, reason, before.fromFile);
38
52
  }
39
53
  else {
40
- debug(`unchanged: %s in %s because %s`, before.specifier, before.fromFile, reason);
54
+ debug(`[%s:unchanged] %s because %s\n in %p`, before.debugType, before.specifier, reason, before.fromFile);
41
55
  }
42
56
  return after;
43
57
  }
44
58
  const compatPattern = /#embroider_compat\/(?<type>[^\/]+)\/(?<rest>.*)/;
45
- class NodeModuleRequest {
46
- constructor(specifier, fromFile, isVirtual, meta) {
47
- this.specifier = specifier;
48
- this.fromFile = fromFile;
49
- this.isVirtual = isVirtual;
50
- this.meta = meta;
51
- }
52
- alias(specifier) {
53
- return new NodeModuleRequest(specifier, this.fromFile, false, this.meta);
54
- }
55
- rehome(fromFile) {
56
- if (this.fromFile === fromFile) {
57
- return this;
58
- }
59
- else {
60
- return new NodeModuleRequest(this.specifier, fromFile, false, this.meta);
61
- }
62
- }
63
- virtualize(filename) {
64
- return new NodeModuleRequest(filename, this.fromFile, true, this.meta);
65
- }
66
- withMeta(meta) {
67
- return new NodeModuleRequest(this.specifier, this.fromFile, this.isVirtual, meta);
68
- }
69
- }
70
59
  class Resolver {
71
60
  constructor(options) {
72
61
  this.options = options;
@@ -79,6 +68,9 @@ class Resolver {
79
68
  // why we need to know about it.
80
69
  return logTransition('early exit', request);
81
70
  }
71
+ if (request.specifier === 'require') {
72
+ return this.external('early require', request, request.specifier);
73
+ }
82
74
  request = this.handleFastbootSwitch(request);
83
75
  request = this.handleGlobalsCompat(request);
84
76
  request = this.handleImplicitModules(request);
@@ -140,10 +132,10 @@ class Resolver {
140
132
  if (nextRequest.fromFile === request.fromFile && nextRequest.specifier === request.specifier) {
141
133
  throw new Error('Bug Discovered! New request is not === original request but has the same fromFile and specifier. This will likely create a loop.');
142
134
  }
143
- if (nextRequest.isVirtual) {
144
- // virtual requests are terminal, there is no more beforeResolve or
145
- // fallbackResolve around them. The defaultResolve is expected to know how
146
- // to implement them.
135
+ if (nextRequest.isVirtual || nextRequest.isNotFound) {
136
+ // virtual and NotFound requests are terminal, there is no more
137
+ // beforeResolve or fallbackResolve around them. The defaultResolve is
138
+ // expected to know how to implement them.
147
139
  return yield defaultResolve(nextRequest);
148
140
  }
149
141
  return yield* this.internalResolve(nextRequest, defaultResolve);
@@ -152,39 +144,7 @@ class Resolver {
152
144
  // top. This is a convenience method for calling resolveSync with the
153
145
  // defaultResolve already configured to be "do the normal node thing".
154
146
  nodeResolve(specifier, fromFile) {
155
- let resolution = this.resolveSync(new NodeModuleRequest(specifier, fromFile, false, undefined), request => {
156
- if (request.isVirtual) {
157
- return {
158
- type: 'found',
159
- result: {
160
- type: 'virtual',
161
- content: (0, virtual_content_1.virtualContent)(request.specifier, this),
162
- filename: request.specifier,
163
- },
164
- };
165
- }
166
- try {
167
- let filename = resolve_1.default.sync(request.specifier, {
168
- basedir: (0, path_1.dirname)(request.fromFile),
169
- extensions: this.options.resolvableExtensions,
170
- });
171
- return { type: 'found', result: { type: 'real', filename } };
172
- }
173
- catch (err) {
174
- if (err.code !== 'MODULE_NOT_FOUND') {
175
- throw err;
176
- }
177
- return { type: 'not_found', err };
178
- }
179
- });
180
- switch (resolution.type) {
181
- case 'not_found':
182
- return resolution;
183
- case 'found':
184
- return resolution.result;
185
- default:
186
- throw (0, assert_never_1.default)(resolution);
187
- }
147
+ return (0, node_resolve_1.nodeResolve)(this, specifier, fromFile);
188
148
  }
189
149
  get packageCache() {
190
150
  return shared_internals_2.RewrittenPackageCache.shared('embroider', this.options.appRoot);
@@ -275,7 +235,7 @@ class Resolver {
275
235
  }
276
236
  let entry = (_a = this.getEntryFromMergeMap(rel, pkg.root)) === null || _a === void 0 ? void 0 : _a.entry;
277
237
  if ((entry === null || entry === void 0 ? void 0 : entry.type) === 'both') {
278
- return logTransition('matched addon entry', request, request.alias(entry[section].localPath).rehome((0, path_1.resolve)(entry[section].packageRoot, 'package.json')));
238
+ return logTransition('matched addon entry', request, request.alias(entry[section].specifier).rehome(entry[section].fromFile));
279
239
  }
280
240
  }
281
241
  return logTransition('failed to match in fastboot switch', request);
@@ -332,28 +292,30 @@ class Resolver {
332
292
  let jsModule = null;
333
293
  // first, the various places our template might be.
334
294
  for (let candidate of this.componentTemplateCandidates(target.packageName)) {
295
+ let candidateSpecifier = `${target.packageName}${candidate.prefix}${target.memberName}${candidate.suffix}.hbs`;
335
296
  let resolution = this.nodeResolve(`${target.packageName}${candidate.prefix}${target.memberName}${candidate.suffix}`, target.from);
336
297
  if (resolution.type === 'real') {
337
- hbsModule = resolution.filename;
298
+ hbsModule = { requested: candidateSpecifier, found: resolution.filename };
338
299
  break;
339
300
  }
340
301
  }
341
302
  // then the various places our javascript might be.
342
303
  for (let candidate of this.componentJSCandidates(target.packageName)) {
343
- let resolution = this.nodeResolve(`${target.packageName}${candidate.prefix}${target.memberName}${candidate.suffix}`, target.from);
304
+ let candidateSpecifier = `${target.packageName}${candidate.prefix}${target.memberName}${candidate.suffix}`;
305
+ let resolution = this.nodeResolve(candidateSpecifier, target.from);
344
306
  // .hbs is a resolvable extension for us, so we need to exclude it here.
345
307
  // It matches as a priority lower than .js, so finding an .hbs means
346
308
  // there's definitely not a .js.
347
309
  if (resolution.type === 'real' && !resolution.filename.endsWith('.hbs')) {
348
- jsModule = resolution.filename;
310
+ jsModule = { requested: candidateSpecifier, found: resolution.filename };
349
311
  break;
350
312
  }
351
313
  }
352
314
  if (hbsModule) {
353
- return logTransition(`resolveComponent found legacy HBS`, request, request.virtualize((0, virtual_content_1.virtualPairComponent)(hbsModule, jsModule)));
315
+ return logTransition(`resolveComponent found legacy HBS`, request, request.virtualize((0, virtual_content_1.virtualPairComponent)(hbsModule.found, jsModule === null || jsModule === void 0 ? void 0 : jsModule.found)));
354
316
  }
355
317
  else if (jsModule) {
356
- return logTransition(`resolveComponent found only JS`, request, request.alias(jsModule).rehome(target.from));
318
+ return logTransition(`resolveComponent found only JS`, request, request.alias(jsModule.requested).rehome(target.from));
357
319
  }
358
320
  else {
359
321
  return logTransition(`resolveComponent failed`, request);
@@ -395,11 +357,20 @@ class Resolver {
395
357
  }
396
358
  }
397
359
  *componentJSCandidates(inPackageName) {
360
+ const extensions = ['.ts', '.gjs', '.gts'];
398
361
  yield { prefix: '/components/', suffix: '' };
399
362
  yield { prefix: '/components/', suffix: '/component' };
363
+ for (const ext of extensions) {
364
+ yield { prefix: '/components/', suffix: ext };
365
+ yield { prefix: '/components/', suffix: `/index${ext}` };
366
+ yield { prefix: '/components/', suffix: `/component${ext}` };
367
+ }
400
368
  let pods = this.podPrefix(inPackageName);
401
369
  if (pods) {
402
370
  yield { prefix: `${pods}/components/`, suffix: '/component' };
371
+ for (const ext of extensions) {
372
+ yield { prefix: `${pods}/components/`, suffix: `/component${ext}` };
373
+ }
403
374
  }
404
375
  }
405
376
  podPrefix(targetPackageName) {
@@ -414,10 +385,10 @@ class Resolver {
414
385
  parseGlobalPath(path, inEngine) {
415
386
  let parts = path.split('@');
416
387
  if (parts.length > 1 && parts[0].length > 0) {
417
- return { packageName: parts[0], memberName: parts[1], from: (0, path_1.resolve)(inEngine.root, 'pacakge.json') };
388
+ return { packageName: parts[0], memberName: parts[1], from: (0, path_1.resolve)(inEngine.root, 'package.json') };
418
389
  }
419
390
  else {
420
- return { packageName: inEngine.packageName, memberName: path, from: (0, path_1.resolve)(inEngine.root, 'pacakge.json') };
391
+ return { packageName: inEngine.packageName, memberName: path, from: (0, path_1.resolve)(inEngine.root, 'package.json') };
421
392
  }
422
393
  }
423
394
  engineConfig(packageName) {
@@ -449,8 +420,8 @@ class Resolver {
449
420
  engineModules.set(inEngineName, {
450
421
  type: 'app-only',
451
422
  'app-js': {
452
- localPath: inAddonName,
453
- packageRoot: addon.root,
423
+ specifier: (0, reverse_exports_1.default)(addon.packageJSON, inAddonName),
424
+ fromFile: addonConfig.canResolveFromFile,
454
425
  fromPackageName: addon.name,
455
426
  },
456
427
  });
@@ -463,8 +434,8 @@ class Resolver {
463
434
  engineModules.set(inEngineName, {
464
435
  type: 'both',
465
436
  'app-js': {
466
- localPath: inAddonName,
467
- packageRoot: addon.root,
437
+ specifier: (0, reverse_exports_1.default)(addon.packageJSON, inAddonName),
438
+ fromFile: addonConfig.canResolveFromFile,
468
439
  fromPackageName: addon.name,
469
440
  },
470
441
  'fastboot-js': prevEntry['fastboot-js'],
@@ -488,8 +459,8 @@ class Resolver {
488
459
  engineModules.set(inEngineName, {
489
460
  type: 'fastboot-only',
490
461
  'fastboot-js': {
491
- localPath: inAddonName,
492
- packageRoot: addon.root,
462
+ specifier: (0, reverse_exports_1.default)(addon.packageJSON, inAddonName),
463
+ fromFile: addonConfig.canResolveFromFile,
493
464
  fromPackageName: addon.name,
494
465
  },
495
466
  });
@@ -502,8 +473,8 @@ class Resolver {
502
473
  engineModules.set(inEngineName, {
503
474
  type: 'both',
504
475
  'fastboot-js': {
505
- localPath: inAddonName,
506
- packageRoot: addon.root,
476
+ specifier: (0, reverse_exports_1.default)(addon.packageJSON, inAddonName),
477
+ fromFile: addonConfig.canResolveFromFile,
507
478
  fromPackageName: addon.name,
508
479
  },
509
480
  'app-js': prevEntry['app-js'],
@@ -525,7 +496,7 @@ class Resolver {
525
496
  return owningEngine;
526
497
  }
527
498
  handleRewrittenPackages(request) {
528
- if (request.isVirtual) {
499
+ if (request.isVirtual || request.isNotFound) {
529
500
  return request;
530
501
  }
531
502
  let requestingPkg = this.packageCache.ownerOfFile(request.fromFile);
@@ -544,10 +515,6 @@ class Resolver {
544
515
  targetPkg = this.packageCache.resolve(packageName, requestingPkg);
545
516
  }
546
517
  catch (err) {
547
- // this is not the place to report resolution failures. If the thing
548
- // doesn't resolve, we're just not interested in redirecting it for
549
- // backward-compat, that's all. The rest of the system will take care of
550
- // reporting a failure to resolve (or handling it a different way)
551
518
  if (err.code !== 'MODULE_NOT_FOUND') {
552
519
  throw err;
553
520
  }
@@ -563,14 +530,26 @@ class Resolver {
563
530
  return logTransition('request targets a moved package', request, this.resolveWithinMovedPackage(request, targetPkg));
564
531
  }
565
532
  else if (originalRequestingPkg !== requestingPkg) {
566
- // in this case, the requesting package is moved but its destination is
567
- // not, so we need to rehome the request back to the original location.
568
- return logTransition('outbound request from moved package', request, request.withMeta({ wasMovedTo: request.fromFile }).rehome((0, path_1.resolve)(originalRequestingPkg.root, 'package.json')));
533
+ if (targetPkg) {
534
+ // in this case, the requesting package is moved but its destination is
535
+ // not, so we need to rehome the request back to the original location.
536
+ return logTransition('outbound request from moved package', request, request
537
+ // setting meta here because if this fails, we want the fallback
538
+ // logic to revert our rehome and continue from the *moved* package.
539
+ .withMeta({ originalFromFile: request.fromFile })
540
+ .rehome((0, path_1.resolve)(originalRequestingPkg.root, 'package.json')));
541
+ }
542
+ else {
543
+ // requesting package was moved and we failed to find its target. We
544
+ // can't let that accidentally succeed in the defaultResolve because we
545
+ // could escape the moved package system.
546
+ return logTransition('missing outbound request from moved package', request, request.notFound());
547
+ }
569
548
  }
570
549
  return request;
571
550
  }
572
551
  handleRenaming(request) {
573
- if (request.isVirtual) {
552
+ if (request.isVirtual || request.isNotFound) {
574
553
  return request;
575
554
  }
576
555
  let packageName = (0, shared_internals_1.packageName)(request.specifier);
@@ -608,7 +587,10 @@ class Resolver {
608
587
  // packages get this help, v2 packages are natively supposed to make their
609
588
  // own modules resolvable, and we want to push them all to do that
610
589
  // correctly.
611
- return logTransition(`v1 self-import`, request, request.alias(request.specifier.replace(pkg.name, '.')).rehome((0, path_1.resolve)(pkg.root, 'package.json')));
590
+ // "my-package/foo" -> "./foo"
591
+ // "my-package" -> "./" (this can't be just "." because node's require.resolve doesn't reliable support that)
592
+ let selfImportPath = request.specifier === pkg.name ? './' : request.specifier.replace(pkg.name, '.');
593
+ return logTransition(`v1 self-import`, request, request.alias(selfImportPath).rehome((0, path_1.resolve)(pkg.root, 'package.json')));
612
594
  }
613
595
  return request;
614
596
  }
@@ -617,16 +599,17 @@ class Resolver {
617
599
  if (pkg.name.startsWith('@')) {
618
600
  levels.push('..');
619
601
  }
602
+ let originalFromFile = request.fromFile;
620
603
  let newRequest = request.rehome((0, path_1.resolve)(pkg.root, ...levels, 'moved-package-target.js'));
621
604
  if (newRequest === request) {
622
605
  return request;
623
606
  }
624
- return newRequest.withMeta({
625
- resolvedWithinPackage: pkg.root,
626
- });
607
+ // setting meta because if this fails, we want the fallback to pick up back
608
+ // in the original requesting package.
609
+ return newRequest.withMeta({ originalFromFile });
627
610
  }
628
611
  preHandleExternal(request) {
629
- if (request.isVirtual) {
612
+ if (request.isVirtual || request.isNotFound) {
630
613
  return request;
631
614
  }
632
615
  let { specifier, fromFile } = request;
@@ -659,7 +642,15 @@ class Resolver {
659
642
  // engine
660
643
  let logicalLocation = this.reverseSearchAppTree(pkg, request.fromFile);
661
644
  if (logicalLocation) {
662
- return logTransition('beforeResolve: relative import in app-js', request, request.rehome((0, path_1.resolve)(logicalLocation.owningEngine.root, logicalLocation.inAppName)));
645
+ return logTransition('beforeResolve: relative import in app-js', request, request
646
+ .alias('./' + path_1.posix.join((0, path_1.dirname)(logicalLocation.inAppName), request.specifier))
647
+ // it's important that we're rehoming this to the root of the engine
648
+ // (which we know really exists), and not to a subdir like
649
+ // logicalLocation.inAppName (which might not physically exist),
650
+ // because some environments (including node's require.resolve) will
651
+ // refuse to do resolution from a notional path that doesn't
652
+ // physically exist.
653
+ .rehome((0, path_1.resolve)(logicalLocation.owningEngine.root, 'package.json')));
663
654
  }
664
655
  return request;
665
656
  }
@@ -674,11 +665,11 @@ class Resolver {
674
665
  if (shared_internals_1.emberVirtualPeerDeps.has(packageName) && !pkg.hasDependency(packageName)) {
675
666
  // addons (whether auto-upgraded or not) may use the app's
676
667
  // emberVirtualPeerDeps, like "@glimmer/component" etc.
677
- if (!this.options.activeAddons[packageName]) {
678
- throw new Error(`${pkg.name} is trying to import the app's ${packageName} package, but it seems to be missing`);
668
+ let addon = this.locateActiveAddon(packageName);
669
+ if (!addon) {
670
+ throw new Error(`${pkg.name} is trying to import the emberVirtualPeerDep "${packageName}", but it seems to be missing`);
679
671
  }
680
- let newHome = (0, path_1.resolve)(this.packageCache.maybeMoved(this.packageCache.get(this.options.appRoot)).root, 'package.json');
681
- return logTransition(`emberVirtualPeerDeps in v2 addon`, request, request.rehome(newHome));
672
+ return logTransition(`emberVirtualPeerDeps`, request, request.rehome(addon.canResolveFromFile));
682
673
  }
683
674
  // if this file is part of an addon's app-js, it's really the logical
684
675
  // package to which it belongs (normally the app) that affects some policy
@@ -709,6 +700,22 @@ class Resolver {
709
700
  }
710
701
  return request;
711
702
  }
703
+ locateActiveAddon(packageName) {
704
+ if (packageName === this.options.modulePrefix) {
705
+ // the app itself is something that addon's can classically resolve if they know it's name.
706
+ return {
707
+ root: this.options.appRoot,
708
+ canResolveFromFile: (0, path_1.resolve)(this.packageCache.maybeMoved(this.packageCache.get(this.options.appRoot)).root, 'package.json'),
709
+ };
710
+ }
711
+ for (let engine of this.options.engines) {
712
+ for (let addon of engine.activeAddons) {
713
+ if (addon.name === packageName) {
714
+ return addon;
715
+ }
716
+ }
717
+ }
718
+ }
712
719
  external(label, request, specifier) {
713
720
  if (this.options.amdCompatibility === 'cjs') {
714
721
  let filename = (0, virtual_content_1.virtualExternalCJSModule)(specifier);
@@ -742,7 +749,7 @@ class Resolver {
742
749
  }
743
750
  }
744
751
  fallbackResolve(request) {
745
- var _a, _b, _c;
752
+ var _a;
746
753
  if (request.specifier === '@embroider/macros') {
747
754
  // the macros package is always handled directly within babel (not
748
755
  // necessarily as a real resolvable package), so we should not mess with it.
@@ -750,8 +757,7 @@ class Resolver {
750
757
  // why we need to know about it.
751
758
  return logTransition('fallback early exit', request);
752
759
  }
753
- let { specifier, fromFile } = request;
754
- if (compatPattern.test(specifier)) {
760
+ if (compatPattern.test(request.specifier)) {
755
761
  // Some kinds of compat requests get rewritten into other things
756
762
  // deterministically. For example, "#embroider_compat/helpers/whatever"
757
763
  // means only "the-current-engine/helpers/whatever", and if that doesn't
@@ -767,39 +773,33 @@ class Resolver {
767
773
  // here.
768
774
  return request;
769
775
  }
770
- if (fromFile.endsWith('moved-package-target.js')) {
771
- if (!((_a = request.meta) === null || _a === void 0 ? void 0 : _a.resolvedWithinPackage)) {
772
- throw new Error(`bug: embroider resolver's meta is not propagating`);
773
- }
774
- fromFile = (0, path_1.resolve)((_b = request.meta) === null || _b === void 0 ? void 0 : _b.resolvedWithinPackage, 'package.json');
775
- }
776
- let pkg = this.packageCache.ownerOfFile(fromFile);
776
+ let pkg = this.packageCache.ownerOfFile(request.fromFile);
777
777
  if (!pkg) {
778
778
  return logTransition('no identifiable owningPackage', request);
779
779
  }
780
- // if we rehomed this request to its un-rewritten location in order to try
781
- // to do the defaultResolve from there, now we refer back to the rewritten
782
- // location because that's what we want to use when asking things like
783
- // isV2Ember()
780
+ // meta.originalFromFile gets set when we want to try to rehome a request
781
+ // but then come back to the original location here in the fallback when the
782
+ // rehomed request fails
784
783
  let movedPkg = this.packageCache.maybeMoved(pkg);
785
784
  if (movedPkg !== pkg) {
786
- if (!((_c = request.meta) === null || _c === void 0 ? void 0 : _c.wasMovedTo)) {
785
+ let originalFromFile = (_a = request.meta) === null || _a === void 0 ? void 0 : _a.originalFromFile;
786
+ if (typeof originalFromFile !== 'string') {
787
787
  throw new Error(`bug: embroider resolver's meta is not propagating`);
788
788
  }
789
- fromFile = request.meta.wasMovedTo;
789
+ request = request.rehome(originalFromFile);
790
790
  pkg = movedPkg;
791
791
  }
792
792
  if (!pkg.isV2Ember()) {
793
793
  return logTransition('fallbackResolve: not in an ember package', request);
794
794
  }
795
- let packageName = (0, shared_internals_1.packageName)(specifier);
795
+ let packageName = (0, shared_internals_1.packageName)(request.specifier);
796
796
  if (!packageName) {
797
797
  // this is a relative import
798
798
  let withinEngine = this.engineConfig(pkg.name);
799
799
  if (withinEngine) {
800
800
  // it's a relative import inside an engine (which also means app), which
801
801
  // means we may need to satisfy the request via app tree merging.
802
- let appJSMatch = this.searchAppTree(request, withinEngine, (0, shared_internals_2.explicitRelative)(pkg.root, (0, path_1.resolve)((0, path_1.dirname)(fromFile), specifier)));
802
+ let appJSMatch = this.searchAppTree(request, withinEngine, (0, shared_internals_2.explicitRelative)(pkg.root, (0, path_1.resolve)((0, path_1.dirname)(request.fromFile), request.specifier)));
803
803
  if (appJSMatch) {
804
804
  return logTransition('fallbackResolve: relative appJsMatch', request, appJSMatch);
805
805
  }
@@ -813,23 +813,32 @@ class Resolver {
813
813
  }
814
814
  }
815
815
  // auto-upgraded packages can fall back to the set of known active addons
816
- if (pkg.meta['auto-upgraded'] && this.options.activeAddons[packageName]) {
817
- const rehomed = this.resolveWithinMovedPackage(request, this.packageCache.get(this.options.activeAddons[packageName]));
818
- if (rehomed !== request) {
819
- return logTransition(`activeAddons`, request, rehomed);
816
+ if (pkg.meta['auto-upgraded']) {
817
+ let addon = this.locateActiveAddon(packageName);
818
+ if (addon) {
819
+ const rehomed = request.rehome(addon.canResolveFromFile);
820
+ if (rehomed !== request) {
821
+ return logTransition(`activeAddons`, request, rehomed);
822
+ }
820
823
  }
821
824
  }
822
- let logicalLocation = this.reverseSearchAppTree(pkg, fromFile);
825
+ let logicalLocation = this.reverseSearchAppTree(pkg, request.fromFile);
823
826
  if (logicalLocation) {
824
827
  // the requesting file is in an addon's appTree. We didn't succeed in
825
828
  // resolving this (non-relative) request from inside the actual addon, so
826
829
  // next try to resolve it from the corresponding logical location in the
827
830
  // app.
828
- return logTransition('fallbackResolve: retry from logical home of app-js file', request, request.rehome((0, path_1.resolve)(logicalLocation.owningEngine.root, logicalLocation.inAppName)));
831
+ return logTransition('fallbackResolve: retry from logical home of app-js file', request,
832
+ // it might look more precise to rehome into logicalLocation.inAppName
833
+ // rather than package.json. But that logical location may not actually
834
+ // exist, and some systems (including node's require.resolve) will be
835
+ // mad about trying to resolve from notional paths that don't really
836
+ // exist.
837
+ request.rehome((0, path_1.resolve)(logicalLocation.owningEngine.root, 'package.json')));
829
838
  }
830
839
  let targetingEngine = this.engineConfig(packageName);
831
840
  if (targetingEngine) {
832
- let appJSMatch = this.searchAppTree(request, targetingEngine, specifier.replace(packageName, '.'));
841
+ let appJSMatch = this.searchAppTree(request, targetingEngine, request.specifier.replace(packageName, '.'));
833
842
  if (appJSMatch) {
834
843
  return logTransition('fallbackResolve: non-relative appJsMatch', request, appJSMatch);
835
844
  }
@@ -839,14 +848,14 @@ class Resolver {
839
848
  // runtime. Native v2 packages can only get this behavior in the
840
849
  // isExplicitlyExternal case above because they need to explicitly ask for
841
850
  // externals.
842
- return this.external('v1 catch-all fallback', request, specifier);
851
+ return this.external('v1 catch-all fallback', request, request.specifier);
843
852
  }
844
853
  else {
845
854
  // native v2 packages don't automatically externalize *everything* the way
846
855
  // auto-upgraded packages do, but they still externalize known and approved
847
856
  // ember virtual packages (like @ember/component)
848
857
  if (shared_internals_1.emberVirtualPackages.has(packageName)) {
849
- return this.external('emberVirtualPackages', request, specifier);
858
+ return this.external('emberVirtualPackages', request, request.specifier);
850
859
  }
851
860
  }
852
861
  // this is falling through with the original specifier which was
@@ -879,15 +888,11 @@ class Resolver {
879
888
  case undefined:
880
889
  return undefined;
881
890
  case 'app-only':
882
- return request
883
- .alias(matched.entry['app-js'].localPath)
884
- .rehome((0, path_1.resolve)(matched.entry['app-js'].packageRoot, 'package.json'));
891
+ return request.alias(matched.entry['app-js'].specifier).rehome(matched.entry['app-js'].fromFile);
885
892
  case 'fastboot-only':
886
- return request
887
- .alias(matched.entry['fastboot-js'].localPath)
888
- .rehome((0, path_1.resolve)(matched.entry['fastboot-js'].packageRoot, 'package.json'));
893
+ return request.alias(matched.entry['fastboot-js'].specifier).rehome(matched.entry['fastboot-js'].fromFile);
889
894
  case 'both':
890
- let foundAppJS = this.nodeResolve(matched.entry['app-js'].localPath, (0, path_1.resolve)(matched.entry['app-js'].packageRoot, 'package.json'));
895
+ let foundAppJS = this.nodeResolve(matched.entry['app-js'].specifier, matched.entry['app-js'].fromFile);
891
896
  if (foundAppJS.type !== 'real') {
892
897
  throw new Error(`${matched.entry['app-js'].fromPackageName} declared ${inEngineSpecifier} in packageJSON.ember-addon.app-js, but that module does not exist`);
893
898
  }