Skip to content

Commit

Permalink
fix vite watch mode
Browse files Browse the repository at this point in the history
  • Loading branch information
patricklx committed Oct 1, 2024
1 parent f33728f commit 5d2b42b
Show file tree
Hide file tree
Showing 9 changed files with 823 additions and 341 deletions.
2 changes: 1 addition & 1 deletion packages/core/src/virtual-entrypoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ export function renderEntrypoint(

return {
src: entryTemplate(params),
watches: [],
watches: [fromDir],
};
}

Expand Down
30 changes: 30 additions & 0 deletions packages/vite/src/build.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { fork } from 'child_process';
import type { Plugin } from 'vite';
import { resolve } from 'path';
import fs from 'fs-extra';
const { ensureSymlinkSync, existsSync, writeFileSync } = fs;
import { locateEmbroiderWorkingDir } from '@embroider/core';
import * as process from 'process';

export function emberBuild(command: string, mode: string, resolvableExtensions: string[] | undefined): Promise<void> {
let env: Record<string, string> = {
Expand Down Expand Up @@ -37,6 +42,30 @@ export function emberBuild(command: string, mode: string, resolvableExtensions:
});
}

function createSymlinkToRewrittenPackages(appRoot: string = process.cwd()) {
const resolvableRewrittenPackages = resolve(
locateEmbroiderWorkingDir(appRoot),
'..',
'@embroider',
'rewritten-packages'
);
const embroiderDir = resolve(locateEmbroiderWorkingDir(appRoot), 'rewritten-packages');
if (existsSync(embroiderDir)) {
ensureSymlinkSync(embroiderDir, resolvableRewrittenPackages, 'dir');
writeFileSync(
resolve(resolvableRewrittenPackages, 'package.json'),
JSON.stringify(
{
name: '@embroider/rewritten-packages',
main: 'moved-package-target.js',
},
null,
2
)
);
}
}

export function compatPrebuild(): Plugin {
let viteCommand: string | undefined;
let viteMode: string | undefined;
Expand All @@ -58,6 +87,7 @@ export function compatPrebuild(): Plugin {
throw new Error(`bug: embroider compatPrebuild did not detect Vite's mode`);
}
await emberBuild(viteCommand, viteMode, resolvableExtensions);
createSymlinkToRewrittenPackages();
},
};
}
11 changes: 8 additions & 3 deletions packages/vite/src/esbuild-request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { dirname } from 'path';

import type { PackageCache as _PackageCache, Resolution, ModuleRequest } from '@embroider/core';
import { externalName } from '@embroider/reverse-exports';
import { makeResolvable } from './request.js';

type PublicAPI<T> = { [K in keyof T]: T[K] };
type PackageCache = PublicAPI<_PackageCache>;
Expand Down Expand Up @@ -169,9 +170,13 @@ export class EsBuildModuleRequest implements ModuleRequest {

requestStatus(request.specifier);

let result = await this.context.resolve(request.specifier, {
importer: request.fromFile,
resolveDir: dirname(request.fromFile),
// we must make this also resolvable so that esbuild generates optimized deps for the same IDs
// that the vite resolver uses
let resolvable = makeResolvable(this.packageCache, this.fromFile, this.specifier);
let r = this.alias(resolvable.specifier).rehome(resolvable.fromFile);
let result = await this.context.resolve(r.specifier, {
importer: r.fromFile,
resolveDir: dirname(r.fromFile),
kind: this.kind,
pluginData: {
embroider: {
Expand Down
77 changes: 74 additions & 3 deletions packages/vite/src/request.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import type { ModuleRequest, Resolution } from '@embroider/core';
import type { ModuleRequest, Resolution, Package, PackageCache as _PackageCache } from '@embroider/core';
import core from '@embroider/core';
const { cleanUrl, getUrlQueryParams } = core;
const { cleanUrl, getUrlQueryParams, locateEmbroiderWorkingDir, packageName } = core;
import type { PluginContext, ResolveIdResult } from 'rollup';
import { resolve } from 'path';

type PublicAPI<T> = { [K in keyof T]: T[K] };
type PackageCache = PublicAPI<_PackageCache>;

export const virtualPrefix = 'embroider_virtual:';

export class RollupModuleRequest implements ModuleRequest {
static from(
packageCache: PackageCache,
context: PluginContext,
source: string,
importer: string | undefined,
Expand Down Expand Up @@ -34,6 +39,7 @@ export class RollupModuleRequest implements ModuleRequest {
let queryParams = getUrlQueryParams(source);

return new RollupModuleRequest(
packageCache,
context,
cleanSource,
fromFile,
Expand All @@ -47,6 +53,7 @@ export class RollupModuleRequest implements ModuleRequest {
}

private constructor(
public packageCache: PackageCache,
private context: PluginContext,
readonly specifier: string,
readonly fromFile: string,
Expand Down Expand Up @@ -75,6 +82,7 @@ export class RollupModuleRequest implements ModuleRequest {

alias(newSpecifier: string) {
return new RollupModuleRequest(
this.packageCache,
this.context,
newSpecifier,
this.fromFile,
Expand All @@ -90,6 +98,7 @@ export class RollupModuleRequest implements ModuleRequest {
return this;
} else {
return new RollupModuleRequest(
this.packageCache,
this.context,
this.specifier,
newFromFile,
Expand All @@ -103,6 +112,7 @@ export class RollupModuleRequest implements ModuleRequest {
}
virtualize(filename: string) {
return new RollupModuleRequest(
this.packageCache,
this.context,
virtualPrefix + filename,
this.fromFile,
Expand All @@ -115,6 +125,7 @@ export class RollupModuleRequest implements ModuleRequest {
}
withMeta(meta: Record<string, any> | undefined): this {
return new RollupModuleRequest(
this.packageCache,
this.context,
this.specifier,
this.fromFile,
Expand All @@ -127,6 +138,7 @@ export class RollupModuleRequest implements ModuleRequest {
}
notFound(): this {
return new RollupModuleRequest(
this.packageCache,
this.context,
this.specifier,
this.fromFile,
Expand All @@ -137,6 +149,7 @@ export class RollupModuleRequest implements ModuleRequest {
this.importerQueryParams
) as this;
}

async defaultResolve(): Promise<Resolution<ResolveIdResult>> {
if (this.isVirtual) {
return {
Expand All @@ -153,7 +166,9 @@ export class RollupModuleRequest implements ModuleRequest {
(err as any).code = 'MODULE_NOT_FOUND';
return { type: 'not_found', err };
}
let result = await this.context.resolve(this.specifierWithQueryParams, this.fromFileWithQueryParams, {
let resolvable = makeResolvable(this.packageCache, this.fromFile, this.specifier);
let r = this.alias(resolvable.specifier).rehome(resolvable.fromFile);
let result = await this.context.resolve(r.specifierWithQueryParams, r.fromFileWithQueryParams, {
skipSelf: true,
custom: {
embroider: {
Expand All @@ -172,6 +187,7 @@ export class RollupModuleRequest implements ModuleRequest {

resolveTo(resolution: Resolution<ResolveIdResult>): this {
return new RollupModuleRequest(
this.packageCache,
this.context,
this.specifier,
this.fromFile,
Expand All @@ -183,3 +199,58 @@ export class RollupModuleRequest implements ModuleRequest {
) as this;
}
}

/**
* For Vite to correctly detect and optimize dependencies the request must have the following conditions
* 1. specifier must be a bare import
* 2. specifier must be node resolvable without any plugins
* 3. importer must not be in node_modules
*
* this functions changes the request for rewritten addons such that they are resolvable from app root
*/
export function makeResolvable(
packageCache: PackageCache,
fromFile: string,
specifier: string
): { fromFile: string; specifier: string } {
if (fromFile.startsWith('@embroider/rewritten-packages')) {
let workingDir = locateEmbroiderWorkingDir(process.cwd());
const rewrittenRoot = resolve(workingDir, 'rewritten-packages');
fromFile = fromFile.replace('@embroider/rewritten-packages', rewrittenRoot);
}
if (fromFile && !fromFile.startsWith('./')) {
let fromPkg: Package;
try {
fromPkg = packageCache.ownerOfFile(fromFile) || packageCache.ownerOfFile(process.cwd())!;
} catch (e) {
fromPkg = packageCache.ownerOfFile(process.cwd())!;
}

if (!fromPkg.isV2App()) {
return { fromFile, specifier };
}

let pkgName = packageName(specifier);
try {
let pkg = pkgName ? packageCache.resolve(pkgName, fromPkg!) : fromPkg;
if (!pkg.isV2Addon() || !pkg.meta['auto-upgraded'] || !pkg.root.includes('rewritten-packages')) {
// some tests make addons be auto-upgraded, but are not actually in rewritten-packages
return { fromFile, specifier };
}
let levels = ['..'];
if (pkg.name.startsWith('@')) {
levels.push('..');
}
let resolvedRoot = resolve(pkg.root, ...levels, ...levels, '..');
if (specifier.startsWith(pkg.name)) {
specifier = resolve(pkg.root, ...levels, specifier);
}
specifier = specifier.replace(resolvedRoot, '@embroider/rewritten-packages').replace(/\\/g, '/');
return {
specifier,
fromFile: resolve(process.cwd(), 'package.json'),
};
} catch (e) {}
}
return { fromFile, specifier };
}
8 changes: 7 additions & 1 deletion packages/vite/src/resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,13 @@ export function resolver(): Plugin {
return await observeDepScan(this, source, importer, options);
}

let request = RollupModuleRequest.from(this, source, importer, options.custom);
let request = RollupModuleRequest.from(
resolverLoader.resolver.packageCache,
this,
source,
importer,
options.custom
);
if (!request) {
// fallthrough to other rollup plugins
return null;
Expand Down
Loading

0 comments on commit 5d2b42b

Please sign in to comment.