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(dev): path handling in dev #7180

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fix(build): retain previous qrl hashes
This pretends that the src/ dir is the root of the project as far as the optimizer is concerned, and makes sure the click-to-component knows about it.

This way the relative paths given to the optimizer are the same as before.
wmertens committed Dec 22, 2024
commit e7814bd8a8bca282ca0cb9cc1da1ff120cbc132c
4 changes: 2 additions & 2 deletions .changeset/thirty-spies-hug.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
'@builder.io/qwik': minor
'@builder.io/qwik': patch
---

FIX: click-to-component works again, and path handling inside the optimizer is simplified. Note: This changes the QRL hashes due to a different internal path
FIX: click-to-component works again, and path handling inside the optimizer is simplified.
Original file line number Diff line number Diff line change
@@ -142,7 +142,7 @@
);

globalThis.qwikOpenInEditor = function (path) {
fetch('{{BASE}}__open-in-editor?file=' + encodeURIComponent(path));
fetch('{{BASE}}__open-in-editor?file={{SRC}}' + encodeURIComponent(path));
};
document.addEventListener(
'contextmenu',
14 changes: 10 additions & 4 deletions packages/qwik/src/optimizer/src/plugins/plugin.ts
Original file line number Diff line number Diff line change
@@ -646,7 +646,12 @@ export function createPlugin(optimizerOptions: OptimizerOptions = {}) {
});
}

const filePath = path.relative(opts.rootDir, pathId);
/**
* We provide paths relative to srcDir for backwards compatibility. That way the qrl hashes
* remain unchanged.
*/
const rootDir = opts.srcDir || opts.rootDir;
const filePath = path.relative(rootDir, pathId);
const entryStrategy: EntryStrategy = opts.entryStrategy;
const transformOpts: TransformModulesOptions = {
input: [{ code, path: filePath }],
@@ -658,9 +663,10 @@ export function createPlugin(optimizerOptions: OptimizerOptions = {}) {
transpileJsx: true,
explicitExtensions: true,
preserveFilenames: true,
// TODO remove
// TODO remove this in v2
srcDir: '',
rootDir: opts.rootDir,
// Sourcemaps need to know this
rootDir,
mode,
scope: opts.scope || undefined,
isServer,
@@ -695,7 +701,7 @@ export function createPlugin(optimizerOptions: OptimizerOptions = {}) {
const deps = new Set<string>();
for (const mod of newOutput.modules) {
if (mod !== module) {
// All modules are in the same directory as the parent
// All segments are in the same directory as the parent
const key = path.join(dir, mod.segment!.canonicalFilename + '.' + mod.segment?.extension);
debug(`transform(${count})`, `segment ${key}`, mod.segment!.displayName);
parentIds.set(key, id);
30 changes: 19 additions & 11 deletions packages/qwik/src/optimizer/src/plugins/vite-dev-server.ts
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ import { SYNC_QRL } from '../../../core/qrl/qrl-class';
import type { OptimizerSystem, Path, QwikManifest, SymbolMapper, SymbolMapperFn } from '../types';
import clickToComponentSrc from './click-to-component.html?raw';
import errorHost from './error-host.html?raw';
import imageDevTools from './image-size-runtime.html?raw';
import imageDevToolsSrc from './image-size-runtime.html?raw';
import perfWarning from './perf-warning.html?raw';
import { parseId, type NormalizedQwikPluginOptions } from './plugin';
import type { QwikViteDevResponse } from './vite';
@@ -27,7 +27,7 @@ function getOrigin(req: IncomingMessage) {
return `${protocol}://${host}`;
}

function createSymbolMapper(base: string): SymbolMapperFn {
function createSymbolMapper(base: string, srcRelative: string): SymbolMapperFn {
return (
symbolName: string,
_mapper: SymbolMapper | undefined,
@@ -45,7 +45,7 @@ function createSymbolMapper(base: string): SymbolMapperFn {
}
// In dev mode, the `parent` is the Vite URL for the parent, not the real absolute path.
// It is always absolute but when on Windows that's without a /
const qrlFile = `${base}${parent.startsWith('/') ? parent.slice(1) : parent}_${symbolName}.js`;
const qrlFile = `${base}${srcRelative}${parent.startsWith('/') ? parent.slice(1) : parent}_${symbolName}.js`;
return [symbolName, qrlFile];
};
}
@@ -77,7 +77,10 @@ export async function configureDevServer(
clientDevInput: string | undefined,
devSsrServer: boolean
) {
symbolMapper = lazySymbolMapper = createSymbolMapper(base);
symbolMapper = lazySymbolMapper = createSymbolMapper(
base,
opts.srcDir ? `${path.relative(opts.rootDir, opts.srcDir)}/` : ''
);
if (!devSsrServer) {
// we just needed the symbolMapper
return;
@@ -212,7 +215,7 @@ export async function configureDevServer(
if ('html' in result) {
res.write((result as any).html);
}
res.write(END_SSR_SCRIPT(opts, base));
res.write(END_SSR_SCRIPT(path, opts, base));
res.end();
} else {
next();
@@ -376,25 +379,30 @@ function relativeURL(url: string, base: string) {
return url;
}

const DEV_QWIK_INSPECTOR = (opts: NormalizedQwikPluginOptions['devTools'], base: string) => {
const DEV_QWIK_INSPECTOR = (path: Path, opts: NormalizedQwikPluginOptions, base: string) => {
const { srcDir, rootDir } = opts;
const srcRelative = srcDir ? `${path.relative(rootDir, srcDir)}/` : '';
const { clickToSource, imageDevTools } = opts.devTools;
const qwikdevtools = {
hotKeys: opts.clickToSource ?? [],
hotKeys: clickToSource ?? [],
};
return (
`<script>
globalThis.qwikdevtools = ${JSON.stringify(qwikdevtools)};
</script>` +
(opts.imageDevTools ? imageDevTools : '') +
(opts.clickToSource ? clickToComponentSrc.replaceAll('{{BASE}}', base) : '')
(imageDevTools ? imageDevToolsSrc : '') +
(clickToSource
? clickToComponentSrc.replaceAll('{{BASE}}', base).replaceAll('{{SRC}}', srcRelative)
: '')
);
};

const END_SSR_SCRIPT = (opts: NormalizedQwikPluginOptions, base: string) => `
const END_SSR_SCRIPT = (path: Path, opts: NormalizedQwikPluginOptions, base: string) => `
<style>${VITE_ERROR_OVERLAY_STYLES}</style>
<script type="module" src="/@vite/client"></script>
${errorHost}
${perfWarning}
${DEV_QWIK_INSPECTOR(opts.devTools, base)}
${DEV_QWIK_INSPECTOR(path, opts, base)}
`;

function getViteDevIndexHtml(entryUrl: string, serverData: Record<string, any>) {
10 changes: 5 additions & 5 deletions starters/e2e/e2e.render.spec.ts
Original file line number Diff line number Diff line change
@@ -28,31 +28,31 @@ test.describe("render", () => {

const attributes = page.locator("#attributes");

await expect(attributes).toHaveClass("⭐️ju3o0m-1 even stable0");
await expect(attributes).toHaveClass("⭐️unvb18-1 even stable0");
await expect(attributes).toHaveAttribute("aria-hidden", "true");
await expect(attributes).toHaveAttribute("preventdefault:click", "");

await increment.click();

await expect(attributes).toHaveClass("⭐️ju3o0m-1 odd stable0");
await expect(attributes).toHaveClass("⭐️unvb18-1 odd stable0");
await expect(attributes).toHaveAttribute("aria-hidden", "true");
await expect(attributes).toHaveAttribute("preventdefault:click", "");

await toggle.click();

await expect(attributes).toHaveClass("⭐️ju3o0m-1");
await expect(attributes).toHaveClass("⭐️unvb18-1");
await expect(attributes).not.hasAttribute("aria-hidden");
await expect(attributes).not.hasAttribute("preventdefault:click");

await increment.click();

await expect(attributes).toHaveClass("⭐️ju3o0m-1");
await expect(attributes).toHaveClass("⭐️unvb18-1");
await expect(attributes).not.hasAttribute("aria-hidden");
await expect(attributes).not.hasAttribute("preventdefault:click");

await toggle.click();

await expect(attributes).toHaveClass("⭐️ju3o0m-1 even stable0");
await expect(attributes).toHaveClass("⭐️unvb18-1 even stable0");
await expect(attributes).toHaveAttribute("aria-hidden", "true");
await expect(attributes).toHaveAttribute("preventdefault:click", "");
});