sveltejs / sapper

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

Use nollup in development mode #1207

Closed jthegedus closed 4 years ago

jthegedus commented 4 years ago

Is your feature request related to a problem? Please describe. The DX of Sapper is great except the speed changes are reflected in browsers in development mode.

Describe the solution you'd like nollup was suggested in prior conversations as a solution to this problem in development mode without requiring a significant rewrite of the build process of Sapper.

Describe alternatives you've considered Alternate tools like Snowpack and subsequently Vite have shown that speed of the development-mode builds can be improved significantly. These were discussed in #1204

How important is this feature to you? DX speed is very important, to the point I am considering rolling Routify or Snowpack with my own SSR instead of Sapper.

Additional context Prior discussion of Snowpack and Vite

antony commented 4 years ago

Here's where I'm at so far: https://github.com/antony/sapper/tree/feature/alternative-bundlers

You can pass --nollup to the CLI in order to use nollup for dev builds. I've refactored a lot of the way that bundlers are determined and instantiated.

I've realised that nollup doesn't have an API that appears to be compatible with how rollup works, so I've not made it much further, but if somebody who knows about this stuff wants to help, I'd be grateful!

I also know nearly nothing about how typescript works so I came a bit unstuck adding a Bundler type. I've just bunged it into a file called bundlers.ts but I'm assuming that this is wrong, so if somebody has a better idea, please say. Additionally I don't know how to get rid of the duplication of that type in the runtime code.

rixo commented 4 years ago

Unfortunately, Nollup is hard to integrate into Sapper because they both want to be the server / dev server... This will require a quite fat integration layer.

@antony BTW I'm very curious about how you intended to integrate Sapper & Snowpack?

Also, there is currently a bug in Nollup that prevents it to work with Sapper's config. I'm going to work on getting it fixed. (We've recently fixed sourcemaps & HMR CSS injection for Svelte components, yay \o/)

I managed to make it work by heavily hacking both Sapper and Nollup. Speed seems OK. I get ~500ms (client) rebuild time / HMR update on the default starter template. What's great is that I still get about the same time after copying routes/blog/ five times in the sources. So it seems that we can get constant rebuild time independent of the size of the project which, I think, is what we're all after.

Is there someone interested in producing a dummy large Sapper app example we can use to stress test the solutions we come up with?

I'm trying to clean what I have and push a demo soon.

rixo commented 4 years ago

I've pushed my patched everywhere version to the nollup branch of sapper-template-hot: https://github.com/rixo/sapper-template-hot/tree/nollup

It proves that it's possible.

I would love a more meaningful demo app that would allow to better appreciate how it performs.

rob-balfre commented 4 years ago

@rixo I tried adding in a large project of mine to your demo but no luck - just got this error after updating.

GET http://localhost:3002/client/client_wryrwa.[hash].js net::ERR_ABORTED 404 (Not Found)

Maybe I missed something? I can't share the repo unfortunately as its work related.

benmccann commented 4 years ago

You could try adding it to the sample apps if you want a more substantial app:

They're not huge apps, but it'd be a good start

rixo commented 4 years ago

@rob-balfre I failed to mention: Nollup is spinning its own web server. I have setup it (and hardwired for now) to proxy to localhost:3000, which is expected to be your Sapper server. This means for HMR support (and your bundle files to be available), you need to hit Nollup's server from your browser, at http://localhost:3333 (port also hardcoded in the demo). I think this is your issue.

@benmccann Yup, good idea, I will start with that, thanks :)

rob-balfre commented 4 years ago

@rixo thanks, a few of the page work now but most just error with Uncaught (in promise) TypeError: modules[number] is not a function

rixo commented 4 years ago

@rob-balfre Thanks for trying and the feedback. I'm battling with precisely the same thing in one of my apps, it helps to know I'm not an isolated esoteric case.

I've started to circle in on the cause. Nollup seems to have difficulties with some dynamic imports. We're pushing it to the max here, we're discovering all the bugs >_>

Edit To be completely fair, it seems that the bug has been introduced by my salvage patch of the previous bug. Discussion is ongoing on this one, so I have good hopes that the author of Nollup will be able to offer a more ecological fix.

rixo commented 4 years ago

@rob-balfre I've pushed a possible fix for your error on my nollup#sapper branch.

If you want to retry, just update with:

yarn add -D rixo/nollup#sapper
rob-balfre commented 4 years ago

@rixo tried, but no change I'm afraid.

GET http://localhost:3333/client/client.[hash].js net::ERR_ABORTED 404 (Not Found)

benmccann commented 4 years ago

Work is ongoing over in the nollup repo thanks to @rixo to improve support for Svelte/Sapper: https://github.com/PepsRyuu/nollup/issues?q=is%3Aissue+author%3Arixo+

rixo commented 4 years ago

Great progress has been made by Nollup on the issues mentioned here!

I've been using a branch with the fix for a few days in another project (simpler config than Sapper :sweat_smile: ), and it seems pretty stable and delightedly fast :)

I've pushed a branch with the forthcoming fixes and the patches currently required to support Sapper on the next branch of my fork (this was changed from sapper branch previously, if someone wants to upgrade a previous trial).

npm install -D rixo/nollup#next

I've also updated the nollup branch of my Sapper template (https://github.com/rixo/sapper-template-hot/tree/nollup) to reflect this and clean the config a bit.

If you're interested in this, now is a ver good time to try it and help us catch all the bugs!

@rob-balfre Both issues you've encountered should now be solved. Would love to hear your feedback to have a confirmation.

arxpoetica commented 4 years ago

@rixo I'm playing catch up, so forgive me for not reading everything in this thread. Can you give the tl;dr on how close this is to being development ready? For example, what would hold us back from documenting somewhere how to use this, or putting it up for consideration (no promises!) for inclusion in a default Sapper setup?

rixo commented 4 years ago

@arxpoetica Sure! The tl;dr is: I don't think there are big blockers. Nollup, I would go for it. But its Sapper integration is only POC level currently, it would need to be implemented cleanly into Sapper (see this commit to get a sense of the changes that are required -- it's not too much). For HMR, I'd say go for it too, but consider it would probably make it de facto official (not a bad thing IMHO).

Sorry, but I can't help some details... So, now, the just "too long" part!

Nollup has just released the fixes for the aforementioned issues. I think it should be pretty stable for usage with Sapper now. It's probably not supporting every Rollup plugins out there, but its author is very helpful, so I'm confident if there's something important missing it could get fixed fast.

I've been using it intensively recently, and I'm very satisfied. The only pain point for me with Nollup is that it uses eval to run your code. Not a huge problem, but it can make debugging some situations harder. Now the near instant rebuild time totally makes up for it, to me. I can live with falling back on Rollup once in a while for debugging. Somewhat related: I'm very hopeful about Vite, and Svelte + Vite has made some good progress lately. I think Sapper + Vite would be very interesting to explore, if someone is up for the challenge (cc @dominikg @intrnl).

All in all, I personally don't see any reasons not to go forward with Nollup. There are some rough edges, but the speed increase is a life changer for non-trivial project. You can go from 15-30s with Rollup down to <1s (often <500ms) with Nollup.

Regarding Svelte HMR, it's been around for a while with increasing usage and I don't get a lot of issues for it. My own experience with it is good and I've received positive feedback, so I think we can say it's stable. IMO it brings enough value to the dev cycle that it would make sense to consider it in official templates.

The catch is that it relies on Svelte's private API internally, so an unfortunate change to the core could break it beyond repair at any time. Inclusion in official templates would mean that the core commits to keep HMR working by not introducing such change. In practice, I think that would mean something like adding HMR test suite to Svelte CI and fix new bugs before release, if they arise.

For what it's worth, Nollup can be integrated independently of Svelte HMR. You still get fast rebuild. And it's relatively easy for a user to setup Svelte HMR on their own, if Nollup is already there.

benmccann commented 4 years ago

@rixo between all the different options of HMR, Nollup, Snowpack, and Vite are there any pros/cons between them or times to use one vs the other?

But its Sapper integration is only POC level currently, it would need to be implemented cleanly into Sapper (see this commit to get a sense of the changes that are required -- it's not too much).

I think it would make sense to have a rollup-sapper-plugin and have Rollup execute Sapper rather than the other way around. I'm assuming if we did this that we would no longer need Sapper to know anything about Nollup and we could integrate much more easily into all these solutions? It would also fix some other issues. E.g. I've run into #1221 #1234 #1266 #1301 which were all caused by trying to reimplement the Rollup CLI in the Sapper CLI

rixo commented 4 years ago

between all the different options of HMR, Nollup, Snowpack, and Vite are there any pros/cons between them or times to use one vs the other?

Nollup supports many Rollup plugins and for its config format, so it is easier to integrate into existing projects for a big speed boost. It also benefits from Rollup's existing ecosystem that is pretty mature, for projects with complex needs.

Vite and Snowpack are more suited to start new projects. New projects that want to live on the cutting edge, because they're both very recent initiatives. But they both aim to be everything you need during dev, so the plugin ecosystem might not count so much. I think their approach has a lot of merit and they will probably become the new standard before too long -- of course, especially Vite in Vue ecosystem. I haven't dug much in either, but from the few I've seen, Vite's API and working feels closer to my heart.

I think it would make sense to have a rollup-sapper-plugin and have Rollup execute Sapper rather than the other way around. [...]

Sapper as a Rollup plugin would be definitely easier to integrate with Nollup. Not sure about the others, though (Vite, Snowpack...). Cleanly abstracting the bundler / dev server part of Sapper to make integration with any solution easy would be a noble goal, but it doesn't seem like a trivial task unfortunately. I'm not sure whether it's better to have Sapper plugins for every dev server out there, or dev server plugins for Sapper.

jthegedus commented 4 years ago

between all the different options of HMR, Nollup, Snowpack, and Vite are there any pros/cons between them or times to use one vs the other?

The Vite README has a Different from Snowpack section which states:

Vite and Snowpack has collaborated on a common API spec for ESM HMR, but due to the constraints of different implementation strategies, the two projects still ship slightly different APIs

Both solutions can also bundle the app for production, but Vite uses Rollup while Snowpack delegates it to Parcel/webpack. This isn't a significant difference, but worth being aware of if you intend to customize the build.

Importantly, Snowpack is adding Rollup support for prod bundling.

benmccann commented 4 years ago

Closing in favor of Snowpack support (https://github.com/sveltejs/sapper/issues/1204), which is planned to be added in the upcoming Svelte Kit