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

templates(cloudflare-workers): use static assets #10034

Merged
merged 5 commits into from
Oct 31, 2024

Conversation

edmundhung
Copy link
Contributor

@edmundhung edmundhung commented Sep 26, 2024

This PR updates the cloudflare-workers template to use the Static Assets feature announced today.

Note: Static assets is currently in open beta

You can learn more about Static Assets in the documentation.

Closes: #

  • Docs
  • Tests

Testing Strategy:

To test, please run create-remix with the template on my fork

npx create-remix@latest --template edmundhung/remix/templates/cloudflare-workers

Then deploy it with wrangler by running:

npm run deploy

Woohoo! Your Remix app is now running on Cloudflare Workers: https://template.remix-run.workers.dev

Copy link

changeset-bot bot commented Sep 26, 2024

⚠️ No Changeset found

Latest commit: 1c039ca

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@edmundhung edmundhung force-pushed the workers-assets branch 2 times, most recently from 0286b11 to 38cd5c9 Compare September 26, 2024 23:29
@edmundhung edmundhung changed the title Update cloudflare worker template to use static assets Update cloudflare-workers template to use static assets Sep 27, 2024
@edmundhung edmundhung force-pushed the workers-assets branch 3 times, most recently from c59ad09 to 10776e5 Compare September 27, 2024 10:41
@ayuhito
Copy link

ayuhito commented Sep 28, 2024

I've been testing this template and it's been working flawlessly. However, has anyone else managed to make the asset binding work? I keep getting TypeError: Cannot read properties of undefined (reading 'fetch') when using the Fetcher interface of the asset binding.

This only occurs when running the dev script with remix:vite dev. wrangler dev seems to work, although that requires the whole build step.

@tsteckenborn
Copy link

@ayuhito are you when running pnpm devalso seeing the state error or is that something on my machine? 😕

So it's showing the page, but I'm seeing the error in the terminal.

> remix vite:dev

Re-optimizing dependencies because lockfile has changed
  ➜  Local:   http://localhost:5173/
  ➜  Network: use --host to expose
  ➜  press h + enter to show help
TypeError [ERR_INVALID_STATE]: Invalid state: Controller is already closed
    at ReadableByteStreamController.close (node:internal/webstreams/readablestream:1157:13)

@ayuhito
Copy link

ayuhito commented Sep 28, 2024

also seeing the state error or is that something on my machine?

Nope. I've got a different error to that. I was alluding to the fact that cloudflareDevProxyVitePlugin might not perfectly handle the static assets interface in my comment.

@MichaelDeBoey MichaelDeBoey changed the title Update cloudflare-workers template to use static assets templates(cloudflare-workers): use static assets Sep 29, 2024
@FraBle
Copy link

FraBle commented Oct 2, 2024

Is there any rough timeline for when this PR might land? (excited about using it)

Copy link

@petebacondarwin petebacondarwin left a comment

Choose a reason for hiding this comment

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

This looks good to me. If we can land this we can fix up the create-cloudflare tool to point to it.

@focux
Copy link

focux commented Oct 4, 2024

Does this same setup work for SPA mode?

@acusti
Copy link
Contributor

acusti commented Oct 7, 2024

Static Assets (aka Workers Assets) is currently in beta, but according to the Wrangler configuration docs, Workers Sites has been deprecated in favor of Workers Assets:

site object optional deprecated

  • See the Workers Sites section below for more information. Cloudflare Pages and Workers Assets is preferred over this approach.

also, i’ve been using it in production (same as the implementation introduced here) without issue for a few weeks now.

my only comment on this PR is that i’m not sure whether or not it’s worth including the custom getLoadContext pattern for augmenting load context, because it seems like more of an advanced pattern. but it also seems pretty harmless, and maybe it will help template consumers discover the pattern if they find the need for it, so i don’t mind either way.


@focux i haven’t tried it, but i can’t imagine why it wouldn’t work for SPA mode. the static assets feature matches any request to any file in the specified directory (./build/client/ in Remix), so it serves any built JS and HTML (and any other static files placed in the ./public/ directory) automatically.


@FraBle you can use this right away for new projects by using the fork:

npx create-remix@latest --template edmundhung/remix/templates/cloudflare-workers

or just manually apply the diff of this PR to an existing Remix / Cloudflare Workers project if you have one.

Comment on lines +19 to +21
export function getLoadContext({ context }: GetLoadContextArgs) {
return context;
}
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
export function getLoadContext({ context }: GetLoadContextArgs) {
return context;
}
export const getLoadContext = ({ context }: GetLoadContextArgs) => context;

// `getPlatformProxy` used during development via Remix's
// `cloudflareDevProxyVitePlugin`:
// https://developers.cloudflare.com/workers/wrangler/api/#getplatformproxy
cf: request.cf,
Copy link
Contributor

Choose a reason for hiding this comment

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

This causes a type error, should it just be cast to any?

Choose a reason for hiding this comment

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

I think we can just set it to

cf: request.cf!

Or, we can change load-context.ts to:

type GetLoadContextArgs = {
  request: Request;
  context: {
    cloudflare: Omit<PlatformProxy<Env, IncomingRequestCfProperties>, "dispose" | "caches" | "cf"> & {
      caches: PlatformProxy<Env, IncomingRequestCfProperties>['caches'] | CacheStorage;
      cf: Request['cf'];
    };
  };
}

The first is simpler, but the second is better.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'd prefer correctness, I'll defer to @edmundhung

Copy link
Contributor

Choose a reason for hiding this comment

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

when I ran into this issue in my own codebase, I looked into it and wound up going with the non-null assertion operator (cf: request.cf!) based on the Cloudflare docs, which explain that “the request.cf object is not available in the Cloudflare Workers dashboard or Playground preview editor”: https://developers.cloudflare.com/workers/runtime-apis/request/#incomingrequestcfproperties

in every other case, the request.cf object is defined and available, so I figured it seemed safe to assert that in this context.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The request.cf object is not always available as @acusti shared so I adopted the 2nd solution @laishere suggested.

@AdiRishi
Copy link
Contributor

Really keen for this to land!

I do have a question, I haven't been able to find a good answer to this yet. How can we set cache-control headers for static asssets server via the new method? Previously the ttl was being configured in code, and in Cloudflare Pages it's configured via the _headers file. What's the strategy here? I can see under the new template all assets use public, max-age=0, must-revalidate as the cache control header.

@edmundhung edmundhung force-pushed the workers-assets branch 2 times, most recently from 75740be to d9fcd55 Compare October 30, 2024 16:02
@edmundhung
Copy link
Contributor Author

Really keen for this to land!

I do have a question, I haven't been able to find a good answer to this yet. How can we set cache-control headers for static asssets server via the new method? Previously the ttl was being configured in code, and in Cloudflare Pages it's configured via the _headers file. What's the strategy here? I can see under the new template all assets use public, max-age=0, must-revalidate as the cache control header.

They are not supported yet. But you can find some workarounds under the Static Assets section: https://developers.cloudflare.com/workers/static-assets/compatibility-matrix/

Copy link
Contributor

@brookslybrand brookslybrand left a comment

Choose a reason for hiding this comment

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

Looks great to me, thanks so much @edmundhung!

@brookslybrand brookslybrand merged commit 04abe37 into remix-run:main Oct 31, 2024
2 checks passed
@edmundhung edmundhung deleted the workers-assets branch November 4, 2024 22:19
@tsteckenborn
Copy link

Is there already a port of this to RR7? @brookslybrand it seems like the type in @react-router/cloudflare over there for the cloudflare createRequestHandler is createPagesFunctionHandlerParams, which might be misleading as it could also be a worker?

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.