nitrojs / nitro

Next Generation Server Toolkit. Create web servers with everything you need and deploy them wherever you prefer.
https://nitro.build
MIT License
6.32k stars 522 forks source link

cloudflare-pages-static with Functions #196

Closed pi0 closed 6 months ago

pi0 commented 2 years ago

Reference: nuxt/framework#110

@warflash Cloudflare pages for static assets + functions for ssr and dynamic content would be awesome!

warflash commented 2 years ago

Nice! Really looking forward to that.

Related discussions for easy future reference: https://github.com/nuxt/framework/discussions/2471 https://github.com/nuxt/framework/discussions/1528 https://github.com/unjs/nitro/discussions/110

@DaniFoldi πŸŽ‰

DaniFoldi commented 2 years ago

I'll look into implementing this sometime this week (I have a test repo that works), probably create a draft PR, would be very helpful if someone with more nitro knowledge could take a look

DaniFoldi commented 2 years ago

@warflash I've got nuxt/nuxt.js#10951 drafted, looking for feedback now

warflash commented 2 years ago

Awesome, great work! I can't give much feedback on the preset itself but what I did notice is the use of _workers.js. That reminded me of a conversation on the cloudflare discord I read:

Functions in particular has been interesting (to me, at least). SvelteKit opted for using _worker.js, whereas Remix and Qwik have opted for functions/[[all]].ts. Plugins should technically work with the later two, but won’t (currently) with SvelteKit, because of that decision. Maybe we encourage SvelteKit to move to the functions folder, or maybe we offer some other way into the Plugins ecosystem. Haven’t quite worked that bit out yet.

That makes it sounds like functions/[[all]].ts is the recommended way forward. I haven't used plugins yet nor am I experienced with nitro presets so I'm not sure how big of a change that is. Figured I'd drop it here in case that's something that's required in the future or when there's people asking about it.

Again, nicely done πŸš€

AlexDicy commented 2 years ago

Awesome, great work! I can't give much feedback on the preset itself but what I did notice is the use of _workers.js. [...]

Again, nicely done πŸš€

I agree. I've also noticed that the code doesn't mention the filename to use when compiling the server.

With my implementation I had to rename the server file from index.mjs to _workers.js (and move it to /public), how is this handled in this PR?

DaniFoldi commented 2 years ago

Correct, should be functions/[[all]].ts for plugin compatibility. Bear in mind plugins are very new, and weren't a thing when I first started experimenting with this combo πŸ˜…

Note to future self: In that case we could also have functions/ as the server output directory

warflash commented 2 years ago

Oh actually something else to note on the _workers.js vs. functions/[[all]].ts topic, currently all static asset requests count as function invocations it seems. Though supposedly that will change once pages go out of beta (maybe we'll already see that with next weeks platform week). After beta only actual functions/[[all]].ts calls are billable whereas _workers.js still proxies every static asset. Atleast that's my understanding of the conversations I read. Maybe @geelen has more insight on that one 🀞

geelen commented 2 years ago

Nah there'll be no difference in terms of billing for functions/[[all]].ts and _workers.js. The current plan is you'll emit a _routes.json as well which can include or exclude paths to run your Worker on. It's not the best api but it's the only way to give frameworks like Nuxt full control over the routing. There are some implementation decisions that are influencing the specifics, but this is the plan.

I think we'll try to bring Plugins into _worker.js builds in the future, since right now it's pretty awkward to use functions/[[all]].ts, except as a straight build output. If you have other files in the functions dir you want to .gitignore [[all.ts]], for example, and it's weird having out and input next to each other in a dir.

But Pages Plugins are new, cool, and it'd be nice to know if they're useful to Nuxt folks.

DaniFoldi commented 2 years ago

@geelen Is the API for this known (even if not yet implemented/available)? If so, would you mind sharing some more details so this PR can implement it properly?

geelen commented 2 years ago

It'll be quite similar to tsconfig include/exclude but the exact wildcard support is not finalised as we need to do some perf testing on a couple of options. Had to be paused while we were finishing off a few other things (https://blog.cloudflare.com/tag/cloudflare-pages/ top 3 links all landed this week).

For now, it's a super good idea if all/most of your assets are under a prefix like /static/* or all your dynamic routes are under a prefix like /api/*. The fewer lines in your _routes.json the better, but we're trying to make it fast enough so it's still good if static and dynamic routes are fully intermingled.

DaniFoldi commented 2 years ago

Quick update from my side, I have @danifoldi/nitropack published to npm for testing (do not use for anything other than a test, I intend to unpublish in a few months).

Check https://nitro-pages-functions.pages.dev/route for a nitro-rendered page and https://nitro-pages-functions.pages.dev/test for a Pages-served static asset. This repo also uses the overrided nitropack to allow some real-world tests.

There's probably something that still won't work, and there will be a bit more work once Functions are in GA and include/exclude system mentioned above can be used to pass static asset requests directly to Pages. Let me know if(when) you find any bug, or anything else that's missing.

Rigo-m commented 2 years ago

@DaniFoldi have you tried deploying nuxt3 by resolving nitropack to your npm repository and deploy it to cloudflare pages? I would like to try it

DaniFoldi commented 2 years ago

@Rigo-m I haven't tried nuxt yet, just a nitro page.

I want to add the documentation first, and we're still working with @danielroe on how to pass bindings to the handlers.

gacek1123 commented 2 years ago

Is it still being worked on? Having this preset would be awesome

ricky11 commented 2 years ago

Im having problems with nuxt server/api/function routes not being copied over to the /functions folder when deployed to cloudflare. I recreated a repo here : https://stackblitz.com/edit/github-dxg5qg?file=server%2Fapi%2Fcustomer.get.js when i run`CF_PAGES=1 npm run generate' this creates a /functions directory but nothing in it, empty. according to nitro docs, the preset will be automatically detected. Even when setting preset to cloudflare_pages, the functions folder is still empty...

marvincaspar commented 2 years ago

I get an error if I try to generate a nuxt app with NITRO_PRESET=cloudflare_pages.

ERROR  Cannot find module '/Users/mca/dev/private/nuxt-cloudflare/functions/index.mjs' imported from /Users/mca/dev/private/nuxt-cloudflare/node_modules/nitropack/dist/shared/nitro.ce47800e.mjs                  07:26:15

  at new NodeError (node:internal/errors:387:5)
  at finalizeResolution (node:internal/modules/esm/resolve:429:11)
  at moduleResolve (node:internal/modules/esm/resolve:1006:10)
  at defaultResolve (node:internal/modules/esm/resolve:1214:11)
  at nextResolve (node:internal/modules/esm/loader:165:28)
  at ESMLoader.resolve (node:internal/modules/esm/loader:844:30)
  at ESMLoader.getModuleJob (node:internal/modules/esm/loader:431:18)
  at ESMLoader.import (node:internal/modules/esm/loader:528:22)
  at importModuleDynamically (node:internal/modules/esm/translators:110:35)
  at importModuleDynamicallyCallback (node:internal/process/esm_loader:35:14)

error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Repo to reproducte the error https://github.com/marvincaspar/nuxt-cloudflare.

There is already an issue in nuxt framwork https://github.com/nuxt/nuxt.js/issues/14866

ricky11 commented 2 years ago

Adding issue 497 cloudflare_pages preset does preset does not transpile the /server/api folder in to cf pages /funtions i believe that was the intention.

marshallswain commented 2 years ago

I did a bunch of research for building a cloudflare-esm module. I didn't have Pages Functions in mind at the time, but I'm linking in this discussion I started in the nuxt/framework repo since it may contain information applicable to creating a cloudflare-pages deployment preset: https://github.com/nuxt/framework/discussions/5487.

iBobik commented 1 year ago

I needed static generated website + functions in /api. My workaround:

package.json, Clouflare configured to run npm run cloudflare (configure it in CF's Build configurations):

{
  "scripts": {
    "cloudflare": "NITRO_PRESET=cloudflare_pages nuxt build && mv dist dist-build && NITRO_PRESET=cloudflare_pages nuxt generate && cp dist-build/_worker.js public/_routes.json dist/ && rm -r dist-build # https://github.com/unjs/nitro/issues/196",

public/_routes.json (default config sends all traffic trhu the worker):

{
  "version": 1,
  "include": [
    "/api/*"
  ],
  "exclude": []
}

It would be nice if default preset could do this by default, or there will be config for it.

Edit: Updated script for Nuxt 3.6.5

Hebilicious commented 1 year ago

It looks like that throughout the year, cloudflare pages and workers will be merged into one service : https://blog.cloudflare.com/pages-and-workers-are-converging-into-one-experience/

There's not much information yet, but I assume everything will work with worker.toml, and that there won't be a need for a cloudflare pages preset anymore (cloudflare-module will replace it)

@pi0 If I'm not mistaken the current cloudflare-pages preset use a _worker.js which resolve this issue ?

Edit: We can use this issue to track function support with cloudflare-pages-static

iBobik commented 3 months ago

@pi0 Could you please link how this was completed? Still broken here.

pi0 commented 3 months ago

@iBobik cloudflare-pages preset. if you have a issue with documented behavior not working as expected, please consider opening a new issue with reproduction steps πŸ™πŸΌ

iBobik commented 3 months ago

Not sure if it is related to Nitro, so posted repro there. https://github.com/nuxt/nuxt/issues/28526