Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix fastboot test #1902

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
17 changes: 0 additions & 17 deletions packages/compat/src/compat-app-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -754,23 +754,6 @@ export class CompatAppBuilder {
private gatherAssets(inputPaths: OutputPaths<TreeNames>): Asset[] {
// first gather all the assets out of addons
let assets: Asset[] = [];

if (this.activeFastboot) {
const source = `
(function(){
var key = '_embroider_macros_runtime_config';
if (!window[key]){ window[key] = [];}
window[key].push(function(m) {
m.setGlobalConfig('fastboot', Object.assign({}, m.getGlobalConfig().fastboot, { isRunning: true }));
});
}())`;
assets.push({
kind: 'in-memory',
source,
relativePath: 'assets/embroider_macros_fastboot_init.js',
});
}

// and finally tack on the ones from our app itself
return assets.concat(this.extractAssets(inputPaths));
}
Expand Down
16 changes: 5 additions & 11 deletions packages/core/src/module-resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ export class Resolver {
return this.external('early require', request, request.specifier);
}

request = this.handleFastbootSwitch(request);
request = await this.handleFastbootSwitch(request);
request = await this.handleGlobalsCompat(request);
request = this.handleImplicitModules(request);
request = this.handleImplicitTestScripts(request);
Expand Down Expand Up @@ -335,7 +335,7 @@ export class Resolver {
return request;
}

private handleFastbootSwitch<R extends ModuleRequest>(request: R): R {
private async handleFastbootSwitch<R extends ModuleRequest>(request: R): Promise<R> {
if (isTerminal(request)) {
return request;
}
Expand Down Expand Up @@ -369,15 +369,9 @@ export class Resolver {
} else {
targetFile = fastbootFile.localFilename;
}
return logTransition(
'matched app entry',
request,
// deliberately not using rehome because we want
// generateFastbootSwitch to see that this request is coming *from*
// a fastboot switch so it won't cycle back around. Instead we make
// the targetFile relative to the fromFile that we already have.
request.alias(explicitRelative(dirname(request.fromFile), resolve(pkg.root, targetFile)))
);

let resolution = await request.alias(targetFile).rehome(resolve(pkg.root, 'package.json')).defaultResolve();
return logTransition('matched app entry', request, request.resolveTo(resolution));
}
}

Expand Down
9 changes: 9 additions & 0 deletions packages/core/src/virtual-content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import { decodeImplicitTestScripts, renderImplicitTestScripts } from './virtual-
import { decodeTestSupportStyles, renderTestSupportStyles } from './virtual-test-support-styles';
import { decodeVirtualVendor, renderVendor } from './virtual-vendor';
import { decodeVirtualVendorStyles, renderVendorStyles } from './virtual-vendor-styles';
import {
decodeEmbroiderMacrosFastbootInit,
renderEmbroiderMacrosFastbootInit,
} from './virtual-embroider-macros-fastboot-init';

const externalESPrefix = '/@embroider/ext-es/';
const externalCJSPrefix = '/@embroider/ext-cjs/';
Expand Down Expand Up @@ -64,6 +68,11 @@ export function virtualContent(filename: string, resolver: Resolver): VirtualCon
return renderTestSupportStyles(filename, resolver);
}

let isEmbroiderMacrosFastbootInit = decodeEmbroiderMacrosFastbootInit(filename);
if (isEmbroiderMacrosFastbootInit) {
return renderEmbroiderMacrosFastbootInit();
}

throw new Error(`not an @embroider/core virtual file: ${filename}`);
}

Expand Down
18 changes: 18 additions & 0 deletions packages/core/src/virtual-embroider-macros-fastboot-init.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type { VirtualContentResult } from './virtual-content';

export function decodeEmbroiderMacrosFastbootInit(filename: string): boolean {
return filename.includes('embroider_macros_fastboot_init.js');
}

export function renderEmbroiderMacrosFastbootInit(): VirtualContentResult {
const src = `
(function(){
var key = '_embroider_macros_runtime_config';
if (!window[key]){ window[key] = [];}
window[key].push(function(m) {
m.setGlobalConfig('fastboot', Object.assign({}, m.getGlobalConfig().fastboot, { isRunning: true }));
});
}())
`;
return { src, watches: [] };
}
3 changes: 2 additions & 1 deletion packages/vite/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export * from './src/hbs.js';
export * from './src/scripts.js';
export * from './src/template-tag.js';
export * from './src/optimize-deps.js';
export * from './src/assets.js';
export * from './src/build.js';
export * from './src/assets.js';
export * from './src/fastboot.js';
export * from './src/content-for.js';
1 change: 1 addition & 0 deletions packages/vite/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ export * from './src/template-tag.js';
export * from './src/optimize-deps.js';
export * from './src/build.js';
export * from './src/assets.js';
export * from './src/fastboot.js';
export * from './src/content-for.js';
36 changes: 36 additions & 0 deletions packages/vite/src/fastboot.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { locateEmbroiderWorkingDir, virtualContent, ResolverLoader } from '@embroider/core';
import { readFileSync } from 'fs-extra';
import { resolve } from 'path';
import type { Plugin } from 'vite';

export function fastboot(): Plugin {
let resolverLoader = new ResolverLoader(process.cwd());

return {
name: 'embroider-fastboot',

buildEnd: {
// we need to wait for the compatBuild plugin's buildStart hook to finish
// so that the resolver config exists before we try to read it.
sequential: true,
order: 'post',
async handler() {
const app = resolverLoader.resolver.options.engines[0];
const hasFastboot = app.activeAddons.find(addon => addon.name === 'ember-cli-fastboot');
if (hasFastboot) {
this.emitFile({
type: 'asset',
fileName: 'assets/embroider_macros_fastboot_init.js',
source: virtualContent('assets/embroider_macros_fastboot_init.js', resolverLoader.resolver).src,
});
// TODO: don't rely on rewritten-app
this.emitFile({
type: 'asset',
fileName: 'package.json',
source: readFileSync(resolve(locateEmbroiderWorkingDir(process.cwd()), 'rewritten-app', 'package.json')),
});
}
},
},
};
}
13 changes: 11 additions & 2 deletions packages/vite/src/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ import type { PluginContext, ResolveIdResult } from 'rollup';

export const virtualPrefix = 'embroider_virtual:';

// TODO: Query params should be bundler-specific and not be sent to the
// bundler-agnostic part of Embroider (e.g. Vite-specific ?direct param)
// However, Fastboot currently relies on the ?names query param, so this
// constant is used as a quick fix to keep the query param when requesting
// Fastboot-related virtual content.
export const fastbootQueryParam = 'names';

export class RollupModuleRequest implements ModuleRequest {
static from(
context: PluginContext,
Expand Down Expand Up @@ -166,8 +173,10 @@ export class RollupModuleRequest implements ModuleRequest {
},
});
if (result) {
let { pathname } = new URL(result.id, 'http://example.com');
return { type: 'found', filename: pathname, result, isVirtual: this.isVirtual };
// strip Vite-specific query params but keep FastBoot ones
let { pathname, searchParams } = new URL(result.id, 'http://example.com');
let filename = searchParams.get(fastbootQueryParam) ? result.id : pathname;
return { type: 'found', filename, result, isVirtual: this.isVirtual };
} else {
return { type: 'not_found', err: undefined };
}
Expand Down
27 changes: 22 additions & 5 deletions packages/vite/src/resolver.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
import type { Plugin, ViteDevServer } from 'vite';
import { virtualContent, ResolverLoader } from '@embroider/core';
import { RollupModuleRequest, virtualPrefix } from './request';
import { type PluginItem, transform } from '@babel/core';
import { locateEmbroiderWorkingDir, virtualContent, ResolverLoader } from '@embroider/core';
import { fastbootQueryParam, RollupModuleRequest, virtualPrefix } from './request';
import assertNever from 'assert-never';
import makeDebug from 'debug';
import { resolve } from 'path';
import { readJSONSync } from 'fs-extra';

const debug = makeDebug('embroider:vite');

export function resolver(): Plugin {
let resolverLoader = new ResolverLoader(process.cwd());
let server: ViteDevServer;
let virtualDeps: Map<string, string[]> = new Map();
let macrosConfig: PluginItem | undefined;

return {
name: 'embroider-resolver',
Expand Down Expand Up @@ -53,11 +56,18 @@ export function resolver(): Plugin {
},
load(id) {
if (id.startsWith(virtualPrefix)) {
let { pathname } = new URL(id, 'http://example.com');
let { src, watches } = virtualContent(pathname.slice(virtualPrefix.length + 1), resolverLoader.resolver);
// strip Vite-specific query params but keep FastBoot ones
let { pathname, searchParams } = new URL(id, 'http://example.com');
let specifier = searchParams.get(fastbootQueryParam) ? id : pathname;
let { src, watches } = virtualContent(specifier.slice(virtualPrefix.length + 1), resolverLoader.resolver);
virtualDeps.set(id, watches);
server?.watcher.add(watches);
return src;
if (!macrosConfig) {
macrosConfig = readJSONSync(
resolve(locateEmbroiderWorkingDir(process.cwd()), 'rewritten-app', 'macros-config.json')
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To change after rebase, relates to #1935:

resolve(locateEmbroiderWorkingDir(process.cwd()), 'macros-config.json')

) as PluginItem;
}
return pathname.endsWith('.css') ? src : runMacros(src, id, macrosConfig);
}
},
buildEnd() {
Expand All @@ -80,3 +90,10 @@ export function resolver(): Plugin {
},
};
}

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