From b6c39a391a285feb475172677387b87dc2971cbd Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Wed, 29 Nov 2023 14:56:53 +0900 Subject: [PATCH 01/41] refactor(remix-dev/vite): use fs watcher to invalidate plugin config and virtual modules --- packages/remix-dev/vite/plugin.ts | 120 +++++++++++++++++++----------- 1 file changed, 77 insertions(+), 43 deletions(-) diff --git a/packages/remix-dev/vite/plugin.ts b/packages/remix-dev/vite/plugin.ts index b8ffd45b909..135f092fadd 100644 --- a/packages/remix-dev/vite/plugin.ts +++ b/packages/remix-dev/vite/plugin.ts @@ -290,7 +290,9 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { | { isSsrBuild: true; getManifest: () => Promise }; let viteChildCompiler: Vite.ViteDevServer | null = null; - let cachedPluginConfig: ResolvedRemixVitePluginConfig | undefined; + + // initialized during `config` hook, so most of the code can assume this is defined without null check + let pluginConfig: ResolvedRemixVitePluginConfig; let resolvePluginConfig = async (): Promise => { @@ -339,7 +341,7 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { }; let getServerEntry = async () => { - let pluginConfig = await resolvePluginConfig(); + // let pluginConfig = await resolvePluginConfig(); return ` import * as entryServer from ${JSON.stringify( @@ -396,7 +398,7 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { }; let createBuildManifest = async (): Promise => { - let pluginConfig = await resolvePluginConfig(); + // let pluginConfig = await resolvePluginConfig(); let viteManifest = await loadViteManifest( pluginConfig.assetsBuildDirectory @@ -461,7 +463,7 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { }; let getDevManifest = async (): Promise => { - let pluginConfig = await resolvePluginConfig(); + // let pluginConfig = await resolvePluginConfig(); let routes: Manifest["routes"] = {}; let routeManifestExports = await getRouteManifestModuleExports( @@ -517,8 +519,8 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { viteUserConfig = _viteUserConfig; viteCommand = viteConfigEnv.command; - let pluginConfig = await resolvePluginConfig(); - cachedPluginConfig = pluginConfig; + pluginConfig = await resolvePluginConfig(); + // cachedPluginConfig = pluginConfig; Object.assign( process.env, @@ -710,10 +712,10 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { // Give the request handler access to the critical CSS in dev to avoid a // flash of unstyled content since Vite injects CSS file contents via JS getCriticalCss: async (build, url) => { - invariant(cachedPluginConfig); + // invariant(pluginConfig); return getStylesForUrl( viteDevServer, - cachedPluginConfig, + pluginConfig, cssModulesManifest, build, url @@ -728,24 +730,27 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { }, }); - // We cache the pluginConfig here to make sure we're only invalidating virtual modules when necessary. - // This requires a separate cache from `cachedPluginConfig`, which is updated by remix-hmr-updates. If - // we shared the cache, it would already be refreshed by remix-hmr-updates at this point, and we'd - // have no way of comparing against the cache to know if the virtual modules need to be invalidated. - let previousPluginConfig: ResolvedRemixVitePluginConfig | undefined; - - return () => { - viteDevServer.middlewares.use(async (_req, _res, next) => { - try { - let pluginConfig = await resolvePluginConfig(); - - if ( - JSON.stringify(pluginConfig) !== - JSON.stringify(previousPluginConfig) - ) { - previousPluginConfig = pluginConfig; - - // Invalidate all virtual modules + // Invalidate plugin config and virtual module via file watcher + invariant(resolvedViteConfig); + let viteConfigFile = resolvedViteConfig.configFile; + let viteRoot = resolvedViteConfig.root; + viteDevServer.watcher.addListener( + "all", + async (event: string, filepath: string) => { + // TODO + // - debounce for bulk file deletion? + // - any race condition? + let filePathAbs = path.resolve(viteRoot, filepath); + if ( + ((event === "add" || event === "unlink") && + filePathAbs.startsWith(pluginConfig.appDirectory)) || + (event === "change" && + viteConfigFile && + filePathAbs === path.resolve(viteRoot, viteConfigFile)) + ) { + let lastPluginConfig = pluginConfig; + pluginConfig = await resolvePluginConfig(); + if (!isEqualJson(lastPluginConfig, pluginConfig)) { vmods.forEach((vmod) => { let mod = viteDevServer.moduleGraph.getModuleById( VirtualModule.resolve(vmod) @@ -756,12 +761,44 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { } }); } - - next(); - } catch (error) { - next(error); } - }); + } + ); + + // // We cache the pluginConfig here to make sure we're only invalidating virtual modules when necessary. + // // This requires a separate cache from `cachedPluginConfig`, which is updated by remix-hmr-updates. If + // // we shared the cache, it would already be refreshed by remix-hmr-updates at this point, and we'd + // // have no way of comparing against the cache to know if the virtual modules need to be invalidated. + // let previousPluginConfig: ResolvedRemixVitePluginConfig | undefined; + + return () => { + // viteDevServer.middlewares.use(async (_req, _res, next) => { + // try { + // let pluginConfig = await resolvePluginConfig(); + + // if ( + // JSON.stringify(pluginConfig) !== + // JSON.stringify(previousPluginConfig) + // ) { + // previousPluginConfig = pluginConfig; + + // // Invalidate all virtual modules + // vmods.forEach((vmod) => { + // let mod = viteDevServer.moduleGraph.getModuleById( + // VirtualModule.resolve(vmod) + // ); + + // if (mod) { + // viteDevServer.moduleGraph.invalidateModule(mod); + // } + // }); + // } + + // next(); + // } catch (error) { + // next(error); + // } + // }); // Let user servers handle SSR requests in middleware mode, // otherwise the Vite plugin will handle the request @@ -792,10 +829,10 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { return; } - invariant( - cachedPluginConfig, - "Expected plugin config to be cached when writeBundle hook is called" - ); + // invariant( + // pluginConfig, + // "Expected plugin config to be cached when writeBundle hook is called" + // ); invariant( resolvedViteConfig, @@ -803,7 +840,7 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { ); let { assetsBuildDirectory, serverBuildPath, rootDirectory } = - cachedPluginConfig; + pluginConfig; let serverBuildDir = path.dirname(serverBuildPath); let ssrViteManifest = await loadViteManifest(serverBuildDir); @@ -938,8 +975,6 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { async transform(code, id, options) { if (options?.ssr) return; - let pluginConfig = cachedPluginConfig || (await resolvePluginConfig()); - let route = getRoute(pluginConfig, id); if (!route) return; @@ -1078,8 +1113,6 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { code = result.code!; let refreshContentRE = /\$Refresh(?:Reg|Sig)\$\(/; if (refreshContentRE.test(code)) { - let pluginConfig = - cachedPluginConfig || (await resolvePluginConfig()); code = addRefreshWrapper(pluginConfig, code, id); } return { code, map: result.map }; @@ -1088,9 +1121,6 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { { name: "remix-hmr-updates", async handleHotUpdate({ server, file, modules }) { - let pluginConfig = await resolvePluginConfig(); - // Update the config cache any time there is a file change - cachedPluginConfig = pluginConfig; let route = getRoute(pluginConfig, file); server.ws.send({ @@ -1109,6 +1139,10 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { ]; }; +function isEqualJson(v1: unknown, v2: unknown) { + return JSON.stringify(v1) === JSON.stringify(v2); +} + function addRefreshWrapper( pluginConfig: ResolvedRemixVitePluginConfig, code: string, From a2f59bc4855d9ef53cb238c85fef8a81e6cde1da Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Wed, 29 Nov 2023 16:04:54 +0900 Subject: [PATCH 02/41] refactor: filepath already absolute --- packages/remix-dev/vite/plugin.ts | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/packages/remix-dev/vite/plugin.ts b/packages/remix-dev/vite/plugin.ts index 135f092fadd..15d327a4e77 100644 --- a/packages/remix-dev/vite/plugin.ts +++ b/packages/remix-dev/vite/plugin.ts @@ -731,22 +731,14 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { }); // Invalidate plugin config and virtual module via file watcher - invariant(resolvedViteConfig); - let viteConfigFile = resolvedViteConfig.configFile; - let viteRoot = resolvedViteConfig.root; viteDevServer.watcher.addListener( "all", async (event: string, filepath: string) => { - // TODO - // - debounce for bulk file deletion? - // - any race condition? - let filePathAbs = path.resolve(viteRoot, filepath); if ( ((event === "add" || event === "unlink") && - filePathAbs.startsWith(pluginConfig.appDirectory)) || + filepath.startsWith(pluginConfig.appDirectory)) || (event === "change" && - viteConfigFile && - filePathAbs === path.resolve(viteRoot, viteConfigFile)) + filepath === resolvedViteConfig?.configFile) ) { let lastPluginConfig = pluginConfig; pluginConfig = await resolvePluginConfig(); From 2dfdc3b679f85403fb953b22c01a8f9a1e7f270d Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Wed, 29 Nov 2023 16:07:36 +0900 Subject: [PATCH 03/41] chore: cleanup --- packages/remix-dev/vite/plugin.ts | 46 ------------------------------- 1 file changed, 46 deletions(-) diff --git a/packages/remix-dev/vite/plugin.ts b/packages/remix-dev/vite/plugin.ts index 15d327a4e77..0ada52f8626 100644 --- a/packages/remix-dev/vite/plugin.ts +++ b/packages/remix-dev/vite/plugin.ts @@ -341,8 +341,6 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { }; let getServerEntry = async () => { - // let pluginConfig = await resolvePluginConfig(); - return ` import * as entryServer from ${JSON.stringify( resolveFileUrl(pluginConfig, pluginConfig.entryServerFilePath) @@ -398,8 +396,6 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { }; let createBuildManifest = async (): Promise => { - // let pluginConfig = await resolvePluginConfig(); - let viteManifest = await loadViteManifest( pluginConfig.assetsBuildDirectory ); @@ -463,7 +459,6 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { }; let getDevManifest = async (): Promise => { - // let pluginConfig = await resolvePluginConfig(); let routes: Manifest["routes"] = {}; let routeManifestExports = await getRouteManifestModuleExports( @@ -520,7 +515,6 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { viteCommand = viteConfigEnv.command; pluginConfig = await resolvePluginConfig(); - // cachedPluginConfig = pluginConfig; Object.assign( process.env, @@ -712,7 +706,6 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { // Give the request handler access to the critical CSS in dev to avoid a // flash of unstyled content since Vite injects CSS file contents via JS getCriticalCss: async (build, url) => { - // invariant(pluginConfig); return getStylesForUrl( viteDevServer, pluginConfig, @@ -757,41 +750,7 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { } ); - // // We cache the pluginConfig here to make sure we're only invalidating virtual modules when necessary. - // // This requires a separate cache from `cachedPluginConfig`, which is updated by remix-hmr-updates. If - // // we shared the cache, it would already be refreshed by remix-hmr-updates at this point, and we'd - // // have no way of comparing against the cache to know if the virtual modules need to be invalidated. - // let previousPluginConfig: ResolvedRemixVitePluginConfig | undefined; - return () => { - // viteDevServer.middlewares.use(async (_req, _res, next) => { - // try { - // let pluginConfig = await resolvePluginConfig(); - - // if ( - // JSON.stringify(pluginConfig) !== - // JSON.stringify(previousPluginConfig) - // ) { - // previousPluginConfig = pluginConfig; - - // // Invalidate all virtual modules - // vmods.forEach((vmod) => { - // let mod = viteDevServer.moduleGraph.getModuleById( - // VirtualModule.resolve(vmod) - // ); - - // if (mod) { - // viteDevServer.moduleGraph.invalidateModule(mod); - // } - // }); - // } - - // next(); - // } catch (error) { - // next(error); - // } - // }); - // Let user servers handle SSR requests in middleware mode, // otherwise the Vite plugin will handle the request if (!viteDevServer.config.server.middlewareMode) { @@ -821,11 +780,6 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { return; } - // invariant( - // pluginConfig, - // "Expected plugin config to be cached when writeBundle hook is called" - // ); - invariant( resolvedViteConfig, "Expected resolvedViteConfig to exist when writeBundle hook is called" From 03d41f71260af59d57f6219be4b6f2b53afe66d8 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Wed, 29 Nov 2023 17:39:47 +0900 Subject: [PATCH 04/41] test: add integration --- .../vite-dev-manifest-invalidation-test.ts | 70 +++++++++++++++++++ packages/remix-dev/vite/plugin.ts | 3 +- 2 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 integration/vite-dev-manifest-invalidation-test.ts diff --git a/integration/vite-dev-manifest-invalidation-test.ts b/integration/vite-dev-manifest-invalidation-test.ts new file mode 100644 index 00000000000..6620a3b6038 --- /dev/null +++ b/integration/vite-dev-manifest-invalidation-test.ts @@ -0,0 +1,70 @@ +import fs from "node:fs/promises"; +import path from "node:path"; +import { test, expect } from "@playwright/test"; +import getPort from "get-port"; + +import { createProject, viteDev, VITE_CONFIG } from "./helpers/vite.js"; + +const files = { + "app/routes/_index.tsx": String.raw` + import { useState, useEffect } from "react"; + import { Link } from "@remix-run/react"; + + export default function IndexRoute() { + const [mounted, setMounted] = useState(false); + useEffect(() => { + setMounted(true); + }, []); + + return ( +
+

Mounted: {mounted ? "yes" : "no"}

+
+ ); + } + `, +}; + +test.describe(async () => { + let port: number; + let cwd: string; + let stop: () => Promise; + + test.beforeAll(async () => { + port = await getPort(); + cwd = await createProject({ + "vite.config.js": await VITE_CONFIG({ port }), + ...files, + }); + stop = await viteDev({ cwd, port }); + }); + test.afterAll(async () => await stop()); + + test("Vite / dev / invalidation", async ({ page }) => { + let pageErrors: Error[] = []; + page.on("pageerror", (error) => pageErrors.push(error)); + + // wait for hydration to make sure initial virtual modules are loaded + await page.goto(`http://localhost:${port}/`); + await page.getByText("Mounted: yes").click(); + + // add new route file + await fs.writeFile( + path.join(cwd, "app/routes/other.tsx"), + String.raw` + export default function Route() { + return ( +
new route
+ ); + } + ` + ); + + // client is not aware of new route addition yet (/~https://github.com/remix-run/remix/issues/7894) + // however server should be able to handle new route (thought it needs a few retries to process invalidation) + expect(async () => { + await page.goto(`http://localhost:${port}/other`); + await page.getByText("new route").click(); + }).toPass(); + }); +}); diff --git a/packages/remix-dev/vite/plugin.ts b/packages/remix-dev/vite/plugin.ts index 0ada52f8626..353425cfc2a 100644 --- a/packages/remix-dev/vite/plugin.ts +++ b/packages/remix-dev/vite/plugin.ts @@ -291,7 +291,8 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { let viteChildCompiler: Vite.ViteDevServer | null = null; - // initialized during `config` hook, so most of the code can assume this is defined without null check + // This is initialized during `config` hook, so most of the code can assume this is defined without null check. + // During dev, this is updated on config file change or route file addition/removal. let pluginConfig: ResolvedRemixVitePluginConfig; let resolvePluginConfig = From 67ce3c9f97ecc7f517881362c85877780b14dc61 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Thu, 30 Nov 2023 10:24:47 +0900 Subject: [PATCH 05/41] test: forgot await --- integration/vite-dev-manifest-invalidation-test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration/vite-dev-manifest-invalidation-test.ts b/integration/vite-dev-manifest-invalidation-test.ts index 6620a3b6038..be406a4bf5e 100644 --- a/integration/vite-dev-manifest-invalidation-test.ts +++ b/integration/vite-dev-manifest-invalidation-test.ts @@ -62,7 +62,7 @@ test.describe(async () => { // client is not aware of new route addition yet (/~https://github.com/remix-run/remix/issues/7894) // however server should be able to handle new route (thought it needs a few retries to process invalidation) - expect(async () => { + await expect(async () => { await page.goto(`http://localhost:${port}/other`); await page.getByText("new route").click(); }).toPass(); From 1a655728b40b33d12909f14e33bc5777b48ac87b Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Thu, 30 Nov 2023 11:16:29 +0900 Subject: [PATCH 06/41] fix: struggle with path manipulation --- packages/remix-dev/vite/plugin.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/remix-dev/vite/plugin.ts b/packages/remix-dev/vite/plugin.ts index 7d2a032c4e3..ef363279b02 100644 --- a/packages/remix-dev/vite/plugin.ts +++ b/packages/remix-dev/vite/plugin.ts @@ -726,14 +726,20 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { }); // Invalidate plugin config and virtual module via file watcher + invariant(resolvedViteConfig); + let viteRoot = resolvedViteConfig.root; + let viteConfigFile = resolvedViteConfig.configFile; + let viteConfigFileAbs = + viteConfigFile && path.resolve(viteRoot, viteConfigFile); + viteDevServer.watcher.addListener( "all", async (event: string, filepath: string) => { + let filepathAbs = path.resolve(viteRoot, filepath); if ( ((event === "add" || event === "unlink") && - filepath.startsWith(pluginConfig.appDirectory)) || - (event === "change" && - filepath === resolvedViteConfig?.configFile) + filepathAbs.startsWith(pluginConfig.appDirectory)) || + (event === "change" && filepathAbs === viteConfigFileAbs) ) { let lastPluginConfig = pluginConfig; pluginConfig = await resolvePluginConfig(); From 4ddf0ccbaec8cfe8cd39150ddab1c143899c2994 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Thu, 30 Nov 2023 11:38:23 +0900 Subject: [PATCH 07/41] fix: struggle 2 --- packages/remix-dev/vite/plugin.ts | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/packages/remix-dev/vite/plugin.ts b/packages/remix-dev/vite/plugin.ts index ef363279b02..74b66322b79 100644 --- a/packages/remix-dev/vite/plugin.ts +++ b/packages/remix-dev/vite/plugin.ts @@ -726,20 +726,17 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { }); // Invalidate plugin config and virtual module via file watcher - invariant(resolvedViteConfig); - let viteRoot = resolvedViteConfig.root; - let viteConfigFile = resolvedViteConfig.configFile; - let viteConfigFileAbs = - viteConfigFile && path.resolve(viteRoot, viteConfigFile); - + let vite = importViteEsmSync(); viteDevServer.watcher.addListener( "all", async (event: string, filepath: string) => { - let filepathAbs = path.resolve(viteRoot, filepath); if ( ((event === "add" || event === "unlink") && - filepathAbs.startsWith(pluginConfig.appDirectory)) || - (event === "change" && filepathAbs === viteConfigFileAbs) + filepath.startsWith( + vite.normalizePath(pluginConfig.appDirectory) + )) || + (event === "change" && + filepath === resolvedViteConfig?.configFile) ) { let lastPluginConfig = pluginConfig; pluginConfig = await resolvePluginConfig(); From 3c9c98c70af56d44ff067a2d4dfc990db965ce17 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Thu, 30 Nov 2023 15:51:30 +0900 Subject: [PATCH 08/41] chore: minor --- integration/vite-dev-manifest-invalidation-test.ts | 3 ++- packages/remix-dev/vite/plugin.ts | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/integration/vite-dev-manifest-invalidation-test.ts b/integration/vite-dev-manifest-invalidation-test.ts index be406a4bf5e..00082ca515b 100644 --- a/integration/vite-dev-manifest-invalidation-test.ts +++ b/integration/vite-dev-manifest-invalidation-test.ts @@ -57,7 +57,8 @@ test.describe(async () => {
new route
); } - ` + `, + "utf-8" ); // client is not aware of new route addition yet (/~https://github.com/remix-run/remix/issues/7894) diff --git a/packages/remix-dev/vite/plugin.ts b/packages/remix-dev/vite/plugin.ts index 74b66322b79..55a4c853b18 100644 --- a/packages/remix-dev/vite/plugin.ts +++ b/packages/remix-dev/vite/plugin.ts @@ -727,7 +727,7 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { // Invalidate plugin config and virtual module via file watcher let vite = importViteEsmSync(); - viteDevServer.watcher.addListener( + viteDevServer.watcher.on( "all", async (event: string, filepath: string) => { if ( From 85c4d3bf342516fdc5d6b06d064d7e9254ce14f4 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Thu, 30 Nov 2023 15:54:46 +0900 Subject: [PATCH 09/41] chore: debug log --- integration/helpers/vite.ts | 11 ++++++++--- integration/vite-dev-manifest-invalidation-test.ts | 2 +- packages/remix-dev/vite/plugin.ts | 1 + 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/integration/helpers/vite.ts b/integration/helpers/vite.ts index 8dced0b42b4..cb11cc78fae 100644 --- a/integration/helpers/vite.ts +++ b/integration/helpers/vite.ts @@ -109,12 +109,13 @@ export async function createProject(files: Record = {}) { type ServerArgs = { cwd: string; port: number; + debug?: boolean; }; const createDev = (nodeArgs: string[]) => - async ({ cwd, port }: ServerArgs): Promise<() => Promise> => { - let proc = node(nodeArgs, { cwd }); + async ({ cwd, port, debug }: ServerArgs): Promise<() => Promise> => { + let proc = node(nodeArgs, { cwd, debug }); await waitForServer(proc, { port: port }); return async () => await kill(proc.pid!); }; @@ -140,7 +141,7 @@ export const viteBuild = (args: { cwd: string }) => { export const viteDev = createDev([resolveBin.sync("vite"), "dev"]); export const customDev = createDev(["./server.mjs"]); -function node(args: string[], options: { cwd: string }) { +function node(args: string[], options: { cwd: string, debug?: boolean }) { let nodeBin = process.argv[0]; let proc = spawn(nodeBin, args, { @@ -148,6 +149,10 @@ function node(args: string[], options: { cwd: string }) { env: process.env, stdio: "pipe", }); + if (options.debug) { + proc.stderr.on("data", (data) => console.log(data.toString())); + proc.stdout.on("data", (data) => console.log(data.toString())); + } return proc; } diff --git a/integration/vite-dev-manifest-invalidation-test.ts b/integration/vite-dev-manifest-invalidation-test.ts index 00082ca515b..dbdee6391b0 100644 --- a/integration/vite-dev-manifest-invalidation-test.ts +++ b/integration/vite-dev-manifest-invalidation-test.ts @@ -36,7 +36,7 @@ test.describe(async () => { "vite.config.js": await VITE_CONFIG({ port }), ...files, }); - stop = await viteDev({ cwd, port }); + stop = await viteDev({ cwd, port, debug: true }); }); test.afterAll(async () => await stop()); diff --git a/packages/remix-dev/vite/plugin.ts b/packages/remix-dev/vite/plugin.ts index 55a4c853b18..42c2be63315 100644 --- a/packages/remix-dev/vite/plugin.ts +++ b/packages/remix-dev/vite/plugin.ts @@ -730,6 +730,7 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { viteDevServer.watcher.on( "all", async (event: string, filepath: string) => { + console.log("@@@@@@ watcher @@@@@@", { event, filepath }); if ( ((event === "add" || event === "unlink") && filepath.startsWith( From 58bf671caa29b7f4a8316a3a73847f079299f464 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Thu, 30 Nov 2023 16:12:59 +0900 Subject: [PATCH 10/41] chore: debug 2 --- integration/helpers/vite.ts | 2 +- packages/remix-dev/vite/plugin.ts | 13 +++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/integration/helpers/vite.ts b/integration/helpers/vite.ts index cb11cc78fae..5128adbeb89 100644 --- a/integration/helpers/vite.ts +++ b/integration/helpers/vite.ts @@ -141,7 +141,7 @@ export const viteBuild = (args: { cwd: string }) => { export const viteDev = createDev([resolveBin.sync("vite"), "dev"]); export const customDev = createDev(["./server.mjs"]); -function node(args: string[], options: { cwd: string, debug?: boolean }) { +function node(args: string[], options: { cwd: string; debug?: boolean }) { let nodeBin = process.argv[0]; let proc = spawn(nodeBin, args, { diff --git a/packages/remix-dev/vite/plugin.ts b/packages/remix-dev/vite/plugin.ts index 42c2be63315..1aefc5748e4 100644 --- a/packages/remix-dev/vite/plugin.ts +++ b/packages/remix-dev/vite/plugin.ts @@ -730,12 +730,17 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { viteDevServer.watcher.on( "all", async (event: string, filepath: string) => { - console.log("@@@@@@ watcher @@@@@@", { event, filepath }); + console.log("@@@@@@ watcher @@@@@@", { + event, + filepath, + appDirectory: pluginConfig.appDirectory, + configFile: resolvedViteConfig?.configFile, + }); if ( ((event === "add" || event === "unlink") && - filepath.startsWith( - vite.normalizePath(pluginConfig.appDirectory) - )) || + vite + .normalizePath(filepath) + .startsWith(vite.normalizePath(pluginConfig.appDirectory))) || (event === "change" && filepath === resolvedViteConfig?.configFile) ) { From 149896478787b369eff4e23a7c8065b4dea229c6 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Thu, 30 Nov 2023 16:34:21 +0900 Subject: [PATCH 11/41] chore: debug 3 --- packages/remix-dev/vite/plugin.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/remix-dev/vite/plugin.ts b/packages/remix-dev/vite/plugin.ts index 1aefc5748e4..1b19cc2819b 100644 --- a/packages/remix-dev/vite/plugin.ts +++ b/packages/remix-dev/vite/plugin.ts @@ -744,6 +744,7 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { (event === "change" && filepath === resolvedViteConfig?.configFile) ) { + console.log("@@@@@@ resolvePluginConfig @@@@@@"); let lastPluginConfig = pluginConfig; pluginConfig = await resolvePluginConfig(); if (!isEqualJson(lastPluginConfig, pluginConfig)) { @@ -751,8 +752,10 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { let mod = viteDevServer.moduleGraph.getModuleById( VirtualModule.resolve(vmod) ); + console.log("@@@@@@ getModuleById @@@@@@", mod?.file); if (mod) { + console.log("@@@@@@ invalidateModule @@@@@@", mod.file); viteDevServer.moduleGraph.invalidateModule(mod); } }); From 06f6c6523cae839532b2165c28c44546e9a44e5b Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Thu, 30 Nov 2023 16:45:57 +0900 Subject: [PATCH 12/41] chore: debug ci --- .github/workflows/shared-test-integration.yml | 2 +- integration/vite-dev-manifest-invalidation-test.ts | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/shared-test-integration.yml b/.github/workflows/shared-test-integration.yml index 97ec135aee9..705bf540255 100644 --- a/.github/workflows/shared-test-integration.yml +++ b/.github/workflows/shared-test-integration.yml @@ -56,4 +56,4 @@ jobs: run: npx playwright install --with-deps ${{ matrix.browser }} - name: 👀 Run Integration Tests ${{ matrix.browser }} - run: "yarn test:integration --project=${{ matrix.browser }}" + run: "yarn test:integration --project=${{ matrix.browser }} integration/vite-dev-manifest-invalidation-test.ts" diff --git a/integration/vite-dev-manifest-invalidation-test.ts b/integration/vite-dev-manifest-invalidation-test.ts index dbdee6391b0..2cd75b19efa 100644 --- a/integration/vite-dev-manifest-invalidation-test.ts +++ b/integration/vite-dev-manifest-invalidation-test.ts @@ -63,7 +63,9 @@ test.describe(async () => { // client is not aware of new route addition yet (/~https://github.com/remix-run/remix/issues/7894) // however server should be able to handle new route (thought it needs a few retries to process invalidation) + let i = 0; await expect(async () => { + console.log(":::::::: TRIAL", i++); await page.goto(`http://localhost:${port}/other`); await page.getByText("new route").click(); }).toPass(); From dfea0f0644d46a5b4f1addc580239c3355a9a2db Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Thu, 30 Nov 2023 17:11:03 +0900 Subject: [PATCH 13/41] ci: force retry when stuck? --- integration/vite-dev-manifest-invalidation-test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration/vite-dev-manifest-invalidation-test.ts b/integration/vite-dev-manifest-invalidation-test.ts index 2cd75b19efa..a37cb7b37c5 100644 --- a/integration/vite-dev-manifest-invalidation-test.ts +++ b/integration/vite-dev-manifest-invalidation-test.ts @@ -66,7 +66,7 @@ test.describe(async () => { let i = 0; await expect(async () => { console.log(":::::::: TRIAL", i++); - await page.goto(`http://localhost:${port}/other`); + await page.goto(`http://localhost:${port}/other`, { timeout: 1000 }); await page.getByText("new route").click(); }).toPass(); }); From 081fcea117abed57003a80f1e0c4194e4d7fd862 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Thu, 30 Nov 2023 17:18:14 +0900 Subject: [PATCH 14/41] test: use "expect.poll" --- integration/vite-dev-manifest-invalidation-test.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/integration/vite-dev-manifest-invalidation-test.ts b/integration/vite-dev-manifest-invalidation-test.ts index a37cb7b37c5..d5c8265f827 100644 --- a/integration/vite-dev-manifest-invalidation-test.ts +++ b/integration/vite-dev-manifest-invalidation-test.ts @@ -64,10 +64,12 @@ test.describe(async () => { // client is not aware of new route addition yet (/~https://github.com/remix-run/remix/issues/7894) // however server should be able to handle new route (thought it needs a few retries to process invalidation) let i = 0; - await expect(async () => { - console.log(":::::::: TRIAL", i++); - await page.goto(`http://localhost:${port}/other`, { timeout: 1000 }); - await page.getByText("new route").click(); - }).toPass(); + await expect + .poll(async () => { + console.log(":::::::: TRIAL", i++); + await page.goto(`http://localhost:${port}/other`); + return page.getByText("new route").isVisible(); + }) + .toBe(true); }); }); From 2d40d674ac19ccb29768194300aca8e33250f5bf Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Thu, 30 Nov 2023 17:29:40 +0900 Subject: [PATCH 15/41] chore: comment --- integration/vite-dev-manifest-invalidation-test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/integration/vite-dev-manifest-invalidation-test.ts b/integration/vite-dev-manifest-invalidation-test.ts index d5c8265f827..c7730c5553a 100644 --- a/integration/vite-dev-manifest-invalidation-test.ts +++ b/integration/vite-dev-manifest-invalidation-test.ts @@ -62,7 +62,8 @@ test.describe(async () => { ); // client is not aware of new route addition yet (/~https://github.com/remix-run/remix/issues/7894) - // however server should be able to handle new route (thought it needs a few retries to process invalidation) + // however server can handle new route + // though it needs a few retries to process invalidation, thus reliance on expect.poll let i = 0; await expect .poll(async () => { From 2b9bb3af24142353355214218717b6706d8fa02e Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Thu, 30 Nov 2023 17:29:57 +0900 Subject: [PATCH 16/41] chore: revert ci --- .github/workflows/shared-test-integration.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/shared-test-integration.yml b/.github/workflows/shared-test-integration.yml index 705bf540255..97ec135aee9 100644 --- a/.github/workflows/shared-test-integration.yml +++ b/.github/workflows/shared-test-integration.yml @@ -56,4 +56,4 @@ jobs: run: npx playwright install --with-deps ${{ matrix.browser }} - name: 👀 Run Integration Tests ${{ matrix.browser }} - run: "yarn test:integration --project=${{ matrix.browser }} integration/vite-dev-manifest-invalidation-test.ts" + run: "yarn test:integration --project=${{ matrix.browser }}" From 714440b7e75b753f294f3ba9d7ad89babfddf4b7 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Thu, 30 Nov 2023 17:33:32 +0900 Subject: [PATCH 17/41] chore: revert debug --- .../vite-dev-manifest-invalidation-test.ts | 3 +-- packages/remix-dev/vite/plugin.ts | 21 +++++++------------ 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/integration/vite-dev-manifest-invalidation-test.ts b/integration/vite-dev-manifest-invalidation-test.ts index c7730c5553a..5fe73b527fa 100644 --- a/integration/vite-dev-manifest-invalidation-test.ts +++ b/integration/vite-dev-manifest-invalidation-test.ts @@ -61,9 +61,8 @@ test.describe(async () => { "utf-8" ); - // client is not aware of new route addition yet (/~https://github.com/remix-run/remix/issues/7894) + // client is not notified of new route addition (/~https://github.com/remix-run/remix/issues/7894) // however server can handle new route - // though it needs a few retries to process invalidation, thus reliance on expect.poll let i = 0; await expect .poll(async () => { diff --git a/packages/remix-dev/vite/plugin.ts b/packages/remix-dev/vite/plugin.ts index 1b19cc2819b..4f1141da985 100644 --- a/packages/remix-dev/vite/plugin.ts +++ b/packages/remix-dev/vite/plugin.ts @@ -726,25 +726,20 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { }); // Invalidate plugin config and virtual module via file watcher - let vite = importViteEsmSync(); + let { normalizePath } = importViteEsmSync(); viteDevServer.watcher.on( "all", async (event: string, filepath: string) => { - console.log("@@@@@@ watcher @@@@@@", { - event, - filepath, - appDirectory: pluginConfig.appDirectory, - configFile: resolvedViteConfig?.configFile, - }); if ( ((event === "add" || event === "unlink") && - vite - .normalizePath(filepath) - .startsWith(vite.normalizePath(pluginConfig.appDirectory))) || + normalizePath(filepath).startsWith( + normalizePath(pluginConfig.appDirectory) + )) || (event === "change" && - filepath === resolvedViteConfig?.configFile) + resolvedViteConfig?.configFile && + normalizePath(filepath) === + normalizePath(resolvedViteConfig.configFile)) ) { - console.log("@@@@@@ resolvePluginConfig @@@@@@"); let lastPluginConfig = pluginConfig; pluginConfig = await resolvePluginConfig(); if (!isEqualJson(lastPluginConfig, pluginConfig)) { @@ -752,10 +747,8 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { let mod = viteDevServer.moduleGraph.getModuleById( VirtualModule.resolve(vmod) ); - console.log("@@@@@@ getModuleById @@@@@@", mod?.file); if (mod) { - console.log("@@@@@@ invalidateModule @@@@@@", mod.file); viteDevServer.moduleGraph.invalidateModule(mod); } }); From 4e8a5ca2e8afa61a507d6252fe086fe200b541bc Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Thu, 30 Nov 2023 17:36:21 +0900 Subject: [PATCH 18/41] chore: revert one more debug --- integration/helpers/vite.ts | 11 +++-------- integration/vite-dev-manifest-invalidation-test.ts | 4 +--- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/integration/helpers/vite.ts b/integration/helpers/vite.ts index 5128adbeb89..8dced0b42b4 100644 --- a/integration/helpers/vite.ts +++ b/integration/helpers/vite.ts @@ -109,13 +109,12 @@ export async function createProject(files: Record = {}) { type ServerArgs = { cwd: string; port: number; - debug?: boolean; }; const createDev = (nodeArgs: string[]) => - async ({ cwd, port, debug }: ServerArgs): Promise<() => Promise> => { - let proc = node(nodeArgs, { cwd, debug }); + async ({ cwd, port }: ServerArgs): Promise<() => Promise> => { + let proc = node(nodeArgs, { cwd }); await waitForServer(proc, { port: port }); return async () => await kill(proc.pid!); }; @@ -141,7 +140,7 @@ export const viteBuild = (args: { cwd: string }) => { export const viteDev = createDev([resolveBin.sync("vite"), "dev"]); export const customDev = createDev(["./server.mjs"]); -function node(args: string[], options: { cwd: string; debug?: boolean }) { +function node(args: string[], options: { cwd: string }) { let nodeBin = process.argv[0]; let proc = spawn(nodeBin, args, { @@ -149,10 +148,6 @@ function node(args: string[], options: { cwd: string; debug?: boolean }) { env: process.env, stdio: "pipe", }); - if (options.debug) { - proc.stderr.on("data", (data) => console.log(data.toString())); - proc.stdout.on("data", (data) => console.log(data.toString())); - } return proc; } diff --git a/integration/vite-dev-manifest-invalidation-test.ts b/integration/vite-dev-manifest-invalidation-test.ts index 5fe73b527fa..85187e0c2e1 100644 --- a/integration/vite-dev-manifest-invalidation-test.ts +++ b/integration/vite-dev-manifest-invalidation-test.ts @@ -36,7 +36,7 @@ test.describe(async () => { "vite.config.js": await VITE_CONFIG({ port }), ...files, }); - stop = await viteDev({ cwd, port, debug: true }); + stop = await viteDev({ cwd, port }); }); test.afterAll(async () => await stop()); @@ -63,10 +63,8 @@ test.describe(async () => { // client is not notified of new route addition (/~https://github.com/remix-run/remix/issues/7894) // however server can handle new route - let i = 0; await expect .poll(async () => { - console.log(":::::::: TRIAL", i++); await page.goto(`http://localhost:${port}/other`); return page.getByText("new route").isVisible(); }) From 3d8f7e295f324ac66b6a6290b1bf47fcbee396e2 Mon Sep 17 00:00:00 2001 From: Mark Dalgleish Date: Fri, 5 Jan 2024 15:18:59 +1100 Subject: [PATCH 19/41] refactor --- packages/remix-dev/vite/plugin.ts | 43 ++++++++++++++++--------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/packages/remix-dev/vite/plugin.ts b/packages/remix-dev/vite/plugin.ts index a4fa880739d..5e29c711ffa 100644 --- a/packages/remix-dev/vite/plugin.ts +++ b/packages/remix-dev/vite/plugin.ts @@ -834,29 +834,30 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { }, }); - // Invalidate plugin config and virtual module via file watcher - let { normalizePath } = importViteEsmSync(); - viteDevServer.watcher.on( - "all", - async (event: string, filepath: string) => { - if ( - ((event === "add" || event === "unlink") && - normalizePath(filepath).startsWith( - normalizePath(pluginConfig.appDirectory) - )) || - (event === "change" && - viteConfig?.configFile && - normalizePath(filepath) === - normalizePath(viteConfig.configFile)) - ) { - let lastPluginConfig = pluginConfig; - pluginConfig = await resolvePluginConfig(); - if (!isEqualJson(lastPluginConfig, pluginConfig)) { - invalidateVirtualModules(viteDevServer); - } + // Invalidate virtual modules and update cached plugin config via file watcher + viteDevServer.watcher.on("all", async (eventName, filepath) => { + let { normalizePath } = importViteEsmSync(); + + let appFileAddedOrRemoved = + (eventName === "add" || eventName === "unlink") && + normalizePath(filepath).startsWith( + normalizePath(pluginConfig.appDirectory) + ); + + invariant(viteConfig?.configFile); + let viteConfigChanged = + eventName === "change" && + normalizePath(filepath) === normalizePath(viteConfig.configFile); + + if (appFileAddedOrRemoved || viteConfigChanged) { + let lastPluginConfig = pluginConfig; + pluginConfig = await resolvePluginConfig(); + + if (!isEqualJson(lastPluginConfig, pluginConfig)) { + invalidateVirtualModules(viteDevServer); } } - ); + }); return () => { // Let user servers handle SSR requests in middleware mode, From da651a8c2b376a1a1592506e2cc0d1301a1ae1ca Mon Sep 17 00:00:00 2001 From: Mark Dalgleish Date: Fri, 5 Jan 2024 15:34:32 +1100 Subject: [PATCH 20/41] refactor and rename tests --- ...lidation-test.ts => vite-route-added-test.ts} | 16 +++++++--------- ...ite-route-exports-modified-offscreen-test.ts} | 2 +- 2 files changed, 8 insertions(+), 10 deletions(-) rename integration/{vite-dev-manifest-invalidation-test.ts => vite-route-added-test.ts} (78%) rename integration/{vite-manifest-invalidation-test.ts => vite-route-exports-modified-offscreen-test.ts} (97%) diff --git a/integration/vite-dev-manifest-invalidation-test.ts b/integration/vite-route-added-test.ts similarity index 78% rename from integration/vite-dev-manifest-invalidation-test.ts rename to integration/vite-route-added-test.ts index 85187e0c2e1..42cdcfedc53 100644 --- a/integration/vite-dev-manifest-invalidation-test.ts +++ b/integration/vite-route-added-test.ts @@ -17,9 +17,7 @@ const files = { }, []); return ( -
-

Mounted: {mounted ? "yes" : "no"}

-
+

Mounted: {mounted ? "yes" : "no"}

); } `, @@ -40,21 +38,21 @@ test.describe(async () => { }); test.afterAll(async () => await stop()); - test("Vite / dev / invalidation", async ({ page }) => { + test("Vite / dev / route added", async ({ page }) => { let pageErrors: Error[] = []; page.on("pageerror", (error) => pageErrors.push(error)); // wait for hydration to make sure initial virtual modules are loaded - await page.goto(`http://localhost:${port}/`); - await page.getByText("Mounted: yes").click(); + await page.goto(`http://localhost:${port}/`, { waitUntil: "networkidle" }); + await expect(page.locator("[data-mounted]")).toHaveText("Mounted: yes"); // add new route file await fs.writeFile( - path.join(cwd, "app/routes/other.tsx"), + path.join(cwd, "app/routes/new.tsx"), String.raw` export default function Route() { return ( -
new route
+
new route
); } `, @@ -65,7 +63,7 @@ test.describe(async () => { // however server can handle new route await expect .poll(async () => { - await page.goto(`http://localhost:${port}/other`); + await page.goto(`http://localhost:${port}/new`); return page.getByText("new route").isVisible(); }) .toBe(true); diff --git a/integration/vite-manifest-invalidation-test.ts b/integration/vite-route-exports-modified-offscreen-test.ts similarity index 97% rename from integration/vite-manifest-invalidation-test.ts rename to integration/vite-route-exports-modified-offscreen-test.ts index 3b5e8c3c39e..851e34a8286 100644 --- a/integration/vite-manifest-invalidation-test.ts +++ b/integration/vite-route-exports-modified-offscreen-test.ts @@ -56,7 +56,7 @@ test.describe(async () => { }); test.afterAll(async () => await stop()); - test("Vite / dev / invalidate manifest on route exports change", async ({ + test("Vite / dev / route exports modified offscreen", async ({ page, context, browserName, From 0a03e9d11aac16682830545536329f809055e531 Mon Sep 17 00:00:00 2001 From: Mark Dalgleish Date: Mon, 8 Jan 2024 07:57:23 +1100 Subject: [PATCH 21/41] add changeset --- .changeset/wet-sheep-call.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/wet-sheep-call.md diff --git a/.changeset/wet-sheep-call.md b/.changeset/wet-sheep-call.md new file mode 100644 index 00000000000..01bcf969909 --- /dev/null +++ b/.changeset/wet-sheep-call.md @@ -0,0 +1,5 @@ +--- +"@remix-run/dev": patch +--- + +Vite: Improve performance of dev server requests by invalidating virtual modules on relevant file changes rather than on every request From c4f9e3eca9b08e159f58c5f77c96c1f9b4fec418 Mon Sep 17 00:00:00 2001 From: Mark Dalgleish Date: Mon, 8 Jan 2024 08:11:42 +1100 Subject: [PATCH 22/41] update changeset --- .changeset/wet-sheep-call.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/wet-sheep-call.md b/.changeset/wet-sheep-call.md index 01bcf969909..48105ec44b6 100644 --- a/.changeset/wet-sheep-call.md +++ b/.changeset/wet-sheep-call.md @@ -2,4 +2,4 @@ "@remix-run/dev": patch --- -Vite: Improve performance of dev server requests by invalidating virtual modules on relevant file changes rather than on every request +Vite: Improve performance of dev server requests by invalidating Remix's virtual modules on relevant file changes rather than on every request From 18022a713b6f843e020f3f177d13be520cc0b4df Mon Sep 17 00:00:00 2001 From: Mark Dalgleish Date: Tue, 9 Jan 2024 11:29:29 +1100 Subject: [PATCH 23/41] fix old cached plugin config usage --- packages/remix-dev/vite/plugin.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/remix-dev/vite/plugin.ts b/packages/remix-dev/vite/plugin.ts index 9d2ff567976..46259a528cb 100644 --- a/packages/remix-dev/vite/plugin.ts +++ b/packages/remix-dev/vite/plugin.ts @@ -986,7 +986,7 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { ); } - if (cachedPluginConfig.isSpaMode) { + if (pluginConfig.isSpaMode) { await handleSpaMode( path.join(rootDirectory, serverBuildDirectory), serverBuildFile, From 4b76e898c78e0e5f8565a7f7bf65909a938de843 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Wed, 10 Jan 2024 17:41:03 +0900 Subject: [PATCH 24/41] (debug) --- .github/workflows/shared-test-integration.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/shared-test-integration.yml b/.github/workflows/shared-test-integration.yml index 97ec135aee9..7bb8f9caaae 100644 --- a/.github/workflows/shared-test-integration.yml +++ b/.github/workflows/shared-test-integration.yml @@ -56,4 +56,7 @@ jobs: run: npx playwright install --with-deps ${{ matrix.browser }} - name: 👀 Run Integration Tests ${{ matrix.browser }} - run: "yarn test:integration --project=${{ matrix.browser }}" + run: | + for ((i=0; i<10; i++)); do + yarn test:integration --project=${{ matrix.browser }} integration/vite-hmr-hdr-test.ts + done From 7b45eb9b66b06b34a6eb60b85f3459f4d879a9a3 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Wed, 10 Jan 2024 17:47:57 +0900 Subject: [PATCH 25/41] (debug) repeatEach --- .github/workflows/shared-test-integration.yml | 7 +++---- integration/playwright.config.ts | 1 + integration/vite-hmr-hdr-test.ts | 2 ++ 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/shared-test-integration.yml b/.github/workflows/shared-test-integration.yml index 7bb8f9caaae..2296e701710 100644 --- a/.github/workflows/shared-test-integration.yml +++ b/.github/workflows/shared-test-integration.yml @@ -56,7 +56,6 @@ jobs: run: npx playwright install --with-deps ${{ matrix.browser }} - name: 👀 Run Integration Tests ${{ matrix.browser }} - run: | - for ((i=0; i<10; i++)); do - yarn test:integration --project=${{ matrix.browser }} integration/vite-hmr-hdr-test.ts - done + run: yarn test:integration --project=${{ matrix.browser }} integration/vite-hmr-hdr-test.ts + env: + REPEAT_EACH: 10 diff --git a/integration/playwright.config.ts b/integration/playwright.config.ts index 62c3e39cfd3..2dc6d037797 100644 --- a/integration/playwright.config.ts +++ b/integration/playwright.config.ts @@ -13,6 +13,7 @@ const config: PlaywrightTestConfig = { }, forbidOnly: !!process.env.CI, retries: process.env.CI ? 3 : 0, + repeatEach: process.env.REPEAT_EACH ? Number(process.env.REPEAT_EACH) : undefined, reporter: process.env.CI ? "dot" : [["html", { open: "never" }]], use: { actionTimeout: 0 }, diff --git a/integration/vite-hmr-hdr-test.ts b/integration/vite-hmr-hdr-test.ts index 1608da450d5..5d3f21f689a 100644 --- a/integration/vite-hmr-hdr-test.ts +++ b/integration/vite-hmr-hdr-test.ts @@ -49,6 +49,7 @@ test.describe(async () => { test.beforeAll(async () => { port = await getPort(); + console.log("@vite", { port }); cwd = await createProject({ "vite.config.js": await VITE_CONFIG({ port }), ...files, @@ -69,6 +70,7 @@ test.describe(async () => { test.beforeAll(async () => { port = await getPort(); + console.log("@express", { port }); cwd = await createProject({ "vite.config.js": await VITE_CONFIG({ port }), "server.mjs": EXPRESS_SERVER({ port }), From 1044dd36f84c00866874af8ac3b0d2bc776f94bf Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Wed, 10 Jan 2024 17:59:11 +0900 Subject: [PATCH 26/41] (debug) just one test --- integration/vite-hmr-hdr-test.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/integration/vite-hmr-hdr-test.ts b/integration/vite-hmr-hdr-test.ts index 5d3f21f689a..d9d9ac47677 100644 --- a/integration/vite-hmr-hdr-test.ts +++ b/integration/vite-hmr-hdr-test.ts @@ -49,7 +49,6 @@ test.describe(async () => { test.beforeAll(async () => { port = await getPort(); - console.log("@vite", { port }); cwd = await createProject({ "vite.config.js": await VITE_CONFIG({ port }), ...files, @@ -63,14 +62,13 @@ test.describe(async () => { }); }); -test.describe(async () => { +test.describe.skip(async () => { let port: number; let cwd: string; let stop: () => Promise; test.beforeAll(async () => { port = await getPort(); - console.log("@express", { port }); cwd = await createProject({ "vite.config.js": await VITE_CONFIG({ port }), "server.mjs": EXPRESS_SERVER({ port }), From 0634762489f138221519d2f2d874807fbe8c673b Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Wed, 10 Jan 2024 18:37:57 +0900 Subject: [PATCH 27/41] (debug) serial test + log invalidateVirtualModules --- integration/helpers/vite.ts | 2 ++ integration/playwright.config.ts | 3 ++- packages/remix-dev/vite/plugin.ts | 2 ++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/integration/helpers/vite.ts b/integration/helpers/vite.ts index 0a6978d88df..2f4d656fd26 100644 --- a/integration/helpers/vite.ts +++ b/integration/helpers/vite.ts @@ -175,6 +175,8 @@ function node(args: string[], options: { cwd: string }) { env: process.env, stdio: "pipe", }); + proc.stdout?.on("data", data => console.log(String(data))) + proc.stderr?.on("data", data => console.log(String(data))) return proc; } diff --git a/integration/playwright.config.ts b/integration/playwright.config.ts index 2dc6d037797..e3a4a2e61e4 100644 --- a/integration/playwright.config.ts +++ b/integration/playwright.config.ts @@ -6,7 +6,8 @@ const config: PlaywrightTestConfig = { testMatch: ["**/*-test.ts"], /* Maximum time one test can run for. */ timeout: process.platform === "win32" ? 60_000 : 30_000, - fullyParallel: true, + // fullyParallel: true, + workers: 1, expect: { /* Maximum time expect() should wait for the condition to be met. */ timeout: 5_000, diff --git a/packages/remix-dev/vite/plugin.ts b/packages/remix-dev/vite/plugin.ts index 0d5d7715c4c..3dfccd9cb27 100644 --- a/packages/remix-dev/vite/plugin.ts +++ b/packages/remix-dev/vite/plugin.ts @@ -868,6 +868,7 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { pluginConfig = await resolvePluginConfig(); if (!isEqualJson(lastPluginConfig, pluginConfig)) { + console.log("[watcher]", { filepath }); invalidateVirtualModules(viteDevServer); } } @@ -1334,6 +1335,7 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { ] as const ).some((key) => oldRouteMetadata[key] !== newRouteMetadata[key]) ) { + console.log("[handleHotUpdate]", { file }); invalidateVirtualModules(server); } } From 79fea979f1abcb5322e59dbdc0490e301cf6a10c Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Wed, 10 Jan 2024 18:41:22 +0900 Subject: [PATCH 28/41] (debug) tweak log --- .github/workflows/shared-test-integration.yml | 2 +- integration/helpers/vite.ts | 4 ++-- integration/playwright.config.ts | 3 +-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/shared-test-integration.yml b/.github/workflows/shared-test-integration.yml index 2296e701710..6e5b749d500 100644 --- a/.github/workflows/shared-test-integration.yml +++ b/.github/workflows/shared-test-integration.yml @@ -56,6 +56,6 @@ jobs: run: npx playwright install --with-deps ${{ matrix.browser }} - name: 👀 Run Integration Tests ${{ matrix.browser }} - run: yarn test:integration --project=${{ matrix.browser }} integration/vite-hmr-hdr-test.ts + run: yarn test:integration --project=${{ matrix.browser }} --workers=1 integration/vite-hmr-hdr-test.ts env: REPEAT_EACH: 10 diff --git a/integration/helpers/vite.ts b/integration/helpers/vite.ts index 2f4d656fd26..c4d3d845bfe 100644 --- a/integration/helpers/vite.ts +++ b/integration/helpers/vite.ts @@ -175,8 +175,8 @@ function node(args: string[], options: { cwd: string }) { env: process.env, stdio: "pipe", }); - proc.stdout?.on("data", data => console.log(String(data))) - proc.stderr?.on("data", data => console.log(String(data))) + proc.stdout?.on("data", data => process.stdout.write(data)) + proc.stderr?.on("data", data => process.stderr.write(data)) return proc; } diff --git a/integration/playwright.config.ts b/integration/playwright.config.ts index e3a4a2e61e4..2dc6d037797 100644 --- a/integration/playwright.config.ts +++ b/integration/playwright.config.ts @@ -6,8 +6,7 @@ const config: PlaywrightTestConfig = { testMatch: ["**/*-test.ts"], /* Maximum time one test can run for. */ timeout: process.platform === "win32" ? 60_000 : 30_000, - // fullyParallel: true, - workers: 1, + fullyParallel: true, expect: { /* Maximum time expect() should wait for the condition to be met. */ timeout: 5_000, From 150adf021ea31797d688c7214c83499a484240e6 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Wed, 10 Jan 2024 18:51:27 +0900 Subject: [PATCH 29/41] (debug) log resolvePluginConfig --- packages/remix-dev/vite/plugin.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/remix-dev/vite/plugin.ts b/packages/remix-dev/vite/plugin.ts index 3dfccd9cb27..a9eaeb5bd78 100644 --- a/packages/remix-dev/vite/plugin.ts +++ b/packages/remix-dev/vite/plugin.ts @@ -864,11 +864,12 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { normalizePath(filepath) === normalizePath(viteConfig.configFile); if (appFileAddedOrRemoved || viteConfigChanged) { + console.log("[watcher:resolvePluginConfig]", { eventName, filepath }); let lastPluginConfig = pluginConfig; pluginConfig = await resolvePluginConfig(); if (!isEqualJson(lastPluginConfig, pluginConfig)) { - console.log("[watcher]", { filepath }); + console.log("[watcher:invalidateVirtualModules]", { eventName, filepath }); invalidateVirtualModules(viteDevServer); } } From 20d80280447e4152e233a1930ab646a3773db5a2 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Wed, 10 Jan 2024 18:56:33 +0900 Subject: [PATCH 30/41] (debug) tweak ci --- .github/workflows/shared-test-integration.yml | 2 +- integration/vite-hmr-hdr-test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/shared-test-integration.yml b/.github/workflows/shared-test-integration.yml index 6e5b749d500..7f07f08e558 100644 --- a/.github/workflows/shared-test-integration.yml +++ b/.github/workflows/shared-test-integration.yml @@ -56,6 +56,6 @@ jobs: run: npx playwright install --with-deps ${{ matrix.browser }} - name: 👀 Run Integration Tests ${{ matrix.browser }} - run: yarn test:integration --project=${{ matrix.browser }} --workers=1 integration/vite-hmr-hdr-test.ts + run: yarn test:integration --project=${{ matrix.browser }} --workers=1 integration/vite-hmr-hdr-test.ts -g dev env: REPEAT_EACH: 10 diff --git a/integration/vite-hmr-hdr-test.ts b/integration/vite-hmr-hdr-test.ts index d9d9ac47677..1608da450d5 100644 --- a/integration/vite-hmr-hdr-test.ts +++ b/integration/vite-hmr-hdr-test.ts @@ -62,7 +62,7 @@ test.describe(async () => { }); }); -test.describe.skip(async () => { +test.describe(async () => { let port: number; let cwd: string; let stop: () => Promise; From e24a5839fdec16acaaccb16fe1a6b5f449faa51e Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Wed, 10 Jan 2024 19:01:55 +0900 Subject: [PATCH 31/41] (debug) log handleHotUpdate more --- packages/remix-dev/vite/plugin.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/remix-dev/vite/plugin.ts b/packages/remix-dev/vite/plugin.ts index a9eaeb5bd78..d91599f08c1 100644 --- a/packages/remix-dev/vite/plugin.ts +++ b/packages/remix-dev/vite/plugin.ts @@ -1323,6 +1323,7 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { ); hmrEventData.route = newRouteMetadata; + console.log("[handleHotUpdate]", { file }); if ( !oldRouteMetadata || @@ -1336,7 +1337,7 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { ] as const ).some((key) => oldRouteMetadata[key] !== newRouteMetadata[key]) ) { - console.log("[handleHotUpdate]", { file }); + console.log("[handleHotUpdate:invalidateVirtualModules]", { file, oldRouteMetadata, newRouteMetadata }); invalidateVirtualModules(server); } } From d0031845e2c05a807301b738d186f7d1d7b07a81 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Wed, 10 Jan 2024 19:12:24 +0900 Subject: [PATCH 32/41] (debug) log edit --- integration/vite-hmr-hdr-test.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/integration/vite-hmr-hdr-test.ts b/integration/vite-hmr-hdr-test.ts index 1608da450d5..3c55777aee8 100644 --- a/integration/vite-hmr-hdr-test.ts +++ b/integration/vite-hmr-hdr-test.ts @@ -98,6 +98,8 @@ async function workflow({ page.on("pageerror", (error) => pageErrors.push(error)); let edit = createEditor(cwd); + console.log("@@\n".repeat(5)) + // setup: initial render await page.goto(`http://localhost:${port}/`, { waitUntil: "networkidle", @@ -119,6 +121,7 @@ async function workflow({ expect(pageErrors).toEqual([]); // route: HMR + console.log("@@ edit 1") await edit("app/routes/_index.tsx", (contents) => contents .replace("HMR updated title: 0", "HMR updated title: 1") @@ -131,6 +134,7 @@ async function workflow({ expect(pageErrors).toEqual([]); // route: add loader + console.log("@@ edit 2") await edit("app/routes/_index.tsx", (contents) => contents .replace( @@ -178,6 +182,7 @@ async function workflow({ pageErrors = []; // route: HDR + console.log("@@ edit 3") await edit("app/routes/_index.tsx", (contents) => contents.replace("HDR updated: 0", "HDR updated: 1") ); @@ -186,6 +191,7 @@ async function workflow({ await expect(input).toHaveValue("stateful"); // route: HMR + HDR + console.log("@@ edit 4") await edit("app/routes/_index.tsx", (contents) => contents .replace("HMR updated: 1", "HMR updated: 2") From 413539dd69a409d52c44dc4cd538c325263a1ada Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Wed, 10 Jan 2024 19:13:40 +0900 Subject: [PATCH 33/41] (debug) log sync --- packages/remix-dev/vite/plugin.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/remix-dev/vite/plugin.ts b/packages/remix-dev/vite/plugin.ts index d91599f08c1..43afee38e6f 100644 --- a/packages/remix-dev/vite/plugin.ts +++ b/packages/remix-dev/vite/plugin.ts @@ -1311,6 +1311,7 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { let hmrEventData: HmrEventData = { route: null }; if (route) { + console.log("[handleHotUpdate]", { file }); // invalidate manifest on route exports change let serverManifest = (await server.ssrLoadModule(serverManifestId)) .default as Manifest; @@ -1323,7 +1324,6 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { ); hmrEventData.route = newRouteMetadata; - console.log("[handleHotUpdate]", { file }); if ( !oldRouteMetadata || From 4968e3a82924d1b964ef19552ae6fa4e11c43e3b Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Wed, 10 Jan 2024 19:19:38 +0900 Subject: [PATCH 34/41] (debug) repeat more --- .github/workflows/shared-test-integration.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/shared-test-integration.yml b/.github/workflows/shared-test-integration.yml index 7f07f08e558..6aa206ead96 100644 --- a/.github/workflows/shared-test-integration.yml +++ b/.github/workflows/shared-test-integration.yml @@ -58,4 +58,4 @@ jobs: - name: 👀 Run Integration Tests ${{ matrix.browser }} run: yarn test:integration --project=${{ matrix.browser }} --workers=1 integration/vite-hmr-hdr-test.ts -g dev env: - REPEAT_EACH: 10 + REPEAT_EACH: 20 From f36878249c018eeba0b6fb01671a4b487de9cdd5 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Thu, 11 Jan 2024 14:05:26 +0900 Subject: [PATCH 35/41] chore: fix merge --- packages/remix-dev/vite/plugin.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/packages/remix-dev/vite/plugin.ts b/packages/remix-dev/vite/plugin.ts index f7a3313959e..b9de0ed540c 100644 --- a/packages/remix-dev/vite/plugin.ts +++ b/packages/remix-dev/vite/plugin.ts @@ -812,11 +812,10 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { } if (id.endsWith(CLIENT_ROUTE_QUERY_STRING)) { - invariant(cachedPluginConfig); let routeModuleId = id.replace(CLIENT_ROUTE_QUERY_STRING, ""); let sourceExports = await getRouteModuleExports( viteChildCompiler, - cachedPluginConfig, + pluginConfig, routeModuleId ); @@ -1074,7 +1073,6 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { } let vite = importViteEsmSync(); - let pluginConfig = await resolvePluginConfig(); let importerShort = vite.normalizePath( path.relative(pluginConfig.rootDirectory, importer) ); @@ -1312,9 +1310,6 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { if (!useFastRefresh) return; if (id.endsWith(CLIENT_ROUTE_QUERY_STRING)) { - let pluginConfig = - cachedPluginConfig || (await resolvePluginConfig()); - return { code: addRefreshWrapper(pluginConfig, code, id) }; } From 4e3880cc7d45a6fa58dc56bf970859b389bf3e46 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Thu, 11 Jan 2024 14:08:38 +0900 Subject: [PATCH 36/41] chore: more merge --- integration/vite-route-added-test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration/vite-route-added-test.ts b/integration/vite-route-added-test.ts index 42cdcfedc53..10d9b4f5872 100644 --- a/integration/vite-route-added-test.ts +++ b/integration/vite-route-added-test.ts @@ -26,7 +26,7 @@ const files = { test.describe(async () => { let port: number; let cwd: string; - let stop: () => Promise; + let stop: () => void; test.beforeAll(async () => { port = await getPort(); From 89bfae585abf1ab2127ba720136c4c5bc1563865 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Thu, 11 Jan 2024 14:14:50 +0900 Subject: [PATCH 37/41] (debug) empty file on hmr? cf. `read` callback in https://vitejs.dev/guide/api-plugin.html#handlehotupdate --- packages/remix-dev/vite/plugin.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/remix-dev/vite/plugin.ts b/packages/remix-dev/vite/plugin.ts index b9de0ed540c..fec388f9c4a 100644 --- a/packages/remix-dev/vite/plugin.ts +++ b/packages/remix-dev/vite/plugin.ts @@ -1477,6 +1477,9 @@ async function getRouteMetadata( pluginConfig, route.file ); + if (sourceExports.length === 0) { + console.log("[getRouteMetadata:empty]", route.file); + } let info = { id: route.id, From 92e3f40002d55b0ab430f36fdd4450da723d0197 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Thu, 11 Jan 2024 16:13:55 +0900 Subject: [PATCH 38/41] fix: use `HmrContext.read` instead of direct `fs.readFile` --- packages/remix-dev/vite/plugin.ts | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/remix-dev/vite/plugin.ts b/packages/remix-dev/vite/plugin.ts index fec388f9c4a..a7bd940d068 100644 --- a/packages/remix-dev/vite/plugin.ts +++ b/packages/remix-dev/vite/plugin.ts @@ -294,7 +294,8 @@ const getRouteManifestModuleExports = async ( const getRouteModuleExports = async ( viteChildCompiler: Vite.ViteDevServer | null, pluginConfig: ResolvedRemixVitePluginConfig, - routeFile: string + routeFile: string, + read?: () => string | Promise ): Promise => { if (!viteChildCompiler) { throw new Error("Vite child compiler not found"); @@ -318,7 +319,7 @@ const getRouteModuleExports = async ( let [id, code] = await Promise.all([ resolveId(), - fse.readFile(routePath, "utf-8"), + read ? read() : fse.readFile(routePath, "utf-8"), // pluginContainer.transform(...) fails if we don't do this first: moduleGraph.ensureEntryFromUrl(url, ssr), ]); @@ -1335,7 +1336,7 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { }, { name: "remix-hmr-updates", - async handleHotUpdate({ server, file, modules }) { + async handleHotUpdate({ server, file, modules, read }) { let route = getRoute(pluginConfig, file); type ManifestRoute = Manifest["routes"][string]; @@ -1352,7 +1353,8 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { let newRouteMetadata = await getRouteMetadata( pluginConfig, viteChildCompiler, - route + route, + read ); hmrEventData.route = newRouteMetadata; @@ -1470,12 +1472,14 @@ function getRoute( async function getRouteMetadata( pluginConfig: ResolvedRemixVitePluginConfig, viteChildCompiler: Vite.ViteDevServer | null, - route: ConfigRoute + route: ConfigRoute, + read: () => string | Promise ) { let sourceExports = await getRouteModuleExports( viteChildCompiler, pluginConfig, - route.file + route.file, + read, ); if (sourceExports.length === 0) { console.log("[getRouteMetadata:empty]", route.file); From ba9d396221d1c79d3d0358c62cbeb1c71e1812d8 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Thu, 11 Jan 2024 16:47:26 +0900 Subject: [PATCH 39/41] (debug) verify by repeat more + fully paralell --- .github/workflows/shared-test-integration.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/shared-test-integration.yml b/.github/workflows/shared-test-integration.yml index 6aa206ead96..7b68be03571 100644 --- a/.github/workflows/shared-test-integration.yml +++ b/.github/workflows/shared-test-integration.yml @@ -56,6 +56,6 @@ jobs: run: npx playwright install --with-deps ${{ matrix.browser }} - name: 👀 Run Integration Tests ${{ matrix.browser }} - run: yarn test:integration --project=${{ matrix.browser }} --workers=1 integration/vite-hmr-hdr-test.ts -g dev + run: yarn test:integration --project=${{ matrix.browser }} integration/vite-hmr-hdr-test.ts -g dev env: - REPEAT_EACH: 20 + REPEAT_EACH: 30 From 6b2b0b477ddd1c56f450a34448de8973e92a1dbe Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Thu, 11 Jan 2024 16:52:30 +0900 Subject: [PATCH 40/41] chore: revert debug log --- integration/helpers/vite.ts | 2 -- integration/vite-hmr-hdr-test.ts | 6 ------ packages/remix-dev/vite/plugin.ts | 7 ------- 3 files changed, 15 deletions(-) diff --git a/integration/helpers/vite.ts b/integration/helpers/vite.ts index 720230ecccd..bba3b627b33 100644 --- a/integration/helpers/vite.ts +++ b/integration/helpers/vite.ts @@ -181,8 +181,6 @@ function node(args: string[], options: { cwd: string }) { env: process.env, stdio: "pipe", }); - proc.stdout?.on("data", data => process.stdout.write(data)) - proc.stderr?.on("data", data => process.stderr.write(data)) return proc; } diff --git a/integration/vite-hmr-hdr-test.ts b/integration/vite-hmr-hdr-test.ts index 14a2ab29ce1..db6e0933bb6 100644 --- a/integration/vite-hmr-hdr-test.ts +++ b/integration/vite-hmr-hdr-test.ts @@ -98,8 +98,6 @@ async function workflow({ page.on("pageerror", (error) => pageErrors.push(error)); let edit = createEditor(cwd); - console.log("@@\n".repeat(5)) - // setup: initial render await page.goto(`http://localhost:${port}/`, { waitUntil: "networkidle", @@ -121,7 +119,6 @@ async function workflow({ expect(pageErrors).toEqual([]); // route: HMR - console.log("@@ edit 1") await edit("app/routes/_index.tsx", (contents) => contents .replace("HMR updated title: 0", "HMR updated title: 1") @@ -134,7 +131,6 @@ async function workflow({ expect(pageErrors).toEqual([]); // route: add loader - console.log("@@ edit 2") await edit("app/routes/_index.tsx", (contents) => contents .replace( @@ -182,7 +178,6 @@ async function workflow({ pageErrors = []; // route: HDR - console.log("@@ edit 3") await edit("app/routes/_index.tsx", (contents) => contents.replace("HDR updated: 0", "HDR updated: 1") ); @@ -191,7 +186,6 @@ async function workflow({ await expect(input).toHaveValue("stateful"); // route: HMR + HDR - console.log("@@ edit 4") await edit("app/routes/_index.tsx", (contents) => contents .replace("HMR updated: 1", "HMR updated: 2") diff --git a/packages/remix-dev/vite/plugin.ts b/packages/remix-dev/vite/plugin.ts index a7bd940d068..6f8fc46f388 100644 --- a/packages/remix-dev/vite/plugin.ts +++ b/packages/remix-dev/vite/plugin.ts @@ -894,12 +894,10 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { normalizePath(filepath) === normalizePath(viteConfig.configFile); if (appFileAddedOrRemoved || viteConfigChanged) { - console.log("[watcher:resolvePluginConfig]", { eventName, filepath }); let lastPluginConfig = pluginConfig; pluginConfig = await resolvePluginConfig(); if (!isEqualJson(lastPluginConfig, pluginConfig)) { - console.log("[watcher:invalidateVirtualModules]", { eventName, filepath }); invalidateVirtualModules(viteDevServer); } } @@ -1344,7 +1342,6 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { let hmrEventData: HmrEventData = { route: null }; if (route) { - console.log("[handleHotUpdate]", { file }); // invalidate manifest on route exports change let serverManifest = (await server.ssrLoadModule(serverManifestId)) .default as Manifest; @@ -1371,7 +1368,6 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { ] as const ).some((key) => oldRouteMetadata[key] !== newRouteMetadata[key]) ) { - console.log("[handleHotUpdate:invalidateVirtualModules]", { file, oldRouteMetadata, newRouteMetadata }); invalidateVirtualModules(server); } } @@ -1481,9 +1477,6 @@ async function getRouteMetadata( route.file, read, ); - if (sourceExports.length === 0) { - console.log("[getRouteMetadata:empty]", route.file); - } let info = { id: route.id, From 435a2c402d2dbaf88d98e888f3989c3d2c76fbca Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Thu, 11 Jan 2024 17:14:59 +0900 Subject: [PATCH 41/41] chore: revert more debug --- .github/workflows/shared-test-integration.yml | 4 +--- integration/playwright.config.ts | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/shared-test-integration.yml b/.github/workflows/shared-test-integration.yml index 7b68be03571..97ec135aee9 100644 --- a/.github/workflows/shared-test-integration.yml +++ b/.github/workflows/shared-test-integration.yml @@ -56,6 +56,4 @@ jobs: run: npx playwright install --with-deps ${{ matrix.browser }} - name: 👀 Run Integration Tests ${{ matrix.browser }} - run: yarn test:integration --project=${{ matrix.browser }} integration/vite-hmr-hdr-test.ts -g dev - env: - REPEAT_EACH: 30 + run: "yarn test:integration --project=${{ matrix.browser }}" diff --git a/integration/playwright.config.ts b/integration/playwright.config.ts index 2dc6d037797..62c3e39cfd3 100644 --- a/integration/playwright.config.ts +++ b/integration/playwright.config.ts @@ -13,7 +13,6 @@ const config: PlaywrightTestConfig = { }, forbidOnly: !!process.env.CI, retries: process.env.CI ? 3 : 0, - repeatEach: process.env.REPEAT_EACH ? Number(process.env.REPEAT_EACH) : undefined, reporter: process.env.CI ? "dot" : [["html", { open: "never" }]], use: { actionTimeout: 0 },