Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

fix(remix-dev/vite, remix-server-runtime): handle criticalCss in an adapter agnostic way #8076

Merged

Conversation

hi-ogawa
Copy link
Contributor

@hi-ogawa hi-ogawa commented Nov 21, 2023

Closes: #7878

(EDIT: virtual module + globalThis approach is rewritten with explicit get/set API exposed by @remix-run/server-runtime. The following comment is only about the former approach.)

This PR adds __unstableRemixViteRuntime to virtual ServerBuild so that server-runtime can use it to implement certain vite dev specific features such as criticalCss (and also my motivation is to use this to expose ssrFixStacktrace #8066).
The idea is that, by extending ServerBuild, it allows server-runtime layer to handle certain features instead of adapter layer.

Messing with globalThis is probably not ideal (since this is essentially exposing API from @remix-run/dev to @remix-run/server-runtime via globalThis.__unstableRemixViteRuntime), but I saw there are other frameworks making use of similar approach to expose certain dev features through virtual module, for examples:

So, I thought this ideas is worth a shot, so I put together a PR. Please let me know if this approach is worth considering. Thanks!

Testing Strategy

Existing tests (namely vite-css-dev-test.ts and vite-css-dev-express-test.ts) should cover the functionality.

Copy link

changeset-bot bot commented Nov 21, 2023

🦋 Changeset detected

Latest commit: 80797d6

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 16 packages
Name Type
@remix-run/dev Patch
@remix-run/server-runtime Patch
@remix-run/cloudflare Patch
@remix-run/deno Patch
@remix-run/node Patch
@remix-run/react Patch
@remix-run/cloudflare-pages Patch
@remix-run/cloudflare-workers Patch
@remix-run/architect Patch
@remix-run/express Patch
@remix-run/serve Patch
@remix-run/testing Patch
create-remix Patch
remix Patch
@remix-run/css-bundle Patch
@remix-run/eslint-config Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@hi-ogawa hi-ogawa changed the title refactor(vite): expose RemixViteRuntime to handle critcalCss in an adapter agnostic way refactor(vite): handle critcalCss in an adapter agnostic way by exposing RemixViteRuntime Nov 21, 2023
@hi-ogawa hi-ogawa changed the title refactor(vite): handle critcalCss in an adapter agnostic way by exposing RemixViteRuntime refactor(vite): handle critcalCss in an adapter agnostic way Nov 21, 2023
@hi-ogawa hi-ogawa marked this pull request as ready for review November 21, 2023 05:54
@hi-ogawa hi-ogawa changed the title refactor(vite): handle critcalCss in an adapter agnostic way refactor(remix-dev/vite, server-runtime): handle critcalCss in an adapter agnostic way Nov 21, 2023
@hi-ogawa hi-ogawa changed the title refactor(remix-dev/vite, server-runtime): handle critcalCss in an adapter agnostic way refactor(remix-dev/vite, remix-server-runtime): handle critcalCss in an adapter agnostic way Nov 21, 2023
Copy link
Member

@markdalgleish markdalgleish left a comment

Choose a reason for hiding this comment

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

I love that this means consumers don't need to worry about managing the critical CSS for custom servers. I've pushed some refactors, mainly to get rid of the indirection of modifying the server build, but overall this looks good to me.

Since my changes were pretty significant, I'm throwing it to @pcattori to have a look too.

packages/remix-server-runtime/dev.ts Outdated Show resolved Hide resolved
) {
(res.locals as Record<string, any>).__remixDevCriticalCss =
criticalCss;
}
Copy link
Member

Choose a reason for hiding this comment

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

This is such a nice clean up 🎉

@markdalgleish markdalgleish changed the title refactor(remix-dev/vite, remix-server-runtime): handle critcalCss in an adapter agnostic way refactor(remix-dev/vite, remix-server-runtime): handle criticalCss in an adapter agnostic way Nov 23, 2023
Comment on lines +36 to +46
const globalDevServerHooksKey = "__remix_devServerHooks";

export function setDevServerHooks(devServerHooks: DevServerHooks) {
// @ts-expect-error
globalThis[globalDevServerHooksKey] = devServerHooks;
}

export function getDevServerHooks(): DevServerHooks | undefined {
// @ts-expect-error
return globalThis[globalDevServerHooksKey];
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nice! I didn't think about exposing get/set API.
If I look at this simplicity, then I wonder if it would also work with just using local let variable like:

let _devServerHooks: DevServerHooks | undefined;

export function setDevServerHooks(devServerHooks: DevServerHooks) {
  _devServerHooks = devServerHooks
}

export function getDevServerHooks(): DevServerHooks | undefined {
  return _devServerHooks;
}

But this might have issues when dual package hazard like scenario (user-code is esm, but remix library is commonjs)?


I was just looking at the sveltekit for how they deal with ssrFixStacktrace and it looks like they have a clever way to pass "vite server thing" to "runtime":

https://github.com/sveltejs/kit/blob/b6c7e8b574b28b83407c068757a456d511891027/packages/kit/src/exports/vite/dev/index.js#L464-L467

				const { set_fix_stack_trace } = await vite.ssrLoadModule(
					`${runtime_base}/shared-server.js`
				);
				set_fix_stack_trace(fix_stack_trace);

https://github.com/sveltejs/kit/blob/b6c7e8b574b28b83407c068757a456d511891027/packages/kit/src/runtime/shared-server.js#L20-L24

export let fix_stack_trace = (error) => error?.stack;

export function set_fix_stack_trace(value) {
	fix_stack_trace = value;
}

I'm still digesting what's happening with this, but it might be possible to avoid globalThis, so I'll investigate further and I can follow up with a separate PR if I find a better way.

@markdalgleish markdalgleish changed the title refactor(remix-dev/vite, remix-server-runtime): handle criticalCss in an adapter agnostic way fix(remix-dev/vite, remix-server-runtime): handle criticalCss in an adapter agnostic way Nov 23, 2023
@markdalgleish markdalgleish merged commit 6953c3f into remix-run:dev Nov 23, 2023
9 checks passed
@markdalgleish
Copy link
Member

@hi-ogawa Thanks so much for kicking off this PR. This is a massive improvement.

@hi-ogawa hi-ogawa deleted the refactor-vite-unstableRemixViteRuntime branch November 23, 2023 03:50
Copy link
Contributor

github-actions bot commented Dec 5, 2023

🤖 Hello there,

We just published version 2.4.0-pre.0 which includes this pull request. If you'd like to take it for a test run please try it out and let us know what you think!

Thanks!

Copy link
Contributor

🤖 Hello there,

We just published version 2.4.0 which includes this pull request. If you'd like to take it for a test run please try it out and let us know what you think!

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants