@embroider/core 3.5.1-unstable.f779011 → 3.5.1
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/package.json +9 -19
- package/src/app-files.d.ts +5 -3
- package/src/app-files.js +8 -25
- package/src/app-files.js.map +1 -1
- package/src/asset.d.ts +32 -0
- package/src/asset.js +3 -0
- package/src/asset.js.map +1 -0
- package/src/ember-html.d.ts +43 -0
- package/src/ember-html.js +110 -0
- package/src/ember-html.js.map +1 -0
- package/src/index.d.ts +5 -5
- package/src/index.js +4 -3
- package/src/index.js.map +1 -1
- package/src/measure-concat.js +2 -1
- package/src/measure-concat.js.map +1 -1
- package/src/module-resolver.d.ts +61 -24
- package/src/module-resolver.js +310 -469
- package/src/module-resolver.js.map +1 -1
- package/src/node-resolve.d.ts +6 -31
- package/src/node-resolve.js +45 -112
- package/src/node-resolve.js.map +1 -1
- package/src/options.d.ts +7 -0
- package/src/options.js +1 -0
- package/src/options.js.map +1 -1
- package/src/packager.d.ts +8 -0
- package/src/packager.js +9 -0
- package/src/packager.js.map +1 -1
- package/src/portable-babel-config.d.ts +11 -0
- package/src/portable-babel-config.js +132 -0
- package/src/portable-babel-config.js.map +1 -0
- package/src/portable-babel-launcher.d.ts +6 -0
- package/src/portable-babel-launcher.js +75 -0
- package/src/portable-babel-launcher.js.map +1 -0
- package/src/resolver-loader.js +1 -8
- package/src/resolver-loader.js.map +1 -1
- package/src/to-broccoli-plugin.d.ts +8 -0
- package/src/to-broccoli-plugin.js +30 -0
- package/src/to-broccoli-plugin.js.map +1 -0
- package/src/virtual-content.d.ts +12 -32
- package/src/virtual-content.js +184 -83
- package/src/virtual-content.js.map +1 -1
- package/src/module-request.d.ts +0 -44
- package/src/module-request.js +0 -100
- package/src/module-request.js.map +0 -1
- package/src/module-resolver-options.d.ts +0 -42
- package/src/module-resolver-options.js +0 -164
- package/src/module-resolver-options.js.map +0 -1
- package/src/virtual-entrypoint.d.ts +0 -21
- package/src/virtual-entrypoint.js +0 -273
- package/src/virtual-entrypoint.js.map +0 -1
- package/src/virtual-route-entrypoint.d.ts +0 -10
- package/src/virtual-route-entrypoint.js +0 -62
- package/src/virtual-route-entrypoint.js.map +0 -1
- package/src/virtual-test-support-styles.d.ts +0 -7
- package/src/virtual-test-support-styles.js +0 -61
- package/src/virtual-test-support-styles.js.map +0 -1
- package/src/virtual-test-support.d.ts +0 -7
- package/src/virtual-test-support.js +0 -65
- package/src/virtual-test-support.js.map +0 -1
- package/src/virtual-vendor-styles.d.ts +0 -8
- package/src/virtual-vendor-styles.js +0 -83
- package/src/virtual-vendor-styles.js.map +0 -1
- package/src/virtual-vendor.d.ts +0 -7
- package/src/virtual-vendor.js +0 -53
- package/src/virtual-vendor.js.map +0 -1
- package/types/virtual/index.d.ts +0 -9
- package/types/virtual/index.js +0 -3
package/src/module-resolver.js
CHANGED
@@ -15,51 +15,64 @@ 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
|
19
|
-
const resolve_exports_1 = require("resolve.exports");
|
18
|
+
const virtual_content_1 = require("./virtual-content");
|
20
19
|
const typescript_memoize_1 = require("typescript-memoize");
|
21
20
|
const describe_exports_1 = require("./describe-exports");
|
22
21
|
const fs_1 = require("fs");
|
23
|
-
const node_resolve_1 = require("./node-resolve");
|
24
22
|
const semver_1 = require("semver");
|
25
|
-
const
|
23
|
+
const node_resolve_1 = require("./node-resolve");
|
26
24
|
const debug = (0, debug_1.default)('embroider:resolver');
|
27
|
-
// Using a formatter makes this work lazy so nothing happens when we aren't
|
28
|
-
// logging. It is unfortunate that formatters are a globally mutable config and
|
29
|
-
// you can only use single character names, but oh well.
|
30
|
-
debug_1.default.formatters.p = (s) => {
|
31
|
-
let cwd = process.cwd();
|
32
|
-
if (s.startsWith(cwd)) {
|
33
|
-
return s.slice(cwd.length + 1);
|
34
|
-
}
|
35
|
-
return s;
|
36
|
-
};
|
37
25
|
function logTransition(reason, before, after = before) {
|
38
|
-
if (after.
|
39
|
-
debug(`
|
26
|
+
if (after.isVirtual) {
|
27
|
+
debug(`virtualized %s in %s because %s`, before.specifier, before.fromFile, reason);
|
40
28
|
}
|
41
29
|
else if (before.specifier !== after.specifier) {
|
42
30
|
if (before.fromFile !== after.fromFile) {
|
43
|
-
debug(`
|
31
|
+
debug(`aliased and rehomed: %s to %s, from %s to %s because %s`, before.specifier, after.specifier, before.fromFile, after.fromFile, reason);
|
44
32
|
}
|
45
33
|
else {
|
46
|
-
debug(`
|
34
|
+
debug(`aliased: %s to %s in %s because`, before.specifier, after.specifier, before.fromFile, reason);
|
47
35
|
}
|
48
36
|
}
|
49
37
|
else if (before.fromFile !== after.fromFile) {
|
50
|
-
debug(`
|
38
|
+
debug(`rehomed: %s from %s to %s because`, before.specifier, before.fromFile, after.fromFile, reason);
|
51
39
|
}
|
52
40
|
else {
|
53
|
-
debug(`
|
41
|
+
debug(`unchanged: %s in %s because %s`, before.specifier, before.fromFile, reason);
|
54
42
|
}
|
55
43
|
return after;
|
56
44
|
}
|
57
|
-
const compatPattern =
|
45
|
+
const compatPattern = /#embroider_compat\/(?<type>[^\/]+)\/(?<rest>.*)/;
|
46
|
+
class NodeModuleRequest {
|
47
|
+
constructor(specifier, fromFile, isVirtual, meta) {
|
48
|
+
this.specifier = specifier;
|
49
|
+
this.fromFile = fromFile;
|
50
|
+
this.isVirtual = isVirtual;
|
51
|
+
this.meta = meta;
|
52
|
+
}
|
53
|
+
alias(specifier) {
|
54
|
+
return new NodeModuleRequest(specifier, this.fromFile, false, this.meta);
|
55
|
+
}
|
56
|
+
rehome(fromFile) {
|
57
|
+
if (this.fromFile === fromFile) {
|
58
|
+
return this;
|
59
|
+
}
|
60
|
+
else {
|
61
|
+
return new NodeModuleRequest(this.specifier, fromFile, false, this.meta);
|
62
|
+
}
|
63
|
+
}
|
64
|
+
virtualize(filename) {
|
65
|
+
return new NodeModuleRequest(filename, this.fromFile, true, this.meta);
|
66
|
+
}
|
67
|
+
withMeta(meta) {
|
68
|
+
return new NodeModuleRequest(this.specifier, this.fromFile, this.isVirtual, meta);
|
69
|
+
}
|
70
|
+
}
|
58
71
|
class Resolver {
|
59
72
|
constructor(options) {
|
60
73
|
this.options = options;
|
61
74
|
}
|
62
|
-
|
75
|
+
beforeResolve(request) {
|
63
76
|
if (request.specifier === '@embroider/macros') {
|
64
77
|
// the macros package is always handled directly within babel (not
|
65
78
|
// necessarily as a real resolvable package), so we should not mess with it.
|
@@ -68,15 +81,9 @@ class Resolver {
|
|
68
81
|
return logTransition('early exit', request);
|
69
82
|
}
|
70
83
|
request = this.handleFastbootSwitch(request);
|
71
|
-
request =
|
84
|
+
request = this.handleGlobalsCompat(request);
|
72
85
|
request = this.handleImplicitModules(request);
|
73
|
-
request = this.handleImplicitTestScripts(request);
|
74
|
-
request = this.handleVendorStyles(request);
|
75
|
-
request = this.handleTestSupportStyles(request);
|
76
|
-
request = this.handleEntrypoint(request);
|
77
|
-
request = this.handleRouteEntrypoint(request);
|
78
86
|
request = this.handleRenaming(request);
|
79
|
-
request = this.handleVendor(request);
|
80
87
|
// we expect the specifier to be app relative at this point - must be after handleRenaming
|
81
88
|
request = this.generateFastbootSwitch(request);
|
82
89
|
request = this.preHandleExternal(request);
|
@@ -90,16 +97,34 @@ class Resolver {
|
|
90
97
|
// that calls your build system's normal module resolver, this does both pre-
|
91
98
|
// and post-resolution adjustments as needed to implement our compatibility
|
92
99
|
// rules.
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
100
|
+
//
|
101
|
+
// Depending on the plugin architecture you're working in, it may be easier to
|
102
|
+
// call beforeResolve and fallbackResolve directly, in which case matching the
|
103
|
+
// details of the recursion to what this method does are your responsibility.
|
104
|
+
async resolve(request, defaultResolve) {
|
105
|
+
let gen = this.internalResolve(request, defaultResolve);
|
106
|
+
let out = gen.next();
|
107
|
+
while (!out.done) {
|
108
|
+
out = gen.next(await out.value);
|
109
|
+
}
|
110
|
+
return out.value;
|
111
|
+
}
|
112
|
+
// synchronous alternative to resolve() above. Because our own internals are
|
113
|
+
// all synchronous, you can use this if your defaultResolve function is
|
114
|
+
// synchronous.
|
115
|
+
resolveSync(request, defaultResolve) {
|
116
|
+
let gen = this.internalResolve(request, defaultResolve);
|
117
|
+
let out = gen.next();
|
118
|
+
while (!out.done) {
|
119
|
+
out = gen.next(out.value);
|
120
|
+
}
|
121
|
+
return out.value;
|
122
|
+
}
|
123
|
+
// Our core implementation is a generator so it can power both resolve() and
|
124
|
+
// resolveSync()
|
125
|
+
*internalResolve(request, defaultResolve) {
|
126
|
+
request = this.beforeResolve(request);
|
127
|
+
let resolution = yield defaultResolve(request);
|
103
128
|
switch (resolution.type) {
|
104
129
|
case 'found':
|
105
130
|
return resolution;
|
@@ -108,57 +133,51 @@ class Resolver {
|
|
108
133
|
default:
|
109
134
|
throw (0, assert_never_1.default)(resolution);
|
110
135
|
}
|
111
|
-
|
112
|
-
let nextRequest = await this.fallbackResolve(request);
|
136
|
+
let nextRequest = this.fallbackResolve(request);
|
113
137
|
if (nextRequest === request) {
|
114
138
|
// no additional fallback is available.
|
115
139
|
return resolution;
|
116
140
|
}
|
117
|
-
if (nextRequest.resolvedTo) {
|
118
|
-
return await (0, module_request_1.extractResolution)(nextRequest.resolvedTo);
|
119
|
-
}
|
120
141
|
if (nextRequest.fromFile === request.fromFile && nextRequest.specifier === request.specifier) {
|
121
142
|
throw new Error('Bug Discovered! New request is not === original request but has the same fromFile and specifier. This will likely create a loop.');
|
122
143
|
}
|
123
|
-
|
144
|
+
if (nextRequest.isVirtual) {
|
145
|
+
// virtual requests are terminal, there is no more beforeResolve or
|
146
|
+
// fallbackResolve around them. The defaultResolve is expected to know how
|
147
|
+
// to implement them.
|
148
|
+
return yield defaultResolve(nextRequest);
|
149
|
+
}
|
150
|
+
return yield* this.internalResolve(nextRequest, defaultResolve);
|
124
151
|
}
|
125
152
|
// Use standard NodeJS resolving, with our required compatibility rules on
|
126
153
|
// top. This is a convenience method for calling resolveSync with the
|
127
154
|
// defaultResolve already configured to be "do the normal node thing".
|
128
|
-
|
129
|
-
|
155
|
+
nodeResolve(specifier, fromFile) {
|
156
|
+
let resolution = this.resolveSync(new NodeModuleRequest(specifier, fromFile, false, undefined), request => {
|
157
|
+
if (request.isVirtual) {
|
158
|
+
return {
|
159
|
+
type: 'found',
|
160
|
+
result: {
|
161
|
+
type: 'virtual',
|
162
|
+
content: (0, virtual_content_1.virtualContent)(request.specifier, this),
|
163
|
+
filename: request.specifier,
|
164
|
+
},
|
165
|
+
};
|
166
|
+
}
|
167
|
+
return (0, node_resolve_1.resolve)(request.specifier, request.fromFile);
|
168
|
+
});
|
169
|
+
switch (resolution.type) {
|
170
|
+
case 'not_found':
|
171
|
+
return resolution;
|
172
|
+
case 'found':
|
173
|
+
return resolution.result;
|
174
|
+
default:
|
175
|
+
throw (0, assert_never_1.default)(resolution);
|
176
|
+
}
|
130
177
|
}
|
131
178
|
get packageCache() {
|
132
179
|
return shared_internals_2.RewrittenPackageCache.shared('embroider', this.options.appRoot);
|
133
180
|
}
|
134
|
-
async afterResolve(request, resolution) {
|
135
|
-
resolution = await this.handleSyntheticComponents(request, resolution);
|
136
|
-
return resolution;
|
137
|
-
}
|
138
|
-
async handleSyntheticComponents(request, resolution) {
|
139
|
-
// Key assumption: the system's defaultResolve performs extension search for
|
140
|
-
// extensionless requests, with JS at a higher priority than HBS.
|
141
|
-
// When the request had an explicit ".js" extension, the system default
|
142
|
-
// extension search doesn't help us locate an HBS, so we need to check for
|
143
|
-
// it ourselves here.
|
144
|
-
if (resolution.type === 'not_found') {
|
145
|
-
let hbsSpecifier = (0, shared_internals_1.syntheticJStoHBS)(request.specifier);
|
146
|
-
if (hbsSpecifier) {
|
147
|
-
resolution = await this.resolve(request.alias(hbsSpecifier));
|
148
|
-
}
|
149
|
-
}
|
150
|
-
// At this point, we might have resolved an HBS file (either because the
|
151
|
-
// request was extensionless and the default search found it, or because of
|
152
|
-
// our own code above) when the request was for a JS file.
|
153
|
-
if (resolution.type === 'found') {
|
154
|
-
let syntheticId = (0, shared_internals_1.needsSyntheticComponentJS)(request.specifier, resolution.filename);
|
155
|
-
if (syntheticId && (0, shared_internals_1.isInComponents)(resolution.filename, this.packageCache)) {
|
156
|
-
let newRequest = logTransition(`synthetic component JS`, request, request.virtualize({ type: 'template-only-component-js', specifier: syntheticId }));
|
157
|
-
return await (0, module_request_1.extractResolution)(newRequest.resolvedTo);
|
158
|
-
}
|
159
|
-
}
|
160
|
-
return resolution;
|
161
|
-
}
|
162
181
|
logicalPackage(owningPackage, file) {
|
163
182
|
let logicalLocation = this.reverseSearchAppTree(owningPackage, file);
|
164
183
|
if (logicalLocation) {
|
@@ -171,9 +190,6 @@ class Resolver {
|
|
171
190
|
return owningPackage;
|
172
191
|
}
|
173
192
|
generateFastbootSwitch(request) {
|
174
|
-
if (request.resolvedTo) {
|
175
|
-
return request;
|
176
|
-
}
|
177
193
|
let pkg = this.packageCache.ownerOfFile(request.fromFile);
|
178
194
|
if (!pkg) {
|
179
195
|
return request;
|
@@ -191,11 +207,9 @@ class Resolver {
|
|
191
207
|
let fastbootFile = engineConfig.fastbootFiles[candidate];
|
192
208
|
if (fastbootFile) {
|
193
209
|
if (fastbootFile.shadowedFilename) {
|
194
|
-
let { names } = (0, describe_exports_1.describeExports)((0, fs_1.readFileSync)((0, path_1.resolve)(pkg.root, fastbootFile.shadowedFilename), 'utf8'), {
|
195
|
-
|
196
|
-
|
197
|
-
let switchFile = fastbootSwitch(candidate, (0, path_1.resolve)(pkg.root, 'package.json'), names);
|
198
|
-
if (switchFile.specifier === request.fromFile) {
|
210
|
+
let { names } = (0, describe_exports_1.describeExports)((0, fs_1.readFileSync)((0, path_1.resolve)(pkg.root, fastbootFile.shadowedFilename), 'utf8'), {});
|
211
|
+
let switchFile = (0, virtual_content_1.fastbootSwitch)(candidate, (0, path_1.resolve)(pkg.root, 'package.json'), names);
|
212
|
+
if (switchFile === request.fromFile) {
|
199
213
|
return logTransition('internal lookup from fastbootSwitch', request);
|
200
214
|
}
|
201
215
|
else {
|
@@ -212,10 +226,7 @@ class Resolver {
|
|
212
226
|
}
|
213
227
|
handleFastbootSwitch(request) {
|
214
228
|
var _a;
|
215
|
-
|
216
|
-
return request;
|
217
|
-
}
|
218
|
-
let match = decodeFastbootSwitch(request.fromFile);
|
229
|
+
let match = (0, virtual_content_1.decodeFastbootSwitch)(request.fromFile);
|
219
230
|
if (!match) {
|
220
231
|
return request;
|
221
232
|
}
|
@@ -253,122 +264,30 @@ class Resolver {
|
|
253
264
|
}
|
254
265
|
let entry = (_a = this.getEntryFromMergeMap(rel, pkg.root)) === null || _a === void 0 ? void 0 : _a.entry;
|
255
266
|
if ((entry === null || entry === void 0 ? void 0 : entry.type) === 'both') {
|
256
|
-
return logTransition('matched addon entry', request, request.alias(entry[section].
|
267
|
+
return logTransition('matched addon entry', request, request.alias(entry[section].localPath).rehome((0, path_1.resolve)(entry[section].packageRoot, 'package.json')));
|
257
268
|
}
|
258
269
|
}
|
259
270
|
return logTransition('failed to match in fastboot switch', request);
|
260
271
|
}
|
261
272
|
handleImplicitModules(request) {
|
262
|
-
|
273
|
+
let im = (0, virtual_content_1.decodeImplicitModules)(request.specifier);
|
274
|
+
if (!im) {
|
263
275
|
return request;
|
264
276
|
}
|
265
|
-
for (let variant of ['', 'test-']) {
|
266
|
-
let suffix = `-embroider-implicit-${variant}modules.js`;
|
267
|
-
if (!request.specifier.endsWith(suffix)) {
|
268
|
-
continue;
|
269
|
-
}
|
270
|
-
let filename = request.specifier.slice(0, -1 * suffix.length);
|
271
|
-
if (!filename.endsWith('/') && filename.endsWith('\\')) {
|
272
|
-
continue;
|
273
|
-
}
|
274
|
-
filename = filename.slice(0, -1);
|
275
|
-
let pkg = this.packageCache.ownerOfFile(request.fromFile);
|
276
|
-
if (!(pkg === null || pkg === void 0 ? void 0 : pkg.isV2Ember())) {
|
277
|
-
throw new Error(`bug: found implicit modules import in non-ember package at ${request.fromFile}`);
|
278
|
-
}
|
279
|
-
let type = `implicit-${variant}modules`;
|
280
|
-
let packageName = (0, shared_internals_1.packageName)(filename);
|
281
|
-
if (packageName) {
|
282
|
-
let dep = this.packageCache.resolve(packageName, pkg);
|
283
|
-
return logTransition(`dep's implicit modules`, request, request.virtualize({ type, specifier: (0, path_1.resolve)(dep.root, `-embroider-${type}.js`), fromFile: dep.root }));
|
284
|
-
}
|
285
|
-
else {
|
286
|
-
return logTransition(`own implicit modules`, request, request.virtualize({ type, specifier: (0, path_1.resolve)(pkg.root, `-embroider-${type}.js`), fromFile: pkg.root }));
|
287
|
-
}
|
288
|
-
}
|
289
|
-
return request;
|
290
|
-
}
|
291
|
-
handleEntrypoint(request) {
|
292
|
-
var _a;
|
293
|
-
if (request.resolvedTo) {
|
294
|
-
return request;
|
295
|
-
}
|
296
|
-
const compatModulesSpecifier = '@embroider/virtual/compat-modules';
|
297
|
-
let isCompatModules = request.specifier === compatModulesSpecifier || request.specifier.startsWith(compatModulesSpecifier + '/');
|
298
|
-
if (!isCompatModules) {
|
299
|
-
return request;
|
300
|
-
}
|
301
|
-
const requestingPkg = this.packageCache.ownerOfFile(request.fromFile);
|
302
|
-
if (!(requestingPkg === null || requestingPkg === void 0 ? void 0 : requestingPkg.isV2Ember())) {
|
303
|
-
throw new Error(`bug: found entrypoint import in non-ember package at ${request.fromFile}`);
|
304
|
-
}
|
305
|
-
let pkg;
|
306
|
-
if (request.specifier === compatModulesSpecifier) {
|
307
|
-
pkg = requestingPkg;
|
308
|
-
}
|
309
|
-
else {
|
310
|
-
let packageName = request.specifier.slice(compatModulesSpecifier.length + 1);
|
311
|
-
pkg = this.packageCache.resolve(packageName, requestingPkg);
|
312
|
-
}
|
313
|
-
let matched = (0, resolve_exports_1.exports)(pkg.packageJSON, '-embroider-entrypoint.js', {
|
314
|
-
browser: true,
|
315
|
-
conditions: ['default', 'imports'],
|
316
|
-
});
|
317
|
-
let specifier = (0, path_1.resolve)(pkg.root, (_a = matched === null || matched === void 0 ? void 0 : matched[0]) !== null && _a !== void 0 ? _a : '-embroider-entrypoint.js');
|
318
|
-
return logTransition('entrypoint', request, request.virtualize({
|
319
|
-
type: 'entrypoint',
|
320
|
-
specifier,
|
321
|
-
fromDir: (0, path_1.dirname)(specifier),
|
322
|
-
}));
|
323
|
-
}
|
324
|
-
handleRouteEntrypoint(request) {
|
325
|
-
if (request.resolvedTo) {
|
326
|
-
return request;
|
327
|
-
}
|
328
|
-
const publicPrefix = '@embroider/core/route/';
|
329
|
-
if (!request.specifier.startsWith(publicPrefix)) {
|
330
|
-
return request;
|
331
|
-
}
|
332
|
-
let routeName = request.specifier.slice(publicPrefix.length);
|
333
277
|
let pkg = this.packageCache.ownerOfFile(request.fromFile);
|
334
278
|
if (!(pkg === null || pkg === void 0 ? void 0 : pkg.isV2Ember())) {
|
335
|
-
throw new Error(`bug: found
|
279
|
+
throw new Error(`bug: found implicit modules import in non-ember package at ${request.fromFile}`);
|
336
280
|
}
|
337
|
-
let
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
let target = matched ? `${matched}:route=${routeName}` : `-embroider-route-entrypoint.js:route=${routeName}`;
|
342
|
-
let specifier = (0, path_1.resolve)(pkg.root, target);
|
343
|
-
return logTransition('route entrypoint', request, request.virtualize({ type: 'route-entrypoint', specifier, route: routeName, fromDir: (0, path_1.dirname)(specifier) }));
|
344
|
-
}
|
345
|
-
handleImplicitTestScripts(request) {
|
346
|
-
if (request.specifier !== '@embroider/virtual/test-support.js') {
|
347
|
-
return request;
|
281
|
+
let packageName = (0, shared_internals_1.packageName)(im.fromFile);
|
282
|
+
if (packageName) {
|
283
|
+
let dep = this.packageCache.resolve(packageName, pkg);
|
284
|
+
return logTransition(`dep's implicit modules`, request, request.virtualize((0, path_1.resolve)(dep.root, `-embroider-${im.type}.js`)));
|
348
285
|
}
|
349
|
-
|
350
|
-
|
351
|
-
throw new Error(`bug: found an import of ${request.specifier} in ${request.fromFile}, but this is not the top-level Ember app. The top-level Ember app is the only one that has support for @embroider/virtual/test-support.js. If you think something should be fixed in Embroider, please open an issue on https://github.com/embroider-build/embroider/issues.`);
|
352
|
-
}
|
353
|
-
return logTransition('test-support', request, request.virtualize({ type: 'test-support-js', specifier: (0, path_1.resolve)(pkg.root, '-embroider-test-support.js') }));
|
354
|
-
}
|
355
|
-
handleTestSupportStyles(request) {
|
356
|
-
if (request.specifier !== '@embroider/virtual/test-support.css') {
|
357
|
-
return request;
|
358
|
-
}
|
359
|
-
let pkg = this.packageCache.ownerOfFile(request.fromFile);
|
360
|
-
if ((pkg === null || pkg === void 0 ? void 0 : pkg.root) !== this.options.engines[0].root) {
|
361
|
-
throw new Error(`bug: found an import of ${request.specifier} in ${request.fromFile}, but this is not the top-level Ember app. The top-level Ember app is the only one that has support for @embroider/virtual/test-support.css. If you think something should be fixed in Embroider, please open an issue on https://github.com/embroider-build/embroider/issues.`);
|
286
|
+
else {
|
287
|
+
return logTransition(`own implicit modules`, request, request.virtualize((0, path_1.resolve)(pkg.root, `-embroider-${im.type}.js`)));
|
362
288
|
}
|
363
|
-
return logTransition('test-support-styles', request, request.virtualize({
|
364
|
-
type: 'test-support-css',
|
365
|
-
specifier: (0, path_1.resolve)(pkg.root, '-embroider-test-support-styles.css'),
|
366
|
-
}));
|
367
289
|
}
|
368
|
-
|
369
|
-
if (request.resolvedTo) {
|
370
|
-
return request;
|
371
|
-
}
|
290
|
+
handleGlobalsCompat(request) {
|
372
291
|
let match = compatPattern.exec(request.specifier);
|
373
292
|
if (!match) {
|
374
293
|
return request;
|
@@ -389,81 +308,62 @@ class Resolver {
|
|
389
308
|
case 'ambiguous':
|
390
309
|
return this.resolveHelperOrComponent(rest, engine, request);
|
391
310
|
default:
|
392
|
-
throw new Error(`bug: unexepected
|
393
|
-
}
|
394
|
-
}
|
395
|
-
handleVendorStyles(request) {
|
396
|
-
if (request.specifier !== '@embroider/virtual/vendor.css') {
|
397
|
-
return request;
|
398
|
-
}
|
399
|
-
let pkg = this.packageCache.ownerOfFile(request.fromFile);
|
400
|
-
if (!pkg || !this.options.engines.some(e => e.root === (pkg === null || pkg === void 0 ? void 0 : pkg.root))) {
|
401
|
-
throw new Error(`bug: found an import of ${request.specifier} in ${request.fromFile}, but this is not the top-level Ember app or Engine. The top-level Ember app is the only one that has support for @embroider/virtual/vendor.css. If you think something should be fixed in Embroider, please open an issue on https://github.com/embroider-build/embroider/issues.`);
|
311
|
+
throw new Error(`bug: unexepected #embroider_compat specifier: ${request.specifier}`);
|
402
312
|
}
|
403
|
-
return logTransition('vendor-styles', request, request.virtualize({ type: 'vendor-css', specifier: (0, path_1.resolve)(pkg.root, '-embroider-vendor-styles.css') }));
|
404
313
|
}
|
405
314
|
resolveHelper(path, inEngine, request) {
|
406
315
|
let target = this.parseGlobalPath(path, inEngine);
|
407
316
|
return logTransition('resolveHelper', request, request.alias(`${target.packageName}/helpers/${target.memberName}`).rehome((0, path_1.resolve)(inEngine.root, 'package.json')));
|
408
317
|
}
|
409
|
-
|
410
|
-
var _a, _b;
|
318
|
+
resolveComponent(path, inEngine, request) {
|
411
319
|
let target = this.parseGlobalPath(path, inEngine);
|
412
320
|
let hbsModule = null;
|
413
321
|
let jsModule = null;
|
414
322
|
// first, the various places our template might be.
|
415
323
|
for (let candidate of this.componentTemplateCandidates(target.packageName)) {
|
416
|
-
let
|
417
|
-
|
418
|
-
|
419
|
-
hbsModule = resolution;
|
324
|
+
let resolution = this.nodeResolve(`${target.packageName}${candidate.prefix}${target.memberName}${candidate.suffix}`, target.from);
|
325
|
+
if (resolution.type === 'real') {
|
326
|
+
hbsModule = resolution.filename;
|
420
327
|
break;
|
421
328
|
}
|
422
329
|
}
|
423
330
|
// then the various places our javascript might be.
|
424
331
|
for (let candidate of this.componentJSCandidates(target.packageName)) {
|
425
|
-
let
|
426
|
-
let resolution = await this.resolve(request.alias(candidateSpecifier).rehome(target.from));
|
332
|
+
let resolution = this.nodeResolve(`${target.packageName}${candidate.prefix}${target.memberName}${candidate.suffix}`, target.from);
|
427
333
|
// .hbs is a resolvable extension for us, so we need to exclude it here.
|
428
334
|
// It matches as a priority lower than .js, so finding an .hbs means
|
429
335
|
// there's definitely not a .js.
|
430
|
-
if (resolution.type === '
|
431
|
-
jsModule = resolution;
|
336
|
+
if (resolution.type === 'real' && !resolution.filename.endsWith('.hbs')) {
|
337
|
+
jsModule = resolution.filename;
|
432
338
|
break;
|
433
339
|
}
|
434
340
|
}
|
435
341
|
if (hbsModule) {
|
436
342
|
if (!this.emberVersionSupportsSeparateTemplates) {
|
437
|
-
throw new Error(`Components with separately resolved templates were removed at Ember 6.0. Migrate to either co-located js/ts + hbs files or to gjs/gts. https://deprecations.emberjs.com/id/component-template-resolving/. Bad template was: ${hbsModule
|
343
|
+
throw new Error(`Components with separately resolved templates were removed at Ember 6.0. Migrate to either co-located js/ts + hbs files or to gjs/gts. https://deprecations.emberjs.com/id/component-template-resolving/. Bad template was: ${hbsModule}.`);
|
438
344
|
}
|
439
|
-
return logTransition(`resolveComponent found legacy HBS`, request, request.virtualize(
|
440
|
-
type: 'component-pair',
|
441
|
-
hbsModule: hbsModule.filename,
|
442
|
-
jsModule: (_a = jsModule === null || jsModule === void 0 ? void 0 : jsModule.filename) !== null && _a !== void 0 ? _a : null,
|
443
|
-
debugName: (0, path_1.basename)(hbsModule.filename).replace(/\.(js|hbs)$/, ''),
|
444
|
-
specifier: `${this.options.appRoot}/embroider-pair-component/${encodeURIComponent(hbsModule.filename)}/__vpc__/${encodeURIComponent((_b = jsModule === null || jsModule === void 0 ? void 0 : jsModule.filename) !== null && _b !== void 0 ? _b : '')}`,
|
445
|
-
}));
|
345
|
+
return logTransition(`resolveComponent found legacy HBS`, request, request.virtualize((0, virtual_content_1.virtualPairComponent)(hbsModule, jsModule)));
|
446
346
|
}
|
447
347
|
else if (jsModule) {
|
448
|
-
return logTransition(`
|
348
|
+
return logTransition(`resolveComponent found only JS`, request, request.alias(jsModule).rehome(target.from));
|
449
349
|
}
|
450
350
|
else {
|
451
351
|
return logTransition(`resolveComponent failed`, request);
|
452
352
|
}
|
453
353
|
}
|
454
|
-
|
354
|
+
resolveHelperOrComponent(path, inEngine, request) {
|
455
355
|
// resolveHelper just rewrites our request to one that should target the
|
456
356
|
// component, so here to resolve the ambiguity we need to actually resolve
|
457
357
|
// that candidate to see if it works.
|
458
358
|
let helperCandidate = this.resolveHelper(path, inEngine, request);
|
459
|
-
let helperMatch =
|
460
|
-
if (helperMatch.type === '
|
461
|
-
return logTransition('
|
359
|
+
let helperMatch = this.nodeResolve(helperCandidate.specifier, helperCandidate.fromFile);
|
360
|
+
if (helperMatch.type === 'real') {
|
361
|
+
return logTransition('ambiguous case matched a helper', request, helperCandidate);
|
462
362
|
}
|
463
363
|
// unlike resolveHelper, resolveComponent already does pre-resolution in
|
464
364
|
// order to deal with its own internal ambiguity around JS vs HBS vs
|
465
365
|
// colocation.≥
|
466
|
-
let componentMatch =
|
366
|
+
let componentMatch = this.resolveComponent(path, inEngine, request);
|
467
367
|
if (componentMatch !== request) {
|
468
368
|
return logTransition('ambiguous case matched a cmoponent', request, componentMatch);
|
469
369
|
}
|
@@ -488,7 +388,6 @@ class Resolver {
|
|
488
388
|
}
|
489
389
|
*componentJSCandidates(inPackageName) {
|
490
390
|
yield { prefix: '/components/', suffix: '' };
|
491
|
-
yield { prefix: '/components/', suffix: '/index' };
|
492
391
|
yield { prefix: '/components/', suffix: '/component' };
|
493
392
|
let pods = this.podPrefix(inPackageName);
|
494
393
|
if (pods) {
|
@@ -507,10 +406,10 @@ class Resolver {
|
|
507
406
|
parseGlobalPath(path, inEngine) {
|
508
407
|
let parts = path.split('@');
|
509
408
|
if (parts.length > 1 && parts[0].length > 0) {
|
510
|
-
return { packageName: parts[0], memberName: parts[1], from: (0, path_1.resolve)(inEngine.root, '
|
409
|
+
return { packageName: parts[0], memberName: parts[1], from: (0, path_1.resolve)(inEngine.root, 'pacakge.json') };
|
511
410
|
}
|
512
411
|
else {
|
513
|
-
return { packageName: inEngine.packageName, memberName: path, from: (0, path_1.resolve)(inEngine.root, '
|
412
|
+
return { packageName: inEngine.packageName, memberName: path, from: (0, path_1.resolve)(inEngine.root, 'pacakge.json') };
|
514
413
|
}
|
515
414
|
}
|
516
415
|
engineConfig(packageName) {
|
@@ -536,18 +435,14 @@ class Resolver {
|
|
536
435
|
if (!inAddonName.startsWith('./')) {
|
537
436
|
throw new Error(`addon ${addon.name} declares app-js in its package.json with the illegal name "${inAddonName}". It must start with "./" to make it clear that it's relative to the addon`);
|
538
437
|
}
|
539
|
-
let specifier = (0, reverse_exports_1.externalName)(addon.packageJSON, inAddonName);
|
540
|
-
if (!specifier) {
|
541
|
-
throw new Error(`${addon.name}'s package.json app-js refers to ${inAddonName}, but that module is not accessible from outside the package`);
|
542
|
-
}
|
543
438
|
let prevEntry = engineModules.get(inEngineName);
|
544
439
|
switch (prevEntry === null || prevEntry === void 0 ? void 0 : prevEntry.type) {
|
545
440
|
case undefined:
|
546
441
|
engineModules.set(inEngineName, {
|
547
442
|
type: 'app-only',
|
548
443
|
'app-js': {
|
549
|
-
|
550
|
-
|
444
|
+
localPath: inAddonName,
|
445
|
+
packageRoot: addon.root,
|
551
446
|
fromPackageName: addon.name,
|
552
447
|
},
|
553
448
|
});
|
@@ -560,8 +455,8 @@ class Resolver {
|
|
560
455
|
engineModules.set(inEngineName, {
|
561
456
|
type: 'both',
|
562
457
|
'app-js': {
|
563
|
-
|
564
|
-
|
458
|
+
localPath: inAddonName,
|
459
|
+
packageRoot: addon.root,
|
565
460
|
fromPackageName: addon.name,
|
566
461
|
},
|
567
462
|
'fastboot-js': prevEntry['fastboot-js'],
|
@@ -579,18 +474,14 @@ class Resolver {
|
|
579
474
|
if (!inAddonName.startsWith('./')) {
|
580
475
|
throw new Error(`addon ${addon.name} declares fastboot-js in its package.json with the illegal name "${inAddonName}". It must start with "./" to make it clear that it's relative to the addon`);
|
581
476
|
}
|
582
|
-
let specifier = (0, reverse_exports_1.externalName)(addon.packageJSON, inAddonName);
|
583
|
-
if (!specifier) {
|
584
|
-
throw new Error(`${addon.name}'s package.json fastboot-js refers to ${inAddonName}, but that module is not accessible from outside the package`);
|
585
|
-
}
|
586
477
|
let prevEntry = engineModules.get(inEngineName);
|
587
478
|
switch (prevEntry === null || prevEntry === void 0 ? void 0 : prevEntry.type) {
|
588
479
|
case undefined:
|
589
480
|
engineModules.set(inEngineName, {
|
590
481
|
type: 'fastboot-only',
|
591
482
|
'fastboot-js': {
|
592
|
-
|
593
|
-
|
483
|
+
localPath: inAddonName,
|
484
|
+
packageRoot: addon.root,
|
594
485
|
fromPackageName: addon.name,
|
595
486
|
},
|
596
487
|
});
|
@@ -603,8 +494,8 @@ class Resolver {
|
|
603
494
|
engineModules.set(inEngineName, {
|
604
495
|
type: 'both',
|
605
496
|
'fastboot-js': {
|
606
|
-
|
607
|
-
|
497
|
+
localPath: inAddonName,
|
498
|
+
packageRoot: addon.root,
|
608
499
|
fromPackageName: addon.name,
|
609
500
|
},
|
610
501
|
'app-js': prevEntry['app-js'],
|
@@ -635,7 +526,7 @@ class Resolver {
|
|
635
526
|
});
|
636
527
|
}
|
637
528
|
handleRewrittenPackages(request) {
|
638
|
-
if (request.
|
529
|
+
if (request.isVirtual) {
|
639
530
|
return request;
|
640
531
|
}
|
641
532
|
let requestingPkg = this.packageCache.ownerOfFile(request.fromFile);
|
@@ -654,6 +545,10 @@ class Resolver {
|
|
654
545
|
targetPkg = this.packageCache.resolve(packageName, requestingPkg);
|
655
546
|
}
|
656
547
|
catch (err) {
|
548
|
+
// this is not the place to report resolution failures. If the thing
|
549
|
+
// doesn't resolve, we're just not interested in redirecting it for
|
550
|
+
// backward-compat, that's all. The rest of the system will take care of
|
551
|
+
// reporting a failure to resolve (or handling it a different way)
|
657
552
|
if (err.code !== 'MODULE_NOT_FOUND') {
|
658
553
|
throw err;
|
659
554
|
}
|
@@ -669,27 +564,14 @@ class Resolver {
|
|
669
564
|
return logTransition('request targets a moved package', request, this.resolveWithinMovedPackage(request, targetPkg));
|
670
565
|
}
|
671
566
|
else if (originalRequestingPkg !== requestingPkg) {
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
return logTransition('outbound request from moved package', request, request
|
676
|
-
// setting meta here because if this fails, we want the fallback
|
677
|
-
// logic to revert our rehome and continue from the *moved* package.
|
678
|
-
.withMeta({ originalFromFile: request.fromFile })
|
679
|
-
.rehome((0, path_1.resolve)(originalRequestingPkg.root, 'package.json')));
|
680
|
-
}
|
681
|
-
else {
|
682
|
-
// requesting package was moved and we failed to find its target. We
|
683
|
-
// can't let that accidentally succeed in the defaultResolve because we
|
684
|
-
// could escape the moved package system.
|
685
|
-
return logTransition('missing outbound request from moved package', request, request.notFound());
|
686
|
-
}
|
567
|
+
// in this case, the requesting package is moved but its destination is
|
568
|
+
// not, so we need to rehome the request back to the original location.
|
569
|
+
return logTransition('outbound request from moved package', request, request.withMeta({ wasMovedTo: request.fromFile }).rehome((0, path_1.resolve)(originalRequestingPkg.root, 'package.json')));
|
687
570
|
}
|
688
571
|
return request;
|
689
572
|
}
|
690
573
|
handleRenaming(request) {
|
691
|
-
|
692
|
-
if (request.resolvedTo) {
|
574
|
+
if (request.isVirtual) {
|
693
575
|
return request;
|
694
576
|
}
|
695
577
|
let packageName = (0, shared_internals_1.packageName)(request.specifier);
|
@@ -697,11 +579,14 @@ class Resolver {
|
|
697
579
|
return request;
|
698
580
|
}
|
699
581
|
let pkg = this.packageCache.ownerOfFile(request.fromFile);
|
582
|
+
if (!pkg || !pkg.isV2Ember()) {
|
583
|
+
return request;
|
584
|
+
}
|
700
585
|
// real deps take precedence over renaming rules. That is, a package like
|
701
586
|
// ember-source might provide backburner via module renaming, but if you
|
702
587
|
// have an explicit dependency on backburner you should still get that real
|
703
588
|
// copy.
|
704
|
-
if (!
|
589
|
+
if (!pkg.hasDependency(packageName)) {
|
705
590
|
for (let [candidate, replacement] of Object.entries(this.options.renameModules)) {
|
706
591
|
if (candidate === request.specifier) {
|
707
592
|
return logTransition(`renameModules`, request, request.alias(replacement));
|
@@ -719,74 +604,30 @@ class Resolver {
|
|
719
604
|
return logTransition(`renamePackages`, request, request.alias(request.specifier.replace(packageName, this.options.renamePackages[packageName])));
|
720
605
|
}
|
721
606
|
}
|
722
|
-
if (
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
//
|
727
|
-
|
728
|
-
// auto-upgraded packages always get automatically adjusted. They never
|
729
|
-
// supported fancy package.json exports features so this direct mapping
|
730
|
-
// to the root is always right.
|
731
|
-
// "my-app/foo" -> "./foo" from app's package.json
|
732
|
-
// "my-addon/foo" -> "my-addon/foo" from a package that's guaranteed to be able to resolve my-addon
|
733
|
-
let owningEngine = this.owningEngine(pkg);
|
734
|
-
let addonConfig = owningEngine.activeAddons.find(a => a.root === pkg.root);
|
735
|
-
if (addonConfig) {
|
736
|
-
// auto-upgraded addons get special support for self-resolving here.
|
737
|
-
return logTransition(`v1 addon self-import`, request, request.rehome(addonConfig.canResolveFromFile));
|
738
|
-
}
|
739
|
-
else {
|
740
|
-
// auto-upgraded apps will necessarily have packageJSON.exports
|
741
|
-
// because we insert them, so for that support we can fall through to
|
742
|
-
// that support below.
|
743
|
-
}
|
744
|
-
}
|
745
|
-
// v2 packages are supposed to use package.json `exports` to enable
|
746
|
-
// self-imports, but not all build tools actually follow the spec. This
|
747
|
-
// is a workaround for badly behaved packagers.
|
748
|
-
//
|
749
|
-
// Known upstream bugs this works around:
|
750
|
-
// - https://github.com/vitejs/vite/issues/9731
|
751
|
-
if (pkg.packageJSON.exports) {
|
752
|
-
let found = (0, resolve_exports_1.exports)(pkg.packageJSON, request.specifier, {
|
753
|
-
browser: true,
|
754
|
-
conditions: ['default', 'imports'],
|
755
|
-
});
|
756
|
-
if (found === null || found === void 0 ? void 0 : found[0]) {
|
757
|
-
return logTransition(`v2 self-import with package.json exports`, request, request.alias(found === null || found === void 0 ? void 0 : found[0]).rehome((0, path_1.resolve)(pkg.root, 'package.json')));
|
758
|
-
}
|
759
|
-
}
|
607
|
+
if (pkg.meta['auto-upgraded'] && pkg.name === packageName) {
|
608
|
+
// we found a self-import, resolve it for them. Only auto-upgraded
|
609
|
+
// packages get this help, v2 packages are natively supposed to make their
|
610
|
+
// own modules resolvable, and we want to push them all to do that
|
611
|
+
// correctly.
|
612
|
+
return logTransition(`v1 self-import`, request, request.alias(request.specifier.replace(pkg.name, '.')).rehome((0, path_1.resolve)(pkg.root, 'package.json')));
|
760
613
|
}
|
761
614
|
return request;
|
762
615
|
}
|
763
|
-
handleVendor(request) {
|
764
|
-
if (request.specifier !== '@embroider/virtual/vendor.js') {
|
765
|
-
return request;
|
766
|
-
}
|
767
|
-
let pkg = this.packageCache.ownerOfFile(request.fromFile);
|
768
|
-
if ((pkg === null || pkg === void 0 ? void 0 : pkg.root) !== this.options.engines[0].root) {
|
769
|
-
throw new Error(`bug: found an import of ${request.specifier} in ${request.fromFile}, but this is not the top-level Ember app. The top-level Ember app is the only one that has support for @embroider/virtual/vendor.js. If you think something should be fixed in Embroider, please open an issue on https://github.com/embroider-build/embroider/issues.`);
|
770
|
-
}
|
771
|
-
return logTransition('vendor', request, request.virtualize({ type: 'vendor-js', specifier: (0, path_1.resolve)(pkg.root, '-embroider-vendor.js') }));
|
772
|
-
}
|
773
616
|
resolveWithinMovedPackage(request, pkg) {
|
774
617
|
let levels = ['..'];
|
775
618
|
if (pkg.name.startsWith('@')) {
|
776
619
|
levels.push('..');
|
777
620
|
}
|
778
|
-
let originalFromFile = request.fromFile;
|
779
621
|
let newRequest = request.rehome((0, path_1.resolve)(pkg.root, ...levels, 'moved-package-target.js'));
|
780
622
|
if (newRequest === request) {
|
781
623
|
return request;
|
782
624
|
}
|
783
|
-
|
784
|
-
|
785
|
-
|
625
|
+
return newRequest.withMeta({
|
626
|
+
resolvedWithinPackage: pkg.root,
|
627
|
+
});
|
786
628
|
}
|
787
629
|
preHandleExternal(request) {
|
788
|
-
|
789
|
-
if (request.resolvedTo) {
|
630
|
+
if (request.isVirtual) {
|
790
631
|
return request;
|
791
632
|
}
|
792
633
|
let { specifier, fromFile } = request;
|
@@ -796,6 +637,11 @@ class Resolver {
|
|
796
637
|
}
|
797
638
|
let packageName = (0, shared_internals_1.packageName)(specifier);
|
798
639
|
if (!packageName) {
|
640
|
+
// This is a relative import. We don't automatically externalize those
|
641
|
+
// because it's rare, and by keeping them static we give better errors. But
|
642
|
+
// we do allow them to be explicitly externalized by the package author (or
|
643
|
+
// a compat adapter). In the metadata, they would be listed in
|
644
|
+
// package-relative form, so we need to convert this specifier to that.
|
799
645
|
let absoluteSpecifier = (0, path_1.resolve)((0, path_1.dirname)(fromFile), specifier);
|
800
646
|
if (!absoluteSpecifier.startsWith(pkg.root)) {
|
801
647
|
// this relative path escape its package. So it's not really using
|
@@ -804,35 +650,48 @@ class Resolver {
|
|
804
650
|
// references to runtime utilities, like we do in @embroider/macros.
|
805
651
|
return logTransition('beforeResolve: relative path escapes its package', request);
|
806
652
|
}
|
653
|
+
let packageRelativeSpecifier = (0, shared_internals_2.explicitRelative)(pkg.root, absoluteSpecifier);
|
654
|
+
if (isExplicitlyExternal(packageRelativeSpecifier, pkg)) {
|
655
|
+
let publicSpecifier = absoluteSpecifier.replace(pkg.root, pkg.name);
|
656
|
+
return this.external('beforeResolve', request, publicSpecifier);
|
657
|
+
}
|
807
658
|
// if the requesting file is in an addon's app-js, the relative request
|
808
659
|
// should really be understood as a request for a module in the containing
|
809
|
-
// engine
|
660
|
+
// engine
|
810
661
|
let logicalLocation = this.reverseSearchAppTree(pkg, request.fromFile);
|
811
662
|
if (logicalLocation) {
|
812
|
-
return logTransition('beforeResolve: relative import in app-js', request, request.
|
663
|
+
return logTransition('beforeResolve: relative import in app-js', request, request.rehome((0, path_1.resolve)(logicalLocation.owningEngine.root, logicalLocation.inAppName)));
|
813
664
|
}
|
814
665
|
return request;
|
815
666
|
}
|
667
|
+
// absolute package imports can also be explicitly external based on their
|
668
|
+
// full specifier name
|
669
|
+
if (isExplicitlyExternal(specifier, pkg)) {
|
670
|
+
return this.external('beforeResolve', request, specifier);
|
671
|
+
}
|
672
|
+
if (shared_internals_1.emberVirtualPackages.has(packageName) && !pkg.hasDependency(packageName)) {
|
673
|
+
return this.external('beforeResolve emberVirtualPackages', request, specifier);
|
674
|
+
}
|
816
675
|
if (shared_internals_1.emberVirtualPeerDeps.has(packageName) && !pkg.hasDependency(packageName)) {
|
817
676
|
// addons (whether auto-upgraded or not) may use the app's
|
818
677
|
// emberVirtualPeerDeps, like "@glimmer/component" etc.
|
819
|
-
|
820
|
-
|
821
|
-
throw new Error(`${pkg.name} is trying to import the emberVirtualPeerDep "${packageName}", but it seems to be missing`);
|
678
|
+
if (!this.options.activeAddons[packageName]) {
|
679
|
+
throw new Error(`${pkg.name} is trying to import the app's ${packageName} package, but it seems to be missing`);
|
822
680
|
}
|
823
|
-
|
681
|
+
let newHome = (0, path_1.resolve)(this.packageCache.maybeMoved(this.packageCache.get(this.options.appRoot)).root, 'package.json');
|
682
|
+
return logTransition(`emberVirtualPeerDeps in v2 addon`, request, request.rehome(newHome));
|
824
683
|
}
|
825
684
|
// if this file is part of an addon's app-js, it's really the logical
|
826
685
|
// package to which it belongs (normally the app) that affects some policy
|
827
686
|
// choices about what it can import
|
828
687
|
let logicalPackage = this.logicalPackage(pkg, fromFile);
|
829
|
-
if (
|
688
|
+
if (logicalPackage.meta['auto-upgraded'] && !logicalPackage.hasDependency('ember-auto-import')) {
|
830
689
|
try {
|
831
690
|
let dep = this.packageCache.resolve(packageName, logicalPackage);
|
832
|
-
if (!dep.
|
691
|
+
if (!dep.isEmberPackage()) {
|
833
692
|
// classic ember addons can only import non-ember dependencies if they
|
834
693
|
// have ember-auto-import.
|
835
|
-
return
|
694
|
+
return this.external('v1 package without auto-import', request, specifier);
|
836
695
|
}
|
837
696
|
}
|
838
697
|
catch (err) {
|
@@ -842,33 +701,49 @@ class Resolver {
|
|
842
701
|
}
|
843
702
|
}
|
844
703
|
// assertions on what native v2 addons can import
|
845
|
-
if (!pkg.
|
846
|
-
!
|
847
|
-
|
848
|
-
|
704
|
+
if (!pkg.meta['auto-upgraded']) {
|
705
|
+
if (!pkg.meta['auto-upgraded'] &&
|
706
|
+
!appImportInAppTree(pkg, logicalPackage, packageName) &&
|
707
|
+
!reliablyResolvable(pkg, packageName)) {
|
708
|
+
throw new Error(`${pkg.name} is trying to import from ${packageName} but that is not one of its explicit dependencies`);
|
709
|
+
}
|
849
710
|
}
|
850
711
|
return request;
|
851
712
|
}
|
852
|
-
|
853
|
-
if (
|
854
|
-
|
855
|
-
return
|
856
|
-
|
857
|
-
|
858
|
-
|
713
|
+
external(label, request, specifier) {
|
714
|
+
if (this.options.amdCompatibility === 'cjs') {
|
715
|
+
let filename = (0, virtual_content_1.virtualExternalCJSModule)(specifier);
|
716
|
+
return logTransition(label, request, request.virtualize(filename));
|
717
|
+
}
|
718
|
+
else if (this.options.amdCompatibility) {
|
719
|
+
let entry = this.options.amdCompatibility.es.find(entry => entry[0] === specifier || entry[0] + '/index' === specifier);
|
720
|
+
if (!entry && request.specifier === 'require') {
|
721
|
+
entry = ['require', ['default', 'has']];
|
722
|
+
}
|
723
|
+
if (!entry) {
|
724
|
+
throw new Error(`A module tried to resolve "${request.specifier}" and didn't find it (${label}).
|
725
|
+
|
726
|
+
- Maybe a dependency declaration is missing?
|
727
|
+
- Remember that v1 addons can only import non-Ember-addon NPM dependencies if they include ember-auto-import in their dependencies.
|
728
|
+
- If this dependency is available in the AMD loader (because someone manually called "define()" for it), you can configure a shim like:
|
729
|
+
|
730
|
+
amdCompatibility: {
|
731
|
+
es: [
|
732
|
+
["${request.specifier}", ["default", "yourNamedExportsGoHere"]],
|
733
|
+
]
|
734
|
+
}
|
735
|
+
|
736
|
+
`);
|
737
|
+
}
|
738
|
+
let filename = (0, virtual_content_1.virtualExternalESModule)(specifier, entry[1]);
|
739
|
+
return logTransition(label, request, request.virtualize(filename));
|
859
740
|
}
|
860
|
-
|
861
|
-
|
862
|
-
if (addon.name === packageName) {
|
863
|
-
return addon;
|
864
|
-
}
|
865
|
-
}
|
741
|
+
else {
|
742
|
+
throw new Error(`Embroider's amdCompatibility option is disabled, but something tried to use it to access "${request.specifier}"`);
|
866
743
|
}
|
867
744
|
}
|
868
|
-
|
869
|
-
|
870
|
-
throw new Error('Build tool bug detected! Fallback resolve should never see an already-resolved request.');
|
871
|
-
}
|
745
|
+
fallbackResolve(request) {
|
746
|
+
var _a, _b, _c;
|
872
747
|
if (request.specifier === '@embroider/macros') {
|
873
748
|
// the macros package is always handled directly within babel (not
|
874
749
|
// necessarily as a real resolvable package), so we should not mess with it.
|
@@ -876,124 +751,108 @@ class Resolver {
|
|
876
751
|
// why we need to know about it.
|
877
752
|
return logTransition('fallback early exit', request);
|
878
753
|
}
|
879
|
-
|
754
|
+
let { specifier, fromFile } = request;
|
755
|
+
if (compatPattern.test(specifier)) {
|
880
756
|
// Some kinds of compat requests get rewritten into other things
|
881
|
-
// deterministically. For example, "
|
757
|
+
// deterministically. For example, "#embroider_compat/helpers/whatever"
|
882
758
|
// means only "the-current-engine/helpers/whatever", and if that doesn't
|
883
759
|
// actually exist it's that path that will show up as a missing import.
|
884
760
|
//
|
885
761
|
// But others have an ambiguous meaning. For example,
|
886
|
-
//
|
762
|
+
// #embroider_compat/components/whatever can mean several different
|
887
763
|
// things. If we're unable to find any of them, the actual
|
888
|
-
// "
|
764
|
+
// "#embroider_compat" request will fall through all the way to here.
|
889
765
|
//
|
890
766
|
// In that case, we don't want to externalize that failure. We know it's
|
891
767
|
// not a classic runtime thing. It's better to let it be a build error
|
892
768
|
// here.
|
893
769
|
return request;
|
894
770
|
}
|
895
|
-
|
896
|
-
|
897
|
-
|
771
|
+
if (fromFile.endsWith('moved-package-target.js')) {
|
772
|
+
if (!((_a = request.meta) === null || _a === void 0 ? void 0 : _a.resolvedWithinPackage)) {
|
773
|
+
throw new Error(`bug: embroider resolver's meta is not propagating`);
|
774
|
+
}
|
775
|
+
fromFile = (0, path_1.resolve)((_b = request.meta) === null || _b === void 0 ? void 0 : _b.resolvedWithinPackage, 'package.json');
|
898
776
|
}
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
|
903
|
-
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
909
|
-
if (
|
910
|
-
|
777
|
+
let pkg = this.packageCache.ownerOfFile(fromFile);
|
778
|
+
if (!pkg) {
|
779
|
+
return logTransition('no identifiable owningPackage', request);
|
780
|
+
}
|
781
|
+
// if we rehomed this request to its un-rewritten location in order to try
|
782
|
+
// to do the defaultResolve from there, now we refer back to the rewritten
|
783
|
+
// location because that's what we want to use when asking things like
|
784
|
+
// isV2Ember()
|
785
|
+
let movedPkg = this.packageCache.maybeMoved(pkg);
|
786
|
+
if (movedPkg !== pkg) {
|
787
|
+
if (!((_c = request.meta) === null || _c === void 0 ? void 0 : _c.wasMovedTo)) {
|
788
|
+
throw new Error(`bug: embroider resolver's meta is not propagating`);
|
911
789
|
}
|
912
|
-
|
790
|
+
fromFile = request.meta.wasMovedTo;
|
791
|
+
pkg = movedPkg;
|
913
792
|
}
|
914
|
-
|
793
|
+
if (!pkg.isV2Ember()) {
|
794
|
+
return logTransition('fallbackResolve: not in an ember package', request);
|
795
|
+
}
|
796
|
+
let packageName = (0, shared_internals_1.packageName)(specifier);
|
915
797
|
if (!packageName) {
|
916
798
|
// this is a relative import
|
917
|
-
|
799
|
+
let withinEngine = this.engineConfig(pkg.name);
|
800
|
+
if (withinEngine) {
|
801
|
+
// it's a relative import inside an engine (which also means app), which
|
802
|
+
// means we may need to satisfy the request via app tree merging.
|
803
|
+
let appJSMatch = this.searchAppTree(request, withinEngine, (0, shared_internals_2.explicitRelative)(pkg.root, (0, path_1.resolve)((0, path_1.dirname)(fromFile), specifier)));
|
804
|
+
if (appJSMatch) {
|
805
|
+
return logTransition('fallbackResolve: relative appJsMatch', request, appJSMatch);
|
806
|
+
}
|
807
|
+
else {
|
808
|
+
return logTransition('fallbackResolve: relative appJs search failure', request);
|
809
|
+
}
|
810
|
+
}
|
811
|
+
else {
|
812
|
+
// nothing else to do for relative imports
|
813
|
+
return logTransition('fallbackResolve: relative failure', request);
|
814
|
+
}
|
918
815
|
}
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
|
816
|
+
// auto-upgraded packages can fall back to the set of known active addons
|
817
|
+
if (pkg.meta['auto-upgraded'] && this.options.activeAddons[packageName]) {
|
818
|
+
const rehomed = this.resolveWithinMovedPackage(request, this.packageCache.get(this.options.activeAddons[packageName]));
|
819
|
+
if (rehomed !== request) {
|
820
|
+
return logTransition(`activeAddons`, request, rehomed);
|
923
821
|
}
|
924
822
|
}
|
925
|
-
let logicalLocation = this.reverseSearchAppTree(pkg,
|
823
|
+
let logicalLocation = this.reverseSearchAppTree(pkg, fromFile);
|
926
824
|
if (logicalLocation) {
|
927
825
|
// the requesting file is in an addon's appTree. We didn't succeed in
|
928
826
|
// resolving this (non-relative) request from inside the actual addon, so
|
929
827
|
// next try to resolve it from the corresponding logical location in the
|
930
828
|
// app.
|
931
|
-
return logTransition('fallbackResolve: retry from logical home of app-js file', request,
|
932
|
-
// it might look more precise to rehome into logicalLocation.inAppName
|
933
|
-
// rather than package.json. But that logical location may not actually
|
934
|
-
// exist, and some systems (including node's require.resolve) will be
|
935
|
-
// mad about trying to resolve from notional paths that don't really
|
936
|
-
// exist.
|
937
|
-
request.rehome((0, path_1.resolve)(logicalLocation.owningEngine.root, 'package.json')));
|
829
|
+
return logTransition('fallbackResolve: retry from logical home of app-js file', request, request.rehome((0, path_1.resolve)(logicalLocation.owningEngine.root, logicalLocation.inAppName)));
|
938
830
|
}
|
939
831
|
let targetingEngine = this.engineConfig(packageName);
|
940
832
|
if (targetingEngine) {
|
941
|
-
let appJSMatch =
|
833
|
+
let appJSMatch = this.searchAppTree(request, targetingEngine, specifier.replace(packageName, '.'));
|
942
834
|
if (appJSMatch) {
|
943
835
|
return logTransition('fallbackResolve: non-relative appJsMatch', request, appJSMatch);
|
944
836
|
}
|
945
837
|
}
|
946
|
-
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
|
951
|
-
|
952
|
-
// meta.originalFromFile gets set when we want to try to rehome a request
|
953
|
-
// but then come back to the original location here in the fallback when the
|
954
|
-
// rehomed request fails
|
955
|
-
let movedPkg = this.packageCache.maybeMoved(pkg);
|
956
|
-
if (movedPkg !== pkg) {
|
957
|
-
let originalFromFile = (_a = request.meta) === null || _a === void 0 ? void 0 : _a.originalFromFile;
|
958
|
-
if (typeof originalFromFile !== 'string') {
|
959
|
-
throw new Error(`bug: embroider resolver's meta is not propagating`);
|
960
|
-
}
|
961
|
-
request = request.rehome(originalFromFile);
|
962
|
-
pkg = movedPkg;
|
963
|
-
}
|
964
|
-
return { pkg, request };
|
965
|
-
}
|
966
|
-
async relativeFallbackResolve(pkg, request) {
|
967
|
-
let withinEngine = this.engineConfig(pkg.name);
|
968
|
-
if (withinEngine) {
|
969
|
-
// it's a relative import inside an engine (which also means app), which
|
970
|
-
// means we may need to satisfy the request via app tree merging.
|
971
|
-
let logicalName = engineRelativeName(pkg, (0, path_1.resolve)((0, path_1.dirname)(request.fromFile), request.specifier));
|
972
|
-
if (!logicalName) {
|
973
|
-
return logTransition('fallbackResolve: relative failure because this file is not externally accessible', request);
|
974
|
-
}
|
975
|
-
let appJSMatch = await this.searchAppTree(request, withinEngine, logicalName);
|
976
|
-
if (appJSMatch) {
|
977
|
-
return logTransition('fallbackResolve: relative appJsMatch', request, appJSMatch);
|
978
|
-
}
|
979
|
-
else {
|
980
|
-
return logTransition('fallbackResolve: relative appJs search failure', request);
|
981
|
-
}
|
838
|
+
if (pkg.meta['auto-upgraded']) {
|
839
|
+
// auto-upgraded packages can fall back to attempting to find dependencies at
|
840
|
+
// runtime. Native v2 packages can only get this behavior in the
|
841
|
+
// isExplicitlyExternal case above because they need to explicitly ask for
|
842
|
+
// externals.
|
843
|
+
return this.external('v1 catch-all fallback', request, specifier);
|
982
844
|
}
|
983
845
|
else {
|
984
|
-
//
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
// auto-upgraded packages can fall back to the set of known active addons
|
990
|
-
let addon = this.locateActiveAddon(requestedPackageName);
|
991
|
-
if (addon) {
|
992
|
-
const rehomed = request.rehome(addon.canResolveFromFile);
|
993
|
-
if (rehomed !== request) {
|
994
|
-
return logTransition(`activeAddons`, request, rehomed);
|
846
|
+
// native v2 packages don't automatically externalize *everything* the way
|
847
|
+
// auto-upgraded packages do, but they still externalize known and approved
|
848
|
+
// ember virtual packages (like @ember/component)
|
849
|
+
if (shared_internals_1.emberVirtualPackages.has(packageName)) {
|
850
|
+
return this.external('emberVirtualPackages', request, specifier);
|
995
851
|
}
|
996
852
|
}
|
853
|
+
// this is falling through with the original specifier which was
|
854
|
+
// non-resolvable, which will presumably cause a static build error in stage3.
|
855
|
+
return logTransition('fallbackResolve final exit', request);
|
997
856
|
}
|
998
857
|
getEntryFromMergeMap(inEngineSpecifier, root) {
|
999
858
|
var _a;
|
@@ -1015,22 +874,26 @@ class Resolver {
|
|
1015
874
|
}
|
1016
875
|
}
|
1017
876
|
}
|
1018
|
-
|
877
|
+
searchAppTree(request, engine, inEngineSpecifier) {
|
1019
878
|
let matched = this.getEntryFromMergeMap(inEngineSpecifier, engine.root);
|
1020
879
|
switch (matched === null || matched === void 0 ? void 0 : matched.entry.type) {
|
1021
880
|
case undefined:
|
1022
881
|
return undefined;
|
1023
882
|
case 'app-only':
|
1024
|
-
return request
|
883
|
+
return request
|
884
|
+
.alias(matched.entry['app-js'].localPath)
|
885
|
+
.rehome((0, path_1.resolve)(matched.entry['app-js'].packageRoot, 'package.json'));
|
1025
886
|
case 'fastboot-only':
|
1026
|
-
return request
|
887
|
+
return request
|
888
|
+
.alias(matched.entry['fastboot-js'].localPath)
|
889
|
+
.rehome((0, path_1.resolve)(matched.entry['fastboot-js'].packageRoot, 'package.json'));
|
1027
890
|
case 'both':
|
1028
|
-
let foundAppJS =
|
1029
|
-
if (foundAppJS.type !== '
|
891
|
+
let foundAppJS = this.nodeResolve(matched.entry['app-js'].localPath, (0, path_1.resolve)(matched.entry['app-js'].packageRoot, 'package.json'));
|
892
|
+
if (foundAppJS.type !== 'real') {
|
1030
893
|
throw new Error(`${matched.entry['app-js'].fromPackageName} declared ${inEngineSpecifier} in packageJSON.ember-addon.app-js, but that module does not exist`);
|
1031
894
|
}
|
1032
|
-
let { names } = (0, describe_exports_1.describeExports)((0, fs_1.readFileSync)(foundAppJS.filename, 'utf8'), {
|
1033
|
-
return request.virtualize(fastbootSwitch(matched.matched, (0, path_1.resolve)(engine.root, 'package.json'), names));
|
895
|
+
let { names } = (0, describe_exports_1.describeExports)((0, fs_1.readFileSync)(foundAppJS.filename, 'utf8'), {});
|
896
|
+
return request.virtualize((0, virtual_content_1.fastbootSwitch)(matched.matched, (0, path_1.resolve)(engine.root, 'package.json'), names));
|
1034
897
|
}
|
1035
898
|
}
|
1036
899
|
// check whether the given file with the given owningPackage is an addon's
|
@@ -1064,10 +927,14 @@ class Resolver {
|
|
1064
927
|
if (engineConfig) {
|
1065
928
|
// we're directly inside an engine, so we're potentially resolvable as a
|
1066
929
|
// global component
|
1067
|
-
|
1068
|
-
|
1069
|
-
|
1070
|
-
|
930
|
+
// this kind of mapping is not true in general for all packages, but it
|
931
|
+
// *is* true for all classical engines (which includes apps) since they
|
932
|
+
// don't support package.json `exports`. As for a future v2 engine or app:
|
933
|
+
// this whole method is only relevant for implementing packageRules, which
|
934
|
+
// should only be for classic stuff. v2 packages should do the right
|
935
|
+
// things from the beginning and not need packageRules about themselves.
|
936
|
+
let inAppName = (0, shared_internals_2.explicitRelative)(engineConfig.root, filename);
|
937
|
+
return this.tryReverseComponent(engineConfig.packageName, inAppName);
|
1071
938
|
}
|
1072
939
|
let engineInfo = this.reverseSearchAppTree(owningPackage, filename);
|
1073
940
|
if (engineInfo) {
|
@@ -1094,6 +961,9 @@ __decorate([
|
|
1094
961
|
__decorate([
|
1095
962
|
(0, typescript_memoize_1.Memoize)()
|
1096
963
|
], Resolver.prototype, "emberVersionSupportsSeparateTemplates", null);
|
964
|
+
function isExplicitlyExternal(specifier, fromPkg) {
|
965
|
+
return Boolean(fromPkg.isV2Addon() && fromPkg.meta['externals'] && fromPkg.meta['externals'].includes(specifier));
|
966
|
+
}
|
1097
967
|
// we don't want to allow things that resolve only by accident that are likely
|
1098
968
|
// to break in other setups. For example: import your dependencies'
|
1099
969
|
// dependencies, or importing your own name from within a monorepo (which will
|
@@ -1115,33 +985,4 @@ function reliablyResolvable(pkg, packageName) {
|
|
1115
985
|
function appImportInAppTree(inPackage, inLogicalPackage, importedPackageName) {
|
1116
986
|
return inPackage !== inLogicalPackage && importedPackageName === inLogicalPackage.name;
|
1117
987
|
}
|
1118
|
-
function engineRelativeName(pkg, filename) {
|
1119
|
-
let outsideName = (0, reverse_exports_1.externalName)(pkg.packageJSON, (0, shared_internals_2.explicitRelative)(pkg.root, filename));
|
1120
|
-
if (outsideName) {
|
1121
|
-
return '.' + outsideName.slice(pkg.name.length);
|
1122
|
-
}
|
1123
|
-
}
|
1124
|
-
const fastbootSwitchSuffix = '/embroider_fastboot_switch';
|
1125
|
-
function fastbootSwitch(specifier, fromFile, names) {
|
1126
|
-
let filename = `${(0, path_1.resolve)((0, path_1.dirname)(fromFile), specifier)}${fastbootSwitchSuffix}`;
|
1127
|
-
let virtualSpecifier;
|
1128
|
-
if (names.size > 0) {
|
1129
|
-
virtualSpecifier = `${filename}?names=${[...names].join(',')}`;
|
1130
|
-
}
|
1131
|
-
else {
|
1132
|
-
virtualSpecifier = filename;
|
1133
|
-
}
|
1134
|
-
return {
|
1135
|
-
type: 'fastboot-switch',
|
1136
|
-
specifier: virtualSpecifier,
|
1137
|
-
names,
|
1138
|
-
hasDefaultExport: 'x',
|
1139
|
-
};
|
1140
|
-
}
|
1141
|
-
function decodeFastbootSwitch(filename) {
|
1142
|
-
let index = filename.indexOf(fastbootSwitchSuffix);
|
1143
|
-
if (index >= 0) {
|
1144
|
-
return { filename: filename.slice(0, index) };
|
1145
|
-
}
|
1146
|
-
}
|
1147
988
|
//# sourceMappingURL=module-resolver.js.map
|