sveltejs / sapper

The next small thing in web development, powered by Svelte
https://sapper.svelte.dev
MIT License
7k stars 434 forks source link

Example Serverless Arquitecture on Now v2 #564

Closed vladejs closed 4 years ago

vladejs commented 5 years ago

It seems that Now (zeit.co/now) is moving towards a serverless approach. Is there an example of Sapper working with Now v2?

Thanks

antony commented 5 years ago

Referencing https://github.com/zeit/now-examples/issues/193

thgh commented 5 years ago

I have no idea what I was doing and it was not successful:

now.json

{
  "version": 2,
  "builds": [
    { "src": "index.js", "use": "@now/node-server" }
  ]
}

index.js

require('./__sapper__/build/index.js')

demo: https://sapper-template-114-izlvje2aa.now.sh shows 500 error Log:

Error while initializing entrypoint: { Error: ENOENT: no such file or directory, scandir '/var/task/user/static'
    at Object.fs.readdirSync (fs.js:904:18)
    at walk (/var/task/user/index.js:4430:20)
    at module.exports.993.module.exports (/var/task/user/index.js:4496:3)
    at module.exports.432.module.exports (/var/task/user/index.js:1654:2)
    at Module.<anonymous> (/var/task/user/index.js:3297:56801)
    at e (/var/task/user/index.js:3276:124)
    at /var/task/user/index.js:3276:923
    at Object.824 (/var/task/user/index.js:3276:933)
    at __webpack_require__ (/var/task/user/index.js:22:30)
    at Object.138 (/var/task/user/index.js:309:1)
  errno: -2,
  code: 'ENOENT',
  syscall: 'scandir',
  path: '/var/task/user/static' }

After removing sirv(static)

Error while initializing entrypoint: { Error: ENOENT: no such file or directory, open '__sapper__/build/build.json'
    at Object.fs.openSync (fs.js:646:18)
    at fs.readFileSync (fs.js:551:33)
    at Rt (/var/task/user/index.js:4086:20874)
    at /var/task/user/index.js:4086:57860
    at Module.<anonymous> (/var/task/user/index.js:4086:57968)
    at e (/var/task/user/index.js:4065:124)
    at /var/task/user/index.js:4065:923
    at Object.921 (/var/task/user/index.js:4065:933)
    at __webpack_require__ (/var/task/user/index.js:22:30)
    at Object.602 (/var/task/user/index.js:2642:1)
  errno: -2,
  code: 'ENOENT',
  syscall: 'open',
  path: '__sapper__/build/build.json' }

I tried several to make a custom builder (now-sapper) but without success...

vladejs commented 5 years ago

Any progress on this?

antony commented 5 years ago

@vladejs you can rest easy knowing that all the Sapper/Svelte sites, docs, examples are all hosted on now v1. Dogfooding is key :)

Conduitry commented 5 years ago

There hasn't been any progress on this that I know of, but I'm pretty sure it will be a focus after Svelte 3 is out the door.

One unfortunate thing that makes this a bit more pressing is that Now apparently isn't allowing v1 for new projects, only for ones created before a certain date. I'm not sure why they decided to have the window be so narrow between the introduction of v2 and disallowing v1 on new projects. I'm pretty sure I read when v2 was announced that "don't worry, v1 isn't going anywhere anytime soon", but I certainly did not get the impression that it was going to be disallowed for new projects so quickly.

thgh commented 5 years ago

Progress: https://sapper-template-now-p0lz941iy.now.sh/

@Conduitry As far as I know, users with projects on v1 can create new v1 projects. Only users that never used v1 are forced to use v2.

antony commented 5 years ago

This is awesome news, well done @thgh

Do you reckon you'll be able to get it running with Polka?

What is the likelihood of a v2 app working with this? I've got a mountain of stuff to migrate and I'm not sure I'm ready just yet!

thgh commented 5 years ago

New version: code / result

edited for clarity

thgh commented 5 years ago

You can try v2 yourself, I think it should work.

@lukeed Polka says:

module initialization error: TypeError
    at _addListener (events.js:239:11)
    at Server.addListener (events.js:297:10)
    at new Server (_http_server.js:269:10)
    at Object.<anonymous> (/var/task/launcher.js:30:16)
    at Module._compile (module.js:652:30)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)
    at Module.require (module.js:596:17)
Conduitry commented 5 years ago

Does now-sapper exist anywhere besides in the package published to npm? https://www.npmjs.com/package/now-sapper doesn't have any readme yet or repo links or anything.

thgh commented 5 years ago

Now it exists: https://github.com/thgh/now-sapper

@antony got Polka working, had to export the app.handler instead.

kylecordes commented 5 years ago

How about putting the example app itself somewhere open? I'd rather not form a relationship with a "zeit" (which might be amazing...) to take a look. Currently clicking on the link about ending in _src requires some kind of account or login.

thgh commented 5 years ago

@kylecordes without login: code / result

antony commented 5 years ago

@thgh looks great! Yeah - Polka doesn't export the handler directly like express. Awesome work!

@kylecordes I think you can also still set a project to open source which will allow anonymous access to _src but github is fine too :)

ccinelli commented 5 years ago

Can this added to sapper with a stage script in package.json ?

zigomir commented 5 years ago

It's nice we have an example.

I'm also interested if we can take this a bit further. If I understand serverless correctly, the whole point is to do code splitting on serverside as well.

This section from next.js explains well how they handle serverless build.

The serverless target will output a single lambda per page. This file is completely standalone and doesn't require any dependencies to run

Would sapper consider supporting a build like this? Or is it even viable? I think it would be really great, as serverless benefits are numerous.

NathanielHill commented 5 years ago

Yeah, to be on par with the Next.js builder it would need to create a lambda for every route

danielschmitz commented 5 years ago

Hi, im building a "sapper+bulma crud"

my now v2 implementation is here: diff demo

joshleblanc commented 5 years ago

Do the examples I see here inherently support server routes, or no?

thgh commented 5 years ago

@horizonshadow yes, e.g. sapper-template has a server route for blog posts.

joshleblanc commented 5 years ago

Was playing around with this just using the @now/node builder, and I'm pretty sure once https://github.com/zeit/ncc/issues/216 gets to now-builders, it'll "just work".

So you'd set the now-build script in package.json to sapper build, and then set @now/node to __sapper__/build/index.js.

I think, anway.

NathanielHill commented 5 years ago

@HorizonShadow While, I think that it will be great when @now/node to work out of the box... this is still a monolithic build. A @svelte/sapper builder that splits each route into it's own lambda function like @now/next does would be needed to take full advantage of the Now V2 architecture.

vfabing commented 5 years ago

Hi,

Base on @danielschmitz modifications, I created a sample repo sapper-now-template base on the original sapper-template (diff).

I don't know if it would make sense to make a Pull Request on the original sapper-template repo based on these modifications, or if you want to keep the template agnostic from Now (Though I was personnaly surprised to see it recommended on the documentation, but not working directly)

Thank you very much anyway for your great work ! Tell me if I can be of any help :)

antony commented 5 years ago

@vfabing The official template already has explicit netlify support, so I would imagine that adding now v2 support would be welcome also.

For a lot of people, myself included, this is a huge problem right now.

kevin-DL commented 5 years ago

I managed somehow to deploy to now 2, based on StackOverflow Not too sure about the service worker, not that i need it right now, but it got the application deployed

now.json


  "name": "portfolio",
  "version": 2,
  "builds": [
    {
      "src": "__sapper__/build/index.js",
      "use": "@now/node-server",
      "config": {
        "includeFiles": [
          "build.json",
          "../../package.json",
          "../build/**",
          "../../static/**",
          "../../node_modules/**"
        ],
        "maxLambdaSize": "15mb"
      }
    },
    {
      "src": "static/**",
      "use": "@now/static"
    },
    {
      "src": "__sapper__/build/client/**",
      "use": "@now/static"
    }
  ],
  "routes": [
    { "src": "/(.*(\\.css)|(\\.json)|(\\.png))", "dest": "/static/$1" },
    { "src": "/client/(.*)", "dest": "/__sapper__/build/client/$1" },
    { "src": "/(.*)", "dest": "/__sapper__/build/index.js" }
  ]
}```
bausk commented 5 years ago

@kevin-DL I'm continuing to research this issue and have observed the following:

https://spectrum.chat/zeit/general/now-cli-deployment-doesnt-build-package-json-dependencies~34dac90d-46fe-499a-89bc-58bffe50a9ab

The most worrying thing for me is the fact that Sapper apparently needs to connect to its own JSON API locally to perform state hydration, and that's not possible when using AWS Lambdas (which are under the hood of Zeit v2, to my understanding), as documented here: https://spectrum.chat/zeit/general/is-it-possible-to-self-connect-to-127-0-0-1-from-within-lambda~8dca04eb-99fb-49ad-a8be-de1c21335396

Whatever black magic now-sapper does to make it possible, I don't know and would love any and all input on this (I'm also including rollup-plugin-json in the Rollup build variant in addition to the standard Sapper config, FWIW).

bausk commented 5 years ago

Also worth mentioning that I've switched to webpack because Rollup keeps screwing with require dependencies in third party libs like Auth0 but that's probably a completely different issue.

kaleidawave commented 5 years ago

I am a bit confused with @kevin-DL 's now.json suggestion as it has a seperate route for client. Isn't the client on the same layer as the server stuff??

kevin-DL commented 5 years ago

@kaleidawave As far as i understand, the routes are just a mapping of where to go depending on the incoming request. When you build the application, you get a client and a server folders so it made sense to me to split it like that. I stopped at the first config that worked for me there is probably a way to optimise it.

dangdennis commented 5 years ago

@vfabing 's solution works for me. Thanks for the easy setup!

However, perhaps it's the use of webpack but the main.js is ~60kb. This is pretty egregious when you consider the sapper realworld app is like ~5kb for the home page.

Edit: I switched over to the rollup config from the sapper template. Now the bundle size is ~12kb. Still much larger than the RealWorld sapper app for some reason.

Edit 2: I am building first locally then deploying. Realized then that Sapper was building in dev mode. Now that I've set NODE_ENV to "production", it's building within the ~5-8kb range now.

Here's a deployed link on https://sapper-now-template.now.sh/

pngwn commented 5 years ago

I've not read this thread and I don't use now. Do we need to put together a custom loader or something? Is there something someone has built that works without any issues? Or maybe we just need to recommend a different host if now v2 is just causing too many problems?

I'm just trying to work out if there is something we need to do as regards this issue or if it is just a support thing.

vladejs commented 5 years ago

I believe sapper should be now v2 aware, since the project is inspired by Next.js which has excellent support for it.

On Fri, Jul 26, 2019, 6:45 PM pngwn notifications@github.com wrote:

I've not read this thread and I don't use now. Do we need to put together a custom loader or something? Is there something someone has built that works without any issues? Or maybe we just need to recommend a different host if now v2 is just causing too many problems?

I'm just trying to work out if there is something we need to do as regards this issue or if it is just a support thing.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/sveltejs/sapper/issues/564?email_source=notifications&email_token=ADANIARCGSKDDV2YU63UMMDQBN5APA5CNFSM4GXXXMTKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD254ATI#issuecomment-515620941, or mute the thread https://github.com/notifications/unsubscribe-auth/ADANIARGVGIU4537MI46HATQBN5APANCNFSM4GXXXMTA .

pngwn commented 5 years ago

next.js has excellent support because it is built by the now team, Sapper was inspired by next but I don't see why that should mean we need to align with a specific, proprietary architecture. Quite frankly, given recent experiences, it's hard to even recommend them.

now v2's requirement are very specific and no other host that I'm aware of has the same requirements. We might be able to provide some guidance or even a separate package to help smooth out these issues but I don't see any reason why Sapper would have first class support for now out of the box since their shift to serverless in v2.

controversial commented 5 years ago

@vladejs That's not correct. My understanding is that Sapper can export static sites for some projects, which will work great on Now v2, but more complex Sapper apps that require the server will not be optimized for Now v2 (they will work, but only slowly, as the server would need to start up again for each request).

vladejs commented 5 years ago

mmm. Interested to know how Next do it, since most basics apps made with Next.js also requires a server.

Also, Zeit provides guides on how to make an Express server serverless, which is done by just using Express as middleware and discarding routing. Routing is handled by now.

I also saw a comment from a Zeit team member on one of their repos saying that sapper should work great on serverless environments.

Not going in technical details but it should be possible to decompose the routes on independent lambdas as Next.js does when setting it's serverless config to true, at the end, both uses the filesystem as routing.

Also, Zeit has improved it's serverless functions by natively using common Express functions on the request and response objects:

https://zeit.co/blog/now-node-helpers

vladejs commented 5 years ago

next.js has excellent support because it is built by the now team, Sapper was inspired by next but I don't see why that should mean we need to align with a specific, proprietary architecture. Quite frankly, given recent experiences, it's hard to even recommend them.

@pngwn , there is some discussion about bringing sapper to now v2 here: https://github.com/zeit/now-examples/issues/193

mcsdevv commented 5 years ago

Hey everyone, we've just optimized Sapper for Now when using sapper export, this allows you to deploy from the boilerplate with now by using "build": "sapper export" - nothing else is required! We've also added an example showing this as well.

vladejs commented 5 years ago

Is possible with that solution export authenticated apps?

Conduitry commented 5 years ago

The rules about when you can export still apply - https://sapper.svelte.dev/docs#When_not_to_export

Being able to serve completely static sites on Now isn't anything new, and nothing about this seems particularly specific to Sapper.

NathanielHill commented 5 years ago

Okay, it's great for the config to be simplified :+1: But this doesn't address serverless at all.

vladejs commented 5 years ago

Exactly

On Fri, Aug 2, 2019, 1:32 AM Nathaniel Hill notifications@github.com wrote:

Okay, it's great for the config to be simplified 👍 But this doesn't address serverless at all.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/sveltejs/sapper/issues/564?email_source=notifications&email_token=ADANIAXSED4E4GENDWUMMVLQCPBFVA5CNFSM4GXXXMTKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD3MUQZI#issuecomment-517556325, or mute the thread https://github.com/notifications/unsubscribe-auth/ADANIASVJDLWMWGJ4LHEQNLQCPBFVANCNFSM4GXXXMTA .

aurnik commented 5 years ago

Not sure if I'm late with this but looks like you could put your authentication functions into an /api folder as described here to automatically deploy as serverless functions

antony commented 5 years ago

@aurnik it's more about a function-per-route like Next does.

cortopy commented 5 years ago

The rules about when you can export still apply - https://sapper.svelte.dev/docs#When_not_to_export

Being able to serve completely static sites on Now isn't anything new, and nothing about this seems particularly specific to Sapper.

While this used to be true for next.js, it's no longer the case after the release of next.js 9. A next.js application can now be static and dynamic at the same time

nickluger commented 5 years ago

Now is tackling the serious cold start problem with lambdas, by simply lowering the lambda cold boot time to an acceptable level (100-300 ms) through server side code splitting and tiny bundles. (Instead of one large monolithic bundle, that takes up to 2 sec to load into memory).

This is a huge advantage for people who want to go the serverless route, and a large plus for Nextjs on the Next-vs-Sapper-comparison-sheet that one might draw mentally, when about to embark on a new project.

As @rauchg has pointed out, the Sapper architecture, inspired by Next's, seems to be perfectly usable for serverless code splitting.

It'd be a pity, if we wouldn't see a marriage between now and sapper - as sapper is still simply leaner and more efficient than react - and it's hard to forego efficiency. But Next+Now enabling killer-features like serverless prerendering makes Next even more appealing, in my opinion, as long as Sapper did not follow suit.

kylecordes commented 5 years ago

Surely it is possible to achieve at least a meaningful portion of this kind of architectural improvement / code split speed booth without becoming bound to one specific serverless platform/vendor? Because while I'm sure Now is a wonderful wonderful thing… It is not reasonable to expect that one product/vendor to become "the" way to host efficiently.

antony commented 5 years ago

@kylecordes nobody is suggesting that, what is being suggested is a solution for all serverless-function based platforms. Now is a good starting place as it allows you to host on AWS, GCP, and possibly Azure in the near future.

Being able to make a Sapper project split a project into functions based upon routes would be a step forward in this direction.

NathanielHill commented 5 years ago

Yes. If I get any spare time this month I'll give it a go. I'll make a fork called sapperless to experiment with building route-based functions and maybe it could be folded back into sapper at some point.

antony commented 5 years ago

I've created a sort-of evolution of the previous now-sapper builder by @thgh .

You can test it out here: https://github.com/beyonk-adventures/now-sapper - by simply sticking the github URL into your now.json.

Feedback is welcome.

The roadmap (which I certainly need help with) is:

thgh commented 4 years ago

@antony Static assets are now served as static routes. Thanks to your refactor!