Skip to content

Commit

Permalink
[wip] esbuild resolver
Browse files Browse the repository at this point in the history
  • Loading branch information
ef4 authored and mansona committed Oct 26, 2023
1 parent 4b21b26 commit 20d0cf1
Show file tree
Hide file tree
Showing 11 changed files with 263 additions and 249 deletions.
4 changes: 4 additions & 0 deletions packages/compat/src/compat-app-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1000,6 +1000,10 @@ export class CompatAppBuilder {
this.addResolverConfig(resolverConfig);
let babelConfig = this.babelConfig(resolverConfig);
this.addBabelConfig(babelConfig);
writeFileSync(
join(this.root, 'macros-config.json'),
JSON.stringify(this.compatApp.macrosConfig.babelPluginConfig()[0], null, 2)
);
}

private combinePackageJSON(meta: AppMeta): object {
Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/module-resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,10 @@ export class Resolver {
return logTransition('early exit', request);
}

if (request.specifier === 'require') {
return this.external('early require', request, request.specifier);
}

request = this.handleFastbootSwitch(request);
request = this.handleGlobalsCompat(request);
request = this.handleImplicitModules(request);
Expand Down
1 change: 1 addition & 0 deletions packages/vite/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './src/resolver.js';
export * from './src/esbuild-resolver.js';
export * from './src/hbs.js';
export * from './src/scripts.js';
export * from './src/template-tag.js';
Expand Down
1 change: 1 addition & 0 deletions packages/vite/index.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './src/resolver.js';
export * from './src/esbuild-resolver.js';
export * from './src/hbs.js';
export * from './src/scripts.js';
export * from './src/template-tag.js';
Expand Down
4 changes: 4 additions & 0 deletions packages/vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,21 @@
"test": "jest"
},
"dependencies": {
"@babel/core": "^7.22.9",
"@embroider/macros": "workspace:*",
"@rollup/pluginutils": "^4.1.1",
"assert-never": "^1.2.1",
"content-tag": "^1.1.2",
"debug": "^4.3.2",
"esbuild": "^0.17.19",
"fs-extra": "^10.0.0",
"jsdom": "^16.6.0",
"source-map-url": "^0.4.1",
"terser": "^5.7.0"
},
"devDependencies": {
"@embroider/core": "workspace:^",
"@types/babel__core": "^7.20.1",
"@types/debug": "^4.1.5",
"@types/jsdom": "^16.2.11",
"@types/fs-extra": "^9.0.12",
Expand Down
44 changes: 44 additions & 0 deletions packages/vite/src/esbuild-request.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { type ModuleRequest, cleanUrl } from '@embroider/core';

export const virtualNamespace = 'embroider';

export class EsBuildModuleRequest implements ModuleRequest {
static from(
source: string,
importer: string | undefined,
pluginData: Record<string, any> | undefined
): EsBuildModuleRequest | undefined {
if (!(pluginData?.embroider?.enableCustomResolver ?? true)) {
return;
}

if (source && importer && source[0] !== '\0') {
let fromFile = cleanUrl(importer);
return new EsBuildModuleRequest(source, fromFile, pluginData?.embroider?.meta, false);
}
}

private constructor(
readonly specifier: string,
readonly fromFile: string,
readonly meta: Record<string, any> | undefined,
readonly isVirtual: boolean
) {}

alias(newSpecifier: string) {
return new EsBuildModuleRequest(newSpecifier, this.fromFile, this.meta, this.isVirtual) as this;
}
rehome(newFromFile: string) {
if (this.fromFile === newFromFile) {
return this;
} else {
return new EsBuildModuleRequest(this.specifier, newFromFile, this.meta, this.isVirtual) as this;
}
}
virtualize(filename: string) {
return new EsBuildModuleRequest(filename, this.fromFile, this.meta, true) as this;
}
withMeta(meta: Record<string, any> | undefined): this {
return new EsBuildModuleRequest(this.specifier, this.fromFile, meta, this.isVirtual) as this;
}
}
101 changes: 101 additions & 0 deletions packages/vite/src/esbuild-resolver.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import type { Plugin as EsBuildPlugin, ImportKind, OnResolveResult, PluginBuild } from 'esbuild';
import { type PluginItem, transform } from '@babel/core';
import {
type Resolution,
type ResolverFunction,
ResolverLoader,
virtualContent,
locateEmbroiderWorkingDir,
} from '@embroider/core';
import { readFileSync, readJSONSync } from 'fs-extra';
import { EsBuildModuleRequest } from './esbuild-request';
import assertNever from 'assert-never';
import { dirname, resolve } from 'path';

export function esBuildResolver(root = process.cwd()): EsBuildPlugin {
let resolverLoader = new ResolverLoader(process.cwd());
let macrosConfig: PluginItem | undefined;

return {
name: 'embroider-esbuild-resolver',
setup(build) {
build.onResolve({ filter: /./ }, async ({ path, importer, pluginData, kind }) => {
let request = EsBuildModuleRequest.from(path, importer, pluginData);
if (!request) {
return null;
}
let resolution = await resolverLoader.resolver.resolve(request, defaultResolve(build, kind));
switch (resolution.type) {
case 'found':
return resolution.result;
case 'not_found':
return resolution.err;
default:
throw assertNever(resolution);
}
});

build.onLoad({ namespace: 'embroider', filter: /./ }, ({ path }) => {
let src = virtualContent(path, resolverLoader.resolver);
if (!macrosConfig) {
macrosConfig = readJSONSync(
resolve(locateEmbroiderWorkingDir(root), 'rewritten-app', 'macros-config.json')
) as PluginItem;
}
return { contents: runMacros(src, path, macrosConfig) };
});

build.onLoad({ filter: /\.js$/ }, ({ path, namespace }) => {
let src: string;
if (namespace === 'embroider') {
src = virtualContent(path, resolverLoader.resolver);
} else {
src = readFileSync(path, 'utf8');
}
if (!macrosConfig) {
macrosConfig = readJSONSync(
resolve(locateEmbroiderWorkingDir(root), 'rewritten-app', 'macros-config.json')
) as PluginItem;
}
return { contents: runMacros(src, path, macrosConfig) };
});
},
};
}

function runMacros(src: string, filename: string, macrosConfig: PluginItem): string {
return transform(src, {
filename,
plugins: [macrosConfig],
})!.code!;
}

function defaultResolve(
context: PluginBuild,
kind: ImportKind
): ResolverFunction<EsBuildModuleRequest, Resolution<OnResolveResult, OnResolveResult>> {
return async (request: EsBuildModuleRequest) => {
if (request.isVirtual) {
return {
type: 'found',
result: { path: request.specifier, namespace: 'embroider' },
};
}
let result = await context.resolve(request.specifier, {
importer: request.fromFile,
resolveDir: dirname(request.fromFile),
kind,
pluginData: {
embroider: {
enableCustomResolver: false,
meta: request.meta,
},
},
});
if (result.errors.length > 0) {
return { type: 'not_found', err: result };
} else {
return { type: 'found', result };
}
};
}
7 changes: 6 additions & 1 deletion packages/vite/src/optimize-deps.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import { esBuildResolver } from './esbuild-resolver';

export interface OptimizeDeps {
exclude?: string[];
[key: string]: unknown;
}

export function optimizeDeps(): OptimizeDeps {
return {
exclude: ['@embroider/macros'],
include: ['ember-welcome-page'],
esbuildOptions: {
plugins: [esBuildResolver()],
},
};
}
3 changes: 3 additions & 0 deletions packages/vite/src/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ export class RollupModuleRequest implements ModuleRequest {
if (!(custom?.embroider?.enableCustomResolver ?? true)) {
return;
}
if (custom?.depScan) {
return;
}

if (source && importer && source[0] !== '\0') {
let nonVirtual: string;
Expand Down
14 changes: 6 additions & 8 deletions packages/vite/src/resolver.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
import type { PluginContext, ResolveIdResult } from 'rollup';
import type { Plugin } from 'vite';
import { join } from 'path';
import type { Resolution, ResolverFunction, ResolverOptions } from '@embroider/core';
import { Resolver, locateEmbroiderWorkingDir, virtualContent } from '@embroider/core';
import { readJSONSync } from 'fs-extra';
import type { Resolution, ResolverFunction } from '@embroider/core';
import { virtualContent, ResolverLoader } from '@embroider/core';
import { RollupModuleRequest, virtualPrefix } from './request';
import assertNever from 'assert-never';

export function resolver(): Plugin {
let resolverOptions: ResolverOptions = readJSONSync(join(locateEmbroiderWorkingDir(process.cwd()), 'resolver.json'));
let resolver = new Resolver(resolverOptions);
let resolverLoader = new ResolverLoader(process.cwd());

return {
name: 'embroider-resolver',
Expand All @@ -20,7 +17,7 @@ export function resolver(): Plugin {
// fallthrough to other rollup plugins
return null;
}
let resolution = await resolver.resolve(request, defaultResolve(this));
let resolution = await resolverLoader.resolver.resolve(request, defaultResolve(this));
switch (resolution.type) {
case 'found':
return resolution.result;
Expand All @@ -32,7 +29,7 @@ export function resolver(): Plugin {
},
load(id) {
if (id.startsWith(virtualPrefix)) {
return virtualContent(id.slice(virtualPrefix.length), resolver);
return virtualContent(id.slice(virtualPrefix.length), resolverLoader.resolver);
}
},
};
Expand All @@ -50,6 +47,7 @@ function defaultResolve(context: PluginContext): ResolverFunction<RollupModuleRe
skipSelf: true,
custom: {
embroider: {
enableCustomResolver: false,
meta: request.meta,
},
},
Expand Down
Loading

0 comments on commit 20d0cf1

Please sign in to comment.