Skip to content

Commit

Permalink
Merge branch 'embroider-build:main' into fix-missing-assets
Browse files Browse the repository at this point in the history
  • Loading branch information
patricklx authored Dec 10, 2024
2 parents c2838c2 + 48f6e51 commit 8a67513
Show file tree
Hide file tree
Showing 19 changed files with 289 additions and 218 deletions.
61 changes: 20 additions & 41 deletions packages/core/src/module-request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ export type RequestAdapterCreate<Init, Res extends Resolution> = (
export interface RequestAdapter<Res extends Resolution> {
readonly debugType: string;
resolve(request: ModuleRequest<Res>): Promise<Res>;

// the function-returning variants of both of these are only because webpack
// plugins are a pain in the butt. Integrators are encouraged to use the plain
// Response-returning variants in all sane build environments.
notFoundResponse(request: ModuleRequest<Res>): Res | (() => Promise<Res>);
virtualResponse(request: ModuleRequest<Res>, virtualFileName: string): Res | (() => Promise<Res>);
}

export interface InitialRequestState {
Expand All @@ -44,23 +50,14 @@ export class ModuleRequest<Res extends Resolution = Resolution> implements Modul
#adapter: RequestAdapter<Res>;
#specifier: string;
#fromFile: string;
#isVirtual: boolean;
#meta: Record<string, unknown> | undefined;
#isNotFound: boolean;
#resolvedTo: Res | undefined;

private constructor(
adapter: RequestAdapter<Res>,
initialize: InitialRequestState,
propagate?: { isVirtual: boolean; isNotFound: boolean; resolvedTo: Res | undefined }
) {
#resolvedTo: Res | (() => Promise<Res>) | undefined;

private constructor(adapter: RequestAdapter<Res>, initialize: InitialRequestState) {
this.#adapter = adapter;
this.#specifier = initialize.specifier;
this.#fromFile = initialize.fromFile;
this.#meta = initialize.meta;
this.#isVirtual = propagate?.isVirtual ?? false;
this.#isNotFound = propagate?.isNotFound ?? false;
this.#resolvedTo = propagate?.resolvedTo;
}

get specifier(): string {
Expand All @@ -71,10 +68,6 @@ export class ModuleRequest<Res extends Resolution = Resolution> implements Modul
return this.#fromFile;
}

get isVirtual(): boolean {
return this.#isVirtual;
}

get debugType(): string {
return this.#adapter.debugType;
}
Expand All @@ -83,59 +76,45 @@ export class ModuleRequest<Res extends Resolution = Resolution> implements Modul
return this.#meta;
}

get isNotFound(): boolean {
return this.#isNotFound;
}

get resolvedTo(): Res | undefined {
get resolvedTo(): Res | (() => Promise<Res>) | undefined {
return this.#resolvedTo;
}

alias(newSpecifier: string): this {
if (this.#specifier === newSpecifier) {
return this;
}
let result = this.#clone();
let result = this.clone();
result.#specifier = newSpecifier;
result.#isNotFound = false;
result.#resolvedTo = undefined;
return result;
}

rehome(newFromFile: string): this {
if (this.#fromFile === newFromFile) {
return this;
}
let result = this.#clone();
let result = this.clone();
result.#fromFile = newFromFile;
result.#isNotFound = false;
result.#resolvedTo = undefined;
return result;
}

virtualize(virtualFileName: string): this {
let result = this.#clone();
result.#specifier = virtualFileName;
result.#isVirtual = true;
result.#isNotFound = false;
result.#resolvedTo = undefined;
return result;
return this.resolveTo(this.#adapter.virtualResponse(this, virtualFileName));
}

withMeta(meta: Record<string, any> | undefined): this {
let result = this.#clone();
let result = this.clone();
result.#meta = meta;
result.#resolvedTo = this.#resolvedTo;
return result;
}

notFound(): this {
let result = this.#clone();
result.#isNotFound = true;
return result;
return this.resolveTo(this.#adapter.notFoundResponse(this));
}

resolveTo(res: Res): this {
let result = this.#clone();
resolveTo(res: Res | (() => Promise<Res>)): this {
let result = this.clone();
result.#resolvedTo = res;
return result;
}
Expand All @@ -144,7 +123,7 @@ export class ModuleRequest<Res extends Resolution = Resolution> implements Modul
return this.#adapter.resolve(this);
}

#clone(): this {
return new ModuleRequest(this.#adapter, this, this) as this;
clone(): this {
return new ModuleRequest(this.#adapter, this) as this;
}
}
63 changes: 30 additions & 33 deletions packages/core/src/module-resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,7 @@ makeDebug.formatters.p = (s: string) => {
};

function logTransition<R extends ModuleRequest>(reason: string, before: R, after: R = before): R {
if (after.isVirtual) {
debug(`[%s:virtualized] %s because %s\n in %p`, before.debugType, before.specifier, reason, before.fromFile);
} else if (after.resolvedTo) {
if (after.resolvedTo) {
debug(`[%s:resolvedTo] %s because %s\n in %p`, before.debugType, before.specifier, reason, before.fromFile);
} else if (before.specifier !== after.specifier) {
if (before.fromFile !== after.fromFile) {
Expand All @@ -64,18 +62,12 @@ function logTransition<R extends ModuleRequest>(reason: string, before: R, after
before.fromFile,
after.fromFile
);
} else if (after.isNotFound) {
debug(`[%s:not-found] %s because %s\n in %p`, before.debugType, before.specifier, reason, before.fromFile);
} else {
debug(`[%s:unchanged] %s because %s\n in %p`, before.debugType, before.specifier, reason, before.fromFile);
}
return after;
}

function isTerminal(request: ModuleRequest): boolean {
return request.isVirtual || request.isNotFound || Boolean(request.resolvedTo);
}

type MergeEntry =
| {
type: 'app-only';
Expand Down Expand Up @@ -152,12 +144,19 @@ export class Resolver {
request: ModuleRequest<ResolveResolution>
): Promise<ResolveResolution> {
request = await this.beforeResolve(request);

let resolution: ResolveResolution;

if (request.resolvedTo) {
return request.resolvedTo;
if (typeof request.resolvedTo === 'function') {
resolution = await request.resolvedTo();
} else {
resolution = request.resolvedTo;
}
} else {
resolution = await request.defaultResolve();
}

let resolution = await request.defaultResolve();

switch (resolution.type) {
case 'found':
case 'ignored':
Expand All @@ -167,14 +166,21 @@ export class Resolver {
default:
throw assertNever(resolution);
}

request = request.clone();

let nextRequest = await this.fallbackResolve(request);
if (nextRequest === request) {
// no additional fallback is available.
return resolution;
}

if (nextRequest.resolvedTo) {
return nextRequest.resolvedTo;
if (typeof nextRequest.resolvedTo === 'function') {
return await nextRequest.resolvedTo();
} else {
return nextRequest.resolvedTo;
}
}

if (nextRequest.fromFile === request.fromFile && nextRequest.specifier === request.specifier) {
Expand All @@ -183,13 +189,6 @@ export class Resolver {
);
}

if (nextRequest.isVirtual || nextRequest.isNotFound) {
// virtual and NotFound requests are terminal, there is no more
// beforeResolve or fallbackResolve around them. The defaultResolve is
// expected to know how to implement them.
return nextRequest.defaultResolve();
}

return this.resolve(nextRequest);
}

Expand Down Expand Up @@ -224,7 +223,7 @@ export class Resolver {
}

private generateFastbootSwitch<R extends ModuleRequest>(request: R): R {
if (isTerminal(request)) {
if (request.resolvedTo) {
return request;
}
let pkg = this.packageCache.ownerOfFile(request.fromFile);
Expand Down Expand Up @@ -271,7 +270,7 @@ export class Resolver {
}

private handleFastbootSwitch<R extends ModuleRequest>(request: R): R {
if (isTerminal(request)) {
if (request.resolvedTo) {
return request;
}
let match = decodeFastbootSwitch(request.fromFile);
Expand Down Expand Up @@ -330,7 +329,7 @@ export class Resolver {
}

private handleImplicitModules<R extends ModuleRequest>(request: R): R {
if (isTerminal(request)) {
if (request.resolvedTo) {
return request;
}
let im = decodeImplicitModules(request.specifier);
Expand Down Expand Up @@ -361,7 +360,7 @@ export class Resolver {
}

private handleEntrypoint<R extends ModuleRequest>(request: R): R {
if (isTerminal(request)) {
if (request.resolvedTo) {
return request;
}

Expand Down Expand Up @@ -410,7 +409,7 @@ export class Resolver {
}

private handleRouteEntrypoint<R extends ModuleRequest>(request: R): R {
if (isTerminal(request)) {
if (request.resolvedTo) {
return request;
}

Expand Down Expand Up @@ -487,7 +486,7 @@ export class Resolver {
}

private async handleGlobalsCompat<R extends ModuleRequest>(request: R): Promise<R> {
if (isTerminal(request)) {
if (request.resolvedTo) {
return request;
}
let match = compatPattern.exec(request.specifier);
Expand Down Expand Up @@ -852,7 +851,7 @@ export class Resolver {
}

private handleRewrittenPackages<R extends ModuleRequest>(request: R): R {
if (isTerminal(request)) {
if (request.resolvedTo) {
return request;
}
let requestingPkg = this.packageCache.ownerOfFile(request.fromFile);
Expand Down Expand Up @@ -915,7 +914,7 @@ export class Resolver {
}

private handleRenaming<R extends ModuleRequest>(request: R): R {
if (isTerminal(request)) {
if (request.resolvedTo) {
return request;
}
let packageName = getPackageName(request.specifier);
Expand Down Expand Up @@ -1044,7 +1043,7 @@ export class Resolver {
}

private preHandleExternal<R extends ModuleRequest>(request: R): R {
if (isTerminal(request)) {
if (request.resolvedTo) {
return request;
}
let { specifier, fromFile } = request;
Expand Down Expand Up @@ -1149,10 +1148,8 @@ export class Resolver {
}

private async fallbackResolve<R extends ModuleRequest>(request: R): Promise<R> {
if (request.isVirtual) {
throw new Error(
'Build tool bug detected! Fallback resolve should never see a virtual request. It is expected that the defaultResolve for your bundler has already resolved this request'
);
if (request.resolvedTo) {
throw new Error('Build tool bug detected! Fallback resolve should never see an already-resolved request.');
}

if (request.specifier === '@embroider/macros') {
Expand Down
46 changes: 25 additions & 21 deletions packages/core/src/node-resolve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,28 +28,32 @@ export class NodeRequestAdapter implements RequestAdapter<Resolution<NodeResolut
return 'node';
}

async resolve(request: ModuleRequest<Resolution<NodeResolution, Error>>): Promise<Resolution<NodeResolution, Error>> {
if (request.isVirtual) {
return {
type: 'found',
filename: request.specifier,
isVirtual: true,
result: {
type: 'virtual' as 'virtual',
content: virtualContent(request.specifier, this.resolver).src,
filename: request.specifier,
},
};
}
if (request.isNotFound) {
let err = new Error(`module not found ${request.specifier}`);
(err as any).code = 'MODULE_NOT_FOUND';
return {
type: 'not_found',
err,
};
}
notFoundResponse(request: ModuleRequest<Resolution<NodeResolution, Error>>): Resolution<NodeResolution, Error> {
let err = new Error(`module not found ${request.specifier}`);
(err as any).code = 'MODULE_NOT_FOUND';
return {
type: 'not_found',
err,
};
}

virtualResponse(
_request: ModuleRequest<Resolution<NodeResolution, Error>>,
virtualFileName: string
): Resolution<NodeResolution, Error> {
return {
type: 'found',
filename: virtualFileName,
isVirtual: true,
result: {
type: 'virtual' as 'virtual',
content: virtualContent(virtualFileName, this.resolver).src,
filename: virtualFileName,
},
};
}

async resolve(request: ModuleRequest<Resolution<NodeResolution, Error>>): Promise<Resolution<NodeResolution, Error>> {
// require.resolve does not like when we resolve from virtual paths.
// That is, a request like "../thing.js" from
// "/a/real/path/VIRTUAL_SUBDIR/virtual.js" has an unambiguous target of
Expand Down
1 change: 1 addition & 0 deletions packages/util/testem.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ module.exports = {
ci: [
// --no-sandbox is needed when running Chrome inside a container
process.env.CI ? '--no-sandbox' : null,
'--disable-gpu',
'--headless',
'--disable-dev-shm-usage',
'--disable-software-rasterizer',
Expand Down
2 changes: 2 additions & 0 deletions packages/vite/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ export * from './src/optimize-deps.js';
export * from './src/build.js';
export * from './src/assets.js';
export * from './src/content-for.js';
export * from './src/classic-ember-support.js';
export * from './src/ember.js';
2 changes: 2 additions & 0 deletions packages/vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
"@embroider/reverse-exports": "workspace:*",
"@rollup/pluginutils": "^5.1.0",
"assert-never": "^1.2.1",
"browserslist": "*",
"browserslist-to-esbuild": "^2.1.1",
"content-tag": "^2.0.2",
"debug": "^4.3.2",
"esbuild": "^0.17.19",
Expand Down
Loading

0 comments on commit 8a67513

Please sign in to comment.