Skip to content

Commit

Permalink
Merge pull request embroider-build#1974 from embroider-build/esbuild-…
Browse files Browse the repository at this point in the history
…virtual-relative

esbuild-resolver: handle relative imports in virtual files
  • Loading branch information
mansona authored Jun 11, 2024
2 parents e5ef9b9 + 4464aad commit 0277294
Showing 1 changed file with 32 additions and 5 deletions.
37 changes: 32 additions & 5 deletions packages/vite/src/esbuild-resolver.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import type { Plugin as EsBuildPlugin } from 'esbuild';
import { type PluginItem, transform } from '@babel/core';
import { ResolverLoader, virtualContent, locateEmbroiderWorkingDir } from '@embroider/core';
import { ResolverLoader, virtualContent, locateEmbroiderWorkingDir, explicitRelative } from '@embroider/core';
import { readFileSync, readJSONSync } from 'fs-extra';
import { EsBuildModuleRequest } from './esbuild-request';
import assertNever from 'assert-never';
import { resolve } from 'path';
import { dirname, isAbsolute, resolve } from 'path';
import { hbsToJS } from '@embroider/core';
import { Preprocessor } from 'content-tag';

Expand Down Expand Up @@ -32,10 +32,11 @@ export function esBuildResolver(root = process.cwd()): EsBuildPlugin {
let firstFailure;

for (let candidate of candidates(path)) {
let result = await build.resolve(candidate, {
let { specifier, fromFile } = adjustVirtualImport(candidate, importer);
let result = await build.resolve(specifier, {
namespace,
resolveDir,
importer,
importer: fromFile,
kind,
pluginData: { ...pluginData, embroiderExtensionSearch: true },
});
Expand All @@ -52,7 +53,8 @@ export function esBuildResolver(root = process.cwd()): EsBuildPlugin {
return firstFailure;
});
build.onResolve({ filter: /./ }, async ({ path, importer, pluginData, kind }) => {
let request = EsBuildModuleRequest.from(build, kind, path, importer, pluginData);
let { specifier, fromFile } = adjustVirtualImport(path, importer);
let request = EsBuildModuleRequest.from(build, kind, specifier, fromFile, pluginData);
if (!request) {
return null;
}
Expand Down Expand Up @@ -132,3 +134,28 @@ function runMacros(src: string, filename: string, macrosConfig: PluginItem): str
plugins: [macrosConfig],
})!.code!;
}

// esbuild's 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 "/a/real/path/thing.js", but esbuild won't do
// that path adjustment until after checking whether VIRTUAL_SUBDIR actually
// exists.
//
// We can do the path adjustments before doing resolve.
function adjustVirtualImport(specifier: string, fromFile: string): { specifier: string; fromFile: string } {
let fromDir = dirname(fromFile);
if (!isAbsolute(specifier) && specifier.startsWith('.')) {
let targetPath = resolve(fromDir, specifier);
let newFromDir = dirname(targetPath);
if (fromDir !== newFromDir) {
return {
specifier: explicitRelative(newFromDir, targetPath),
// we're resolving *from* the destination, because we need to resolve
// from a file that exists, and we know that (if this was supposed to
// succeed at all) that file definitely does
fromFile: targetPath,
};
}
}
return { specifier, fromFile };
}

0 comments on commit 0277294

Please sign in to comment.