From 69c2603d3176d8b0eef7a92b3225240bc6ee7ae9 Mon Sep 17 00:00:00 2001 From: Amine Ilidrissi <38422328+aminevg@users.noreply.github.com> Date: Mon, 16 Mar 2026 13:42:56 +0900 Subject: [PATCH 1/2] refactor: refactor dev address handling --- packages/core/src/dev/constants.ts | 1 + packages/core/src/dev/resolve.ts | 9 +++---- packages/core/src/dev/setup.ts | 32 +++++++++++------------- packages/core/src/types.ts | 15 +++++------ packages/core/src/utils/rewriteFsUrls.ts | 11 -------- packages/core/tests/fixture.ts | 19 +++++++++----- packages/hono/src/dev.ts | 14 +++++------ 7 files changed, 47 insertions(+), 54 deletions(-) create mode 100644 packages/core/src/dev/constants.ts delete mode 100644 packages/core/src/utils/rewriteFsUrls.ts diff --git a/packages/core/src/dev/constants.ts b/packages/core/src/dev/constants.ts new file mode 100644 index 0000000..67ab1e6 --- /dev/null +++ b/packages/core/src/dev/constants.ts @@ -0,0 +1 @@ +export const MIGHTY_DEV_PLACEHOLDER_ADDRESS = "http://mighty-placeholder.test"; diff --git a/packages/core/src/dev/resolve.ts b/packages/core/src/dev/resolve.ts index f70a9db..d678e70 100644 --- a/packages/core/src/dev/resolve.ts +++ b/packages/core/src/dev/resolve.ts @@ -1,6 +1,7 @@ import path from "node:path"; import { fileURLToPath } from "node:url"; import type { DevEnvironment } from "vite"; +import { MIGHTY_DEV_PLACEHOLDER_ADDRESS } from "./constants"; /** * Creates the `resolve` callback passed to AstroContainer. @@ -9,20 +10,18 @@ import type { DevEnvironment } from "vite"; * fully-qualified Vite dev-server URLs the browser can fetch. */ export function createResolve( - getAddress: () => string, ssrEnvironment: DevEnvironment, root: URL, ): (s: string) => Promise { return async (s: string) => { - const address = getAddress(); if (s.startsWith("astro:scripts")) { - return `${address}/@id/${s}`; + return `${MIGHTY_DEV_PLACEHOLDER_ADDRESS}/@id/${s}`; } if (s.startsWith("/@id")) { - return `${address}${s}`; + return `${MIGHTY_DEV_PLACEHOLDER_ADDRESS}${s}`; } const resolved = await resolveIdToUrl(ssrEnvironment, s, root); - return `${address}${resolved}`; + return `${MIGHTY_DEV_PLACEHOLDER_ADDRESS}${resolved}`; }; } diff --git a/packages/core/src/dev/setup.ts b/packages/core/src/dev/setup.ts index b9d0a3e..897267b 100644 --- a/packages/core/src/dev/setup.ts +++ b/packages/core/src/dev/setup.ts @@ -13,11 +13,11 @@ import { getStylesForURL } from "@/dev/css"; import type { MightyDevMiddleware, MightyDevOptions, - MightyRenderRequest, + MightyRenderDevRequest, } from "@/types"; import { dotStringToPath } from "@/utils/dotStringToPath"; import { injectTagsIntoHead } from "@/utils/injectTagsIntoHead"; -import { rewriteFsUrls } from "@/utils/rewriteFsUrls"; +import { MIGHTY_DEV_PLACEHOLDER_ADDRESS } from "./constants"; import type { MightyRenderFunction, MightyStartContainerFunction, @@ -108,11 +108,7 @@ export async function setupDev( createContainer: MightyStartContainerFunction; }; - const resolve = createResolve( - options.getAddress, - viteServer.environments.ssr, - finalConfig.root, - ); + const resolve = createResolve(viteServer.environments.ssr, finalConfig.root); await createContainer(loadedRenderers, resolve); @@ -138,7 +134,7 @@ export async function setupDev( tagName: "script", properties: { type: "module", - src: `${options.getAddress()}/@id/astro:scripts/page.js`, + src: `${MIGHTY_DEV_PLACEHOLDER_ADDRESS}/@id/astro:scripts/page.js`, }, children: [], }, @@ -146,11 +142,11 @@ export async function setupDev( : () => []; const renderComponentByPath = async ( - data: Omit & { + data: Omit & { componentPath: `${string}.astro`; }, ) => { - const { componentPath, props, context, partial = true } = data; + const { componentPath, props, context, partial = true, address } = data; const [rawRenderedComponent, styleTags] = await Promise.all([ renderComponent({ @@ -172,17 +168,17 @@ export async function setupDev( ), ]); - const renderedComponent = rewriteFsUrls( - rawRenderedComponent, - options.getAddress(), - ); + // Rewrite image URLs to include the dev address + const renderedComponent = rawRenderedComponent + .replace(/(["'(])\/@fs\//g, `$1${MIGHTY_DEV_PLACEHOLDER_ADDRESS}/@fs/`) + .replaceAll(MIGHTY_DEV_PLACEHOLDER_ADDRESS, address); const viteClientScript: Element = { type: "element", tagName: "script", properties: { type: "module", - src: `${options.getAddress()}/@vite/client`, + src: `${MIGHTY_DEV_PLACEHOLDER_ADDRESS}/@vite/client`, }, children: [], }; @@ -202,9 +198,9 @@ export async function setupDev( return { viteMiddleware: viteServer.middlewares, stop: () => viteServer.close(), - render: async (request: MightyRenderRequest) => { + render: async (request: MightyRenderDevRequest) => { try { - const { component, props, context, partial } = request; + const { component, props, context, partial, address } = request; const componentPath: `${string}.astro` = `${path.join( finalConfig.srcDir.pathname, @@ -226,6 +222,7 @@ export async function setupDev( props, context, partial, + address, }), }; } catch (error) { @@ -249,6 +246,7 @@ export async function setupDev( }, context: {}, partial: false, + address: request.address, }), }; } diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index 2e3b804..afa69a2 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -13,12 +13,6 @@ export type MightyServerOptions = { }; export type MightyDevOptions = MightyServerOptions & { - /** - * Specifies the address the Mighty development server will be available at. - * - * This is used to get correct paths for client-side assets. - */ - getAddress: () => string; /** * Whether to show the Mighty error page when an error occurs. * @default true @@ -49,10 +43,17 @@ export type MightyRenderRequest = { partial?: boolean; }; +export type MightyRenderDevRequest = MightyRenderRequest & { + /** + * The address the Mighty development server is available at. + */ + address: string; +}; + export type MightyDevMiddleware = { /** Renders an Astro component. */ render: ( - req: MightyRenderRequest, + req: MightyRenderDevRequest, ) => Promise<{ status: number; content: string }>; /** * The Connect middleware provider by the Vite/Astro development server. diff --git a/packages/core/src/utils/rewriteFsUrls.ts b/packages/core/src/utils/rewriteFsUrls.ts deleted file mode 100644 index caf68f8..0000000 --- a/packages/core/src/utils/rewriteFsUrls.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Rewrite bare `/@fs/` URLs to include the Mighty dev address. - * - * Astro's image vite plugin (`astro:assets:esm`) hardcodes image `src` as - * `/@fs/` without the Vite base prefix. Without rewriting, the - * browser requests `/@fs/...` from the app server instead of the Vite dev - * server, resulting in a 404. - */ -export function rewriteFsUrls(html: string, address: string): string { - return html.replace(/(["'(])\/@fs\//g, `$1${address}/@fs/`); -} diff --git a/packages/core/tests/fixture.ts b/packages/core/tests/fixture.ts index e4469ea..30beba2 100644 --- a/packages/core/tests/fixture.ts +++ b/packages/core/tests/fixture.ts @@ -6,10 +6,16 @@ import { toFetchResponse, toReqRes } from "fetch-to-node"; import { build } from "@/build"; import { setupDev } from "@/dev/setup"; import { setupStart } from "@/start/setup"; -import type { MightyDevOptions, MightyServerOptions } from "@/types"; +import type { + MightyDevOptions, + MightyRenderRequest, + MightyServerOptions, +} from "@/types"; import { dotStringToPath } from "@/utils/dotStringToPath"; -export type DevRenderFunction = Awaited>["render"]; +export type DevRenderFunction = ( + req: MightyRenderRequest, +) => Promise<{ status: number; content: string }>; export type StartRenderFunction = Awaited< ReturnType >["render"]; @@ -21,7 +27,7 @@ export type GetFromViteMiddlewareFunction = ( export function getFixture(fixtureName: string): { fixtureRoot: string; outDir: string; - startDevServer: (params?: Omit) => Promise<{ + startDevServer: (params?: MightyDevOptions) => Promise<{ render: DevRenderFunction; getFromViteMiddleware: GetFromViteMiddlewareFunction; stop: () => Promise; @@ -60,12 +66,14 @@ export function getFixture(fixtureName: string): { }); }; + const DEV_TEST_ADDRESS = "http://host-placeholder.test"; + return { fixtureRoot, outDir, startDevServer: async (params) => { const { - render, + render: rawRender, stop: stopDevServer, viteMiddleware, } = await setupDev({ @@ -77,11 +85,10 @@ export function getFixture(fixtureName: string): { }, params?.config ?? {}, ), - getAddress: () => "http://host-placeholder.test", }); return { - render, + render: (req) => rawRender({ ...req, address: DEV_TEST_ADDRESS }), getFromViteMiddleware: async (path: string) => { const { req, res } = toReqRes( new Request( diff --git a/packages/hono/src/dev.ts b/packages/hono/src/dev.ts index e01da0f..1f1ebc3 100644 --- a/packages/hono/src/dev.ts +++ b/packages/hono/src/dev.ts @@ -8,16 +8,14 @@ import { runConnectMiddleware } from "./utils/runConnectMiddleware.ts"; const MIGHTY_DEV_ROOT = "/__MIGHTY_DEV_ADDRESS__"; export function devMiddleware( - options?: Omit, + options?: MightyDevOptions, ): StartMightyServerMiddlewareHandler { - let rootAddress: string = ""; const mightyConfig: MightyDevOptions = { ...options, config: mergeConfig( { root: "./astro", vite: { base: MIGHTY_DEV_ROOT } }, options?.config ?? {}, ), - getAddress: () => new URL(MIGHTY_DEV_ROOT, rootAddress).toString(), }; const setupDevPromise = dev(mightyConfig); @@ -25,18 +23,18 @@ export function devMiddleware( return createMiddleware(async (c, next) => { const { render, viteMiddleware } = await setupDevPromise; - if (!rootAddress) { - rootAddress = new URL(c.req.url).origin; - } - if (c.req.method === "GET" && c.req.path.includes(MIGHTY_DEV_ROOT)) { return runConnectMiddleware(viteMiddleware, c); } + const address = new URL( + MIGHTY_DEV_ROOT, + new URL(c.req.url).origin, + ).toString(); const sharedData: Record = {}; c.setRenderer(async (req) => { - const response = await render({ ...req, context: sharedData }); + const response = await render({ ...req, context: sharedData, address }); return c.html(response.content, response.status as UnofficialStatusCode); }); From c95de655369d721032192b3a6299a2bef089a377 Mon Sep 17 00:00:00 2001 From: Amine Ilidrissi <38422328+aminevg@users.noreply.github.com> Date: Mon, 16 Mar 2026 13:49:38 +0900 Subject: [PATCH 2/2] push --- packages/core/src/dev/setup.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/core/src/dev/setup.ts b/packages/core/src/dev/setup.ts index 897267b..5bb1e05 100644 --- a/packages/core/src/dev/setup.ts +++ b/packages/core/src/dev/setup.ts @@ -169,9 +169,10 @@ export async function setupDev( ]); // Rewrite image URLs to include the dev address - const renderedComponent = rawRenderedComponent - .replace(/(["'(])\/@fs\//g, `$1${MIGHTY_DEV_PLACEHOLDER_ADDRESS}/@fs/`) - .replaceAll(MIGHTY_DEV_PLACEHOLDER_ADDRESS, address); + const renderedComponent = rawRenderedComponent.replace( + /(["'(])\/@fs\//g, + `$1${MIGHTY_DEV_PLACEHOLDER_ADDRESS}/@fs/`, + ); const viteClientScript: Element = { type: "element", @@ -192,7 +193,7 @@ export async function setupDev( ...headInlineScriptTags, ], partial, - ); + ).replaceAll(MIGHTY_DEV_PLACEHOLDER_ADDRESS, address); }; return {