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

HMR breaks on invalid imports/syntax errors #638

Closed
simonszalai opened this issue Mar 4, 2024 · 22 comments · Fixed by #837
Closed

HMR breaks on invalid imports/syntax errors #638

simonszalai opened this issue Mar 4, 2024 · 22 comments · Fixed by #837
Labels
help wanted Extra attention is needed

Comments

@simonszalai
Copy link

simonszalai commented Mar 4, 2024

I just tried this on a newly created vanilla epic-stack app. If I save a file with an invalid input, I get an error like the one below. After that, if I save it again with the correct path, HMR is not picking up the change (also no full reload is happening). I need to kill the dev server and run npm run dev again, which can take a while. This slows me down quite a bit, happening tens of times per hour. Did not have this problem before upgrading to Vite, which was aimed to dramatically reduce the time we waste on reloading changes. Sadly for me it did the opposite.

Press Ctrl+C to stop
9:42:13 PM [vite] Pre-transform error: Failed to load url ./components/error-boundar.tsx (resolved id: ./components/error-boundar.tsx) in /Users/simon/dev/epic-app-test/app/root.tsx. Does the file exist?
9:42:14 PM [vite] Error when evaluating SSR module /app/root.tsx: failed to import "./components/error-boundar.tsx"
|- Error: Failed to load url ./components/error-boundar.tsx (resolved id: ./components/error-boundar.tsx) in /Users/simon/dev/epic-app-test/app/root.tsx. Does the file exist?
    at loadAndTransform (file:///Users/simon/dev/epic-app-test/node_modules/vite/dist/node/chunks/dep-jDlpJiMN.js:53601:21)
    at instantiateModule (file:///Users/simon/dev/epic-app-test/node_modules/vite/dist/node/chunks/dep-jDlpJiMN.js:54623:10)

9:42:14 PM [vite] Error when evaluating SSR module virtual:remix/server-build: failed to import "/app/root.tsx"
|- Error: Failed to load url ./components/error-boundar.tsx (resolved id: ./components/error-boundar.tsx) in /Users/simon/dev/epic-app-test/app/root.tsx. Does the file exist?
    at loadAndTransform (file:///Users/simon/dev/epic-app-test/node_modules/vite/dist/node/chunks/dep-jDlpJiMN.js:53601:21)
    at instantiateModule (file:///Users/simon/dev/epic-app-test/node_modules/vite/dist/node/chunks/dep-jDlpJiMN.js:54623:10)

Error: Failed to load url ./components/error-boundar.tsx (resolved id: ./components/error-boundar.tsx) in /Users/simon/dev/epic-app-test/app/root.tsx. Does the file exist?
Error: Failed to load url ./components/error-boundar.tsx (resolved id: ./components/error-boundar.tsx) in /Users/simon/dev/epic-app-test/app/root.tsx. Does the file exist?
    at loadAndTransform (file:///Users/simon/dev/epic-app-test/node_modules/vite/dist/node/chunks/dep-jDlpJiMN.js:53601:21)
    at instantiateModule (file:///Users/simon/dev/epic-app-test/node_modules/vite/dist/node/chunks/dep-jDlpJiMN.js:54623:10)

@kentcdodds
Copy link
Member

This is probably a bug in vite or remix so you'll want to open an issue there. But I have to ask... Do you really change file names 10 times an hour?

@simonszalai
Copy link
Author

simonszalai commented Mar 5, 2024

It can happen for various reasons, happens if I rename a file or move a file, and even on syntax errors. Also I use an addon to automatically add imports, and sometimes it creates an import that doesn't have an extension, so I have to add it manually. It really does happen often.

Seems like there is a pre-transform step, and if that fails, I need to restart the dev server: Pre-transform error: Transform failed with 1 error

Do you think its more likely a bug in remix or vite?

@simonszalai simonszalai changed the title HMR breaks on invalid inputs HMR breaks on invalid imports Mar 5, 2024
@simonszalai
Copy link
Author

I was about to open an issue on vite, then I created a new React/Remix project with npm create vite@latest, and it's not an issue there at all. I can save a file with invalid imports or syntax errors and as soon as I fix it, HMR picks it up.

@simonszalai simonszalai changed the title HMR breaks on invalid imports HMR breaks on invalid imports/syntax errors Mar 5, 2024
@kentcdodds
Copy link
Member

This could still be a bug in Remix when you use a custom server (like we do with Express).

Anyone who can do some additional investigation in this is appreciated!

@kentcdodds kentcdodds added the help wanted Extra attention is needed label Mar 5, 2024
@ajwtech
Copy link
Contributor

ajwtech commented Mar 8, 2024

I think you are right I use Code-Forge-Net/Remix-Dev-Tools and vite-tsconfig-paths so I dont have those types of issues. I havent done the complete setup of remix-dev-tools yet. just installed it and added in to the vite config.

@simonszalai
Copy link
Author

I'm also using vite-tsconfig-paths. How does that avoid the issue for you? It even occurs for me when global imports or package imports are invalid, so I don't think the tsconfig aliases are the cause.

@ajwtech
Copy link
Contributor

ajwtech commented Mar 9, 2024

If I remove Code-Forge-Net/Remix-Dev-Tools it start happening again.
If I remove vite-tsconfig-paths it starts happening again as well.

I came across someone who had posted that they were having this problem when they resolved it I started trying to figure out if any of their vite.config.ts changes fixed it for me. Their last post was just "something fixed it, I dont know what." These were in their tsconfig.

I wish I had a better answer than that. but I think that tsconfig-paths is needed for Remix dev tools to work and remix dev tools is what actually allows the debugger to reconnect to vscode. I did actually finish the setup of that after my last comment. I hope this helps in some way. If you do install devtools make sure you look at the install instructions for the configuration details.

vite.config.ts

import { vitePlugin as remix } from '@remix-run/dev'
import { remixDevTools } from "remix-development-tools/vite"
import { flatRoutes } from 'remix-flat-routes'
import { defineConfig } from 'vite'
import tsconfigPaths from 'vite-tsconfig-paths'

const MODE = process.env.NODE_ENV

export default defineConfig({

	build: {
		cssMinify: MODE === 'production',
		rollupOptions: {
			external: [/node:.*/, 'stream', 'crypto', 'fsevents'],
		},
	},
	plugins: [
		remixDevTools(),
		remix({
			ignoredRouteFiles: ['**/*'],
			serverModuleFormat: 'esm',
			routes: async defineRoutes => {
				return flatRoutes('routes', defineRoutes, {
					ignoredRouteFiles: [
						'.*',
						'**/*.css',
						'**/*.test.{js,jsx,ts,tsx}',
						'**/__*.*',
						// This is for server-side utilities you want to colocate next to
						// your routes without making an additional directory.
						// If you need a route that includes "server" or "client" in the
						// filename, use the escape brackets like: my-route.[server].tsx
						'**/*.server.*',
						'**/*.client.*',
					],
				})
			},
		}),
		tsconfigPaths()
	],
}) 

@AlemTuzlak
Copy link
Contributor

@ajwtech "installing it and adding it to the vite config" is the WHOLE setup. Although the rdt plugin shouldn't either help or cause this issue.

@simonszalai
Copy link
Author

I just tried it on a fresh Epic Stack app, adding rdt or tsconfigpaths did not make any difference. @ajwtech do you have the link about the discussion you mentioned? Maybe it will help.

@ajwtech
Copy link
Contributor

ajwtech commented Mar 11, 2024

@ajwtech "installing it and adding it to the vite config" is the WHOLE setup. Although the rdt plugin shouldn't either help or cause this issue.

I'll upgrade to v4 and try it out, but those comments were for v3.7.4 which was the latest last week. There was more to do to actually get it working which I did get working last week. From what you're saying though it sounds like it should now work with a custom vite server even if I remove:

// Make sure you guard this with NODE_ENV check
if(MODE === 'development') {
const { withServerDevTools, defineServerConfig } = await import("remix-development-tools/server"); 
	// Allows you to define the configuration for the dev tools
	let devToolsConfig = defineServerConfig({ 
	//... your config here ...
})
// wrap the build with the dev tools

	withServerDevTools(build, devToolsConfig)

}

@ajwtech
Copy link
Contributor

ajwtech commented Mar 11, 2024

I just tried it on a fresh Epic Stack app, adding rdt or tsconfigpaths did not make any difference. @ajwtech do you have the link about the discussion you mentioned? Maybe it will help.

I'll see if I can find it again. I'll dig deeper into this too. There may be something else I changed that made it work as a side effect.

@AlemTuzlak
Copy link
Contributor

@ajwtech "installing it and adding it to the vite config" is the WHOLE setup. Although the rdt plugin shouldn't either help or cause this issue.

I'll upgrade to v4 and try it out, but those comments were for v3.7.4 which was the latest last week. There was more to do to actually get it working which I did get working last week. From what you're saying though it sounds like it should now work with a custom vite server even if I remove:

// Make sure you guard this with NODE_ENV check
if(MODE === 'development') {
const { withServerDevTools, defineServerConfig } = await import("remix-development-tools/server"); 
	// Allows you to define the configuration for the dev tools
	let devToolsConfig = defineServerConfig({ 
	//... your config here ...
})
// wrap the build with the dev tools

	withServerDevTools(build, devToolsConfig)

}

I was talking about 3.7.4, I created the package, it was only required to be added to vite plugins when it came to remix vite projects, no setup on the server or the client besides that

@ajwtech
Copy link
Contributor

ajwtech commented Mar 12, 2024

I just tried it on a fresh Epic Stack app, adding rdt or tsconfigpaths did not make any difference. @ajwtech do you have the link about the discussion you mentioned? Maybe it will help.

@simonszalai I was not able to find the post from before but I think it is irrelevant now. Here is what I found after digging in. The error seems to be driven from ssrLoadModule and it is recoverable if you can retrigger the live reload. however when this happens the only file that is still being watched that I could find is the index.ts

I have been doing a lot of reconfiguring of the vite setup since finding this and have found a configuration that fixes this issue. I've not finished setting it up to work out any issues with it but as you can see the server recovers as it is supposed to with this:

LOADER root triggered - 3.63 ms
11:49:14 AM [vite] hmr update /app/components/error-boundary.tsx, /app/styles/tailwind.css?direct
LOADER root triggered - 1.68 ms
11:49:19 AM [vite] page reload app/components/error-boundary.tsx
11:49:19 AM [vite] hmr update /app/components/error-boundary.tsx, /app/styles/tailwind.css?direct
11:49:19 AM [vite] Error when evaluating SSR module /app/root.tsx: failed to import "/app/components/error-boundary.tsx"
|- Error: Failed to load url /app/components/error-boundary.tsx (resolved id: D:/source/polycreteusa.com/newGallery/epic-hs-gallery-app/app/components/error-boundary.tsx) in D:/source/polycreteusa.com/newGallery/epic-hs-gallery-app/app/root.tsx. Does the file exist?
    at loadAndTransform (file:///D:/source/polycreteusa.com/newGallery/epic-hs-gallery-app/node_modules/vite/dist/node/chunks/dep-jvB8WLp9.js:53736:21)
    at async instantiateModule (file:///D:/source/polycreteusa.com/newGallery/epic-hs-gallery-app/node_modules/vite/dist/node/chunks/dep-jvB8WLp9.js:54797:10)

11:49:19 AM [vite] Error when evaluating SSR module virtual:remix/server-build: failed to import "/app/root.tsx"
|- Error: Failed to load url /app/components/error-boundary.tsx (resolved id: D:/source/polycreteusa.com/newGallery/epic-hs-gallery-app/app/components/error-boundary.tsx) in D:/source/polycreteusa.com/newGallery/epic-hs-gallery-app/app/root.tsx. Does the file exist?
    at loadAndTransform (file:///D:/source/polycreteusa.com/newGallery/epic-hs-gallery-app/node_modules/vite/dist/node/chunks/dep-jvB8WLp9.js:53736:21)
    at async instantiateModule (file:///D:/source/polycreteusa.com/newGallery/epic-hs-gallery-app/node_modules/vite/dist/node/chunks/dep-jvB8WLp9.js:54797:10)

11:49:19 AM [vite] Internal server error: Failed to load url /app/components/error-boundary.tsx (resolved id: D:/source/polycreteusa.com/newGallery/epic-hs-gallery-app/app/components/error-boundary.tsx) in D:/source/polycreteusa.com/newGallery/epic-hs-gallery-app/app/root.tsx. Does the file exist?
      at loadAndTransform (file:///D:/source/polycreteusa.com/newGallery/epic-hs-gallery-app/node_modules/vite/dist/node/chunks/dep-jvB8WLp9.js:53736:21)
      at async instantiateModule (file:///D:/source/polycreteusa.com/newGallery/epic-hs-gallery-app/node_modules/vite/dist/node/chunks/dep-jvB8WLp9.js:54797:10)
11:49:38 AM [vite] page reload app/components/error-boundary.tsx
11:49:38 AM [vite] hmr update /app/components/error-boundary.tsx
LOADER root triggered - 1.39 ms
11:49:38 AM [vite] page reload app/components/error-boundar.tsx
LOADER root triggered - 3.96 ms

The remix documentation is a bit confusing and maybe misleading because it looks like they have both the experimental integration and the released integration instructions hosted on the docs. Following the documentation that states remix is now just a vite plugin in combination with Vites SSR docs have got me here.

I'll finish running through this and share all my changes with you. Probably a couple more hours of effort.

@ajwtech
Copy link
Contributor

ajwtech commented Mar 13, 2024

So the problem I have run into now is that I broke my production system. everything works except the site root just shows up blank. I think this is related to some changes I have stashed though. I'll figure that out later. for now:

  • change dev script in package.json to "dev": "remix vite:dev",
  • change tsconfig.json includes to "include": ["types/vite.env.d.ts", "**/*.ts", "**/*.tsx"],
  • added types to vite.env.d.ts This may be the cause of my blank page issue.
/// <reference types="vite/client" />
/// <reference types="@remix-run/node/globals" />


interface ImportMetaEnv {
  readonly VITE_APP_TITLE: string
  // more env variables...
}

interface ImportMeta {
  readonly env: ImportMetaEnv
}
  • then changed the server/index.ts get build and app.all to:
async function getBuild() {
	const build =
		viteDevServer
			? await viteDevServer.ssrLoadModule('virtual:remix/server-build')
			: await import('#build/server/index.js')
	return build 
}

app.all(
	'*',
	async (req, res, next) => {
		const build = await getBuild();
		createRequestHandler({
			getLoadContext: async (_: any, res: any) => ({
				cspNonce: res.locals.cspNonce,
				serverBuild: await getBuild(),
			}),
			mode: MODE,
			build: build,
		})(req, res, next);
	}
);

This isnt yet a complete solution but it works well in dev.

@simonszalai
Copy link
Author

simonszalai commented Mar 14, 2024

Thank you so much, I'll try it soon!

EDIT: It does indeed work, thank you! My app is not in production yet, so I didn't try that part, but I hope you can figure that out as well eventually.

With your code I got a TS error though, which I could easily fix with an assertion (see below), just putting it here because it might give you a clue fixing the build issue.

async function getBuild() {
	const build = viteDevServer
		? await viteDevServer.ssrLoadModule('virtual:remix/server-build')
		: await import('#build/server/index.js')
	return build as ServerBuild // Added here
}

@simonszalai
Copy link
Author

Looks like nonce broke:

chunk-DAMSANAS.js?v=e4a89767:2027 Warning: Prop `nonce` did not match. Server: "undefined" Client: ""
    at script
    at ClientHintCheck (http://localhost:3000/app/utils/client-hints.tsx:33:3)
    at head
    at html
    at Document (http://localhost:3000/app/root.tsx:110:3)
    at App (http://localhost:3000/app/root.tsx:223:16)
    at HoneypotProvider (http://localhost:3000/node_modules/.vite/deps/remix-utils_honeypot_react.js?v=e4a89767:27:29)
    at AppWithProviders (http://localhost:3000/app/root.tsx:259:16)
    at SentryRoot
    at AppWithDevTools (http://localhost:3000/node_modules/.vite/deps/remix-development-tools.js?v=e4a89767:27291:22)
    at RenderedRoute (http://localhost:3000/node_modules/.vite/deps/chunk-OMF3HZP7.js?v=e4a89767:397:5)
    at RenderErrorBoundary (http://localhost:3000/node_modules/.vite/deps/chunk-OMF3HZP7.js?v=e4a89767:357:5)
    at DataRoutes (http://localhost:3000/node_modules/.vite/deps/chunk-OMF3HZP7.js?v=e4a89767:1385:5)
    at Router (http://localhost:3000/node_modules/.vite/deps/chunk-OMF3HZP7.js?v=e4a89767:738:15)
    at RouterProvider (http://localhost:3000/node_modules/.vite/deps/chunk-OMF3HZP7.js?v=e4a89767:1202:5)
    at RemixErrorBoundary (http://localhost:3000/node_modules/.vite/deps/chunk-OMF3HZP7.js?v=e4a89767:2969:5)
    at RemixBrowser (http://localhost:3000/node_modules/.vite/deps/chunk-OMF3HZP7.js?v=e4a89767:3810:46)

@ajwtech
Copy link
Contributor

ajwtech commented Mar 18, 2024

in nonce-provider.ts

export const NonceContext = React.createContext<string>("undefined")

This is the fallback nonce it should be the same as what the server has but my guess here is that they have been separated to work around issues with nonce and error boundary. 🤷‍♂️

@simonszalai
Copy link
Author

@ajwtech did you find the whole solution by any chance?

@quangIle
Copy link

quangIle commented Apr 26, 2024

Hi, I want to share my current solution based on yours. It works properly and I just need to reload the browser. I also look at the source code of createRequestHandler (here), putting await to getBuild() fixes the problem.

app.all(
  '*',
  createRequestHandler({
-     getLoadContext: (_, res) => ({
+     getLoadContext: async (_, res) => ({
      cspNonce: res.locals.cspNonce,
-     serverBuild: getBuild(),
+     serverBuild: await getBuild(),
    }),
    mode: MODE,
    build: getBuild,
  }),
)

@kentcdodds
Copy link
Member

That's unexpected! But if it fixes the issue then I guess we should do it 🤷‍♂️

@kentcdodds
Copy link
Member

Hmmm... After checking it some more, I'm pretty sure this solution is unrelated. I don't get any difference before/after.

I'm not sure which tool in the tool chain is causing the problems, but I'm pretty sure the fix will not come in the epic stack but one of the underlying tools.

@ajwtech
Copy link
Contributor

ajwtech commented Apr 29, 2024 via email

agcty added a commit to agcty/epic-stack that referenced this issue Sep 4, 2024
agcty added a commit to agcty/epic-stack that referenced this issue Sep 4, 2024
@agcty agcty mentioned this issue Sep 4, 2024
kentcdodds pushed a commit that referenced this issue Sep 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants